Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Theory of effects #165

Draft
wants to merge 16 commits into
base: main
Choose a base branch
from
Draft

Conversation

countvajhula
Copy link
Collaborator

@countvajhula countvajhula commented Mar 19, 2024

Summary of Changes

This PR elaborates Qi's theory of effects. The main result is the following:

"Qi guarantees that the output of execution of the compiled program is the same as that of the source program, assuming effects are local, and further, it guarantees that the effects will be well-ordered in relation to the source program."

The rest of these changes are supporting explanations, examples and advice, including:

  • introduces the concept of "well ordering" of effects as being a natural functional guarantee
  • explains how this guarantee is well behaved with "local" effects
  • improves the discussion of Schrodinger's probe
  • misc other improvements, including linking defined concepts

For more context, see the meeting notes, especially Side Effects Include Confusion and Schrodinger's Probe.

Public Domain Dedication

  • In contributing, I relinquish any copyright claims on my contribution and freely release it into the public domain in the simple hope that it will provide value.

(Why: The freely released, copyright-free work in this repository represents an investment in a better way of doing things called attribution-based economics. Attribution-based economics is based on the simple idea that we gain more by giving more, not by holding on to things that, truly, we could only create because we, in our turn, received from others. As it turns out, an economic system based on attribution -- where those who give more are more empowered -- is significantly more efficient than capitalism while also being stable and fair (unlike capitalism, on both counts), giving it transformative power to elevate the human condition and address the problems that face us today along with a host of others that have been intractable since the beginning. You can help make this a reality by releasing your work in the same way -- freely into the public domain in the simple hope of providing value. Learn more about attribution-based economics at drym.org, tell your friends, do your part.)

Comment on lines +116 to +119
@; This relation, like the usual strict order relation on numbers, is
@; irreflexive (f isn't upstream of itself, not f < f),
@; asymmetric (f < g ⇒ not g < f)
@; and transitive (f < g and g < h ⇒ f < h)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want the "not less than character": .


In general, pure functions (that is, functions free of such effects) are easier to understand and easier to reuse, and favoring their use is considered good functional style. But of course, it's necessary for your code to actually do things besides compute values, too! There are many ways in which you might combine effects and pure functions, from mixing them freely, as you might in Racket, to extracting them completely using monads, as you might in Haskell. Qi encourages using pure functions side by side with what we could call "pure effects."
In general, pure functions (that is, functions free of such effects) are easier to understand and easier to reuse, and favoring their use is considered good functional style. But of course, it's necessary for your code to actually do things besides compute values, too! There are many ways in which you might combine effects and pure functions, from mixing them freely, as you might in Racket, to extracting them completely using monads, as you might in Haskell. Qi encourages using pure functions side by side with what we could call @deftech{pure effects}.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: perhaps "pure effect" is confusing here. With care, it can be read as distinguishing between purely effectful computations and effectful computations which also does something else (what? In the meeting, we proposed "not having output" as being "purely effectful" whereas a computation with outputs is not "purely effectful").

Perhaps we should find a substitute for "pure" to avoid mixing terminology.

@benknoble
Copy link
Collaborator

(possibly unrelated) nit: The following paragraph needlessly ties effect to the semantics of tee (the equivalences in the preceding paragraph are useful, but explaining the implementation seems gratuitous):

Remember that, as the side-effect flow is based on a tee junction, it must handle as many inputs as the main flow. For instance, if you were to use displayln as the side-effect, it wouldn’t work if more than one value were flowing, and you’d get an inscrutable error resembling:

—Qi docs, effect form

I suggest something more like

The effect flow must handle as many inputs as the main flow `flo`. For instance, if you were to use…

@benknoble
Copy link
Collaborator

An original comment chain on readout, Shrodinger's probe, and effects: #152 (comment)

@benknoble
Copy link
Collaborator

RE: effects within esc: #152 (comment), #152 (comment). I think some of these were addressed, but I also think the conversation re-arose during today's meeting.

@benknoble
Copy link
Collaborator

RE: "syntax warnings," what produces the "unused identifer" annotations in Racket Mode/DrRacket/racket-langserver?

@benknoble
Copy link
Collaborator

RE: the effect relation, if the ordering function (judgement?) Michael proposed is writable: it will likely to be easier with a smaller core syntax.


Well-ordering is defined in relation to a source program encoding the intended meaning of the flow, which serves as the point of reference for program translations. Qi guarantees that effects will remain well-ordered through any such translations of the source program that are undertaken during @seclink["It_s_Languages_All_the_Way_Down"]{optimization}. As we will soon see, this guarantee assumes, and prescribes, that effects employed in flows be @tech{local}.

@definition["Effect locality"]{@tech{Effects} in a flow F are said to be @deftech{local} if the @tech{output} of F is invariant under all @tech{well-orderings} of effects. Specifically, if a @techlink[#:key "well-ordering"]{well-ordered} program translation causes a program to produce different @tech{output}, then the program contains @deftech{nonlocal} effects.}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The word "local" for this property is a little confusing to me, because the effects may in fact impact each other at a great syntactic or temporal distance! It's just that they're restricted to be related by the dependency structure of the flows.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see an explicit definition of what it means to be a well-ordered program transformation, as opposed to effects in a program being well-ordered. At the same time, bringing in the issue of program transformations at all and what properties they need to maintain seems like it should be in separate developer documentation.

@@ -21,7 +37,7 @@

A @deftech{flow} is either made up of flows, or is a native (e.g. Racket) @seclink["lambda" #:doc '(lib "scribblings/guide/guide.scrbl")]{function}. Flows may be composed using a number of combinators that could yield either linear or nonlinear composite flows.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dominik pointed out that this definition identifies flows semantically with functions (and also a couple of paragraphs below). That may not be the case in general, especially if we allow users to indicate the backend.

@@ -21,7 +37,7 @@

A @deftech{flow} is either made up of flows, or is a native (e.g. Racket) @seclink["lambda" #:doc '(lib "scribblings/guide/guide.scrbl")]{function}. Flows may be composed using a number of combinators that could yield either linear or nonlinear composite flows.

A flow in general accepts @code{m} inputs and yields @code{n} outputs, for arbitrary non-negative integers @code{m} and @code{n}. We say that such a flow is @code{m × n}.
A flow in general accepts @code{m} @deftech{inputs} and yields @code{n} @deftech{outputs}, for arbitrary non-negative integers @code{m} and @code{n}. We say that such a flow is @code{m × n}. Inputs and outputs are ordinary @tech/reference{values}.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like we do mention "non-negative integers" here so it entails pure effects as we are currently defining them @dzoe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants