Open Technologicat opened 5 years ago
Maybe in the initial implementation:
with definitions
to appear in tail position in the with topdown
. Allow only one.with definitions
block in tail position in another with definitions
block (so that the definitions themselves can also use top-down style, recursively).with topdown
itself is first- or second-pass.with topdown
body is such as context; as are the bodies of any with definitions
. The handler should first check for the presence of a with definitions
block in tail position, recurse into it if present, and paste the result to the beginning of the output. Then just append everything else to the output.This should yield a simple implementation that does the most important thing. This could be implemented already in 0.14.2.
The final detail are the names. with topdown
is long, and not common programming terminology - the issue of presentation order (where the terms top-down and bottom-up in the sense intended here originate from) is more often discussed in the context of writing or making presentations.
So let's consider some alternatives. with clarity
(the reason why one would use this construct) is just silly, and no shorter - but perhaps more memorable. with lifo
invites a misleading association with queues. with td
is short, but a tad cryptic. with aim
can be misread as a TLA - what's this A.I.M. and how do you with
with it? Maybe with goal
, that's what it does?
As for with definitions
, the obvious abbreviation with defs
is almost self-documenting, except the detail that it actually accepts any statements, not just def
statements. Those are the main use case, though, so perhaps this is acceptable.
So maybe this feature will be named with goal
and with defs
.
Meh, maybe better to feature-freeze 0.14.2 now and leave this for the next release.
Maybe the definitions should apply backwards, to remove the need of nesting with defs
blocks when the definitions are top-down too?
with goal:
x = a * b * c
with sfed:
a = f(...)
f = ...
being equivalent to
with goal:
x = a * b * c
with defs:
a = f(...)
with defs:
f = ...
which expands to
f = ...
a = f(...)
x = a * b * c
For simple use cases, a single with
-form that applies its statements from last to first would be enough, but the point of the two-part design is to have more control in complex use cases (which is where this whole feature benefits the most).
Maybe this still needs some more thinking...
Occasionally a top-down presentation style (like Haskell's
where
) is useful:The benefit of the top-down presentation is the reader will already have seen the overall plan when the detailed definitions start. The program logic reads in the same order it plays out.
This would expand to:
In pure Python, it is of course already possible to delay the match call by thunkifying it:
This works because - while values are populated dynamically - name resolution occurs lexically, so it's indeed pointing to the intended
frobnicate
(and it's fine if a value has been assigned to it by the time the lambda is actually called).However, this introduces a promise, and we have to remember to force it at the end (after the many, many definitions) to actually compute the result. (For a proper evaluate-at-most-once promise, we would use
lazy[]
from MacroPy, and maybe for readability, force it usingunpythonic.force
instead of just calling it.)In use cases like this, the main benefit of inlining lambdas to the
match
call (e.g. in Racket) is the approximately top-down presentation. Thewith topdown
construct introduces this benefit for named functions.Since 0.12.0, we already support top-down presentation for expressions:
The
with topdown
construct would add top-down presentation for statements.The goal is to allow arbitrary statements in the
with definitions
block, although it is recommended to use it only to bind names used by the body (whether bydef
or by assignment, doesn't matter).The top-level explicit
with topdown
is a feature to warn the reader, because top-down style can destroy readability if used globally.The
topdown
macro should apply first in the xmas tree.At this stage the design still needs some thought, e.g.:
with definitions
to always appear in tail position, or allow it in any position?with definitions
blocks?with definitions
blocks?topdown
anddefinitions
?