[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
let and for vs. lambda variations
[Harald wrote a note a long time ago (last week) which i've been meaning to
reply to, with the subject ``Features to remove: return and noreturn.'' the
easier part dealt with removing for (which he called ``do'' by mistake in his
posting), so i decided to respond to that suggestion first. a comment on his
other suggestions will follow. first, i quote what Harald wrote, following a
,x/do/c/for/ so it made sense to me.]
> let me
> take another look at my suggestion to get rid of `for', which met with
> such resistance. If people want for for its convenience I guess it
> stays in, but there is still no reason why we could not throw away at
> least the many-variable for and let the simple case be syntactic sugar:
> Rewrite for (x = x1 x2 ...) {cmd} as %for @ x {cmd} x1 x2 ...
> and define the hook function %for along the lines of
> fn %for fun list {let (x=) {while {x list=$list; !~ $#x 0} {$fun $x}}}
first of all, let me note that let is in the same category as for: it can be
replaced by lambda, if you throw away the multiple binding forms. that is,
the above fn %for can become
fn %for fun list {
@ x {while {x list=$list; !~ $#x 0} {$fun $x}}
}
two notes:
(1) this should be obvious, since es at some levels is just a veneer
over a lambda calculus, but it took me until i read Harald's note
to realize it.
(2) the multiple assignment form of let (see comment), which will be
in the next release, are definitely very close to lambda binding,
and, in fact, use the same code.
[notational comment:
multiple binding means ``let (a = 1; b = 2 3)''
multiple assignment means ``let (a b = 1 2 3)''
they are not equivalent. (consider
let (a b = $x $y)
versus
let (a = $x; b = $y)
where $x and $y are 2 element lists, for example.)]
we also had some discussion earlier which argued that multiple binding should
not be the same as several nested bindings, that is, all of the values in the
let should be evaluated before any of the actual bindings are done. for
example,
x = bar; y = foo
let (x = $y; y = $x) echo $x $y
would print
foo bar # let
and not, as it currently (0.84) does,
foo foo # let*
for those who care, this is the let vs. let* discussion.
note, and this is important, that in es, you cannot rewrite multiple binding
lets as lambdas, if let has the semantics we decided it should have. (aka,
scheme let.) this is exactly the same reason that multiple binding for cannot
be rewritten as lambdas. (well, for is a little harder.)
local is different, but easier in many ways. local could almost be written as
a function, except for namespace collisions, as is usually the problem with
dynamic binding. but local could easily become a primitive if, again, it
doesn't have a local binding form.
so, i now raise the issue, should let, local, and for be replaced with syntax
rewriting and/or hook functions? if so, it means that we have to give up
multiple binding semantics for all of them, including the somewhat special
form that multiple binding takes for ``for'':
; for (i = a b c; j = 1 2) echo $i $j
a 1
b 2
c
;
note that this is an all-or-nothing choice: i want to handle all three of
these binding forms in the same way. if for goes, so do let and local. (of
course, all stay at the syntax level, but the multiple binding forms really
will disappear completely.)
paul