[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