[plt-scheme] macros, special forms, and lazy functions

From: Stephen Bloch (goliards at verizon.net)
Date: Fri Dec 11 23:40:45 EST 2009

On Dec 11, 2009, at 10:10 AM, David Van Horn wrote:

> So the fact that `and' and `or' are not values can be observed as  
> early as ISL (disregarding the fact that the "smartness" can be  
> observed from the beginning).

Good point.  Actually, I do point out the "smartness" earlier than this.

> In ISL, you can do this:
> (define f add1)
> (f 0)
> So if `and' were a value, you should be able to do:
> (define g and)
> (g true)
> But you cannot in ISL.
> I find it simpler and easier to convey that there is 1) function  
> application, which has a uniform evaluation process, and there are  
> 2) other expression forms, which have specialized evaluation  
> processes.

The classroom use-case I'm thinking of is "I assign a bunch of  
functions on lists, which can be written from scratch using  
recursion, or more briefly using standard higher-order functions like  
map, filter, foldr and foldl, etc."

The following problems would fit naturally into this use-case, and  
they have obvious definitions, but the fact that "and" and "or" are  
special forms means that the obvious definitions don't pass a syntax  
1) "any-true? : list-of-Boolean -> Boolean": the obvious definition  
is "(foldr false or ...)".
2) "all-true? : list-of-Boolean -> Boolean": the obvious definition  
is "(foldr true and ...)".
3) "bitwise-and : list-of-Boolean list-of-Boolean -> list-of- 
Boolean": the obvious definition is "(map and ...)"
In all these cases, short-circuit evaluation is irrelevant because  
the assigned function takes in a list, and "list" is a true function  
so all the Booleans must obviously be evaluated before there is even  
an argument to give to the assigned function.

One solution to this would be to have "and" and "or" recognize when  
they're being "mentioned" rather than "used", and act as true  
functions in that context.  Another solution would be to provide true  
functions "andf" and "orf" that do the same job (except for short- 
circuit evaluation)... but then I have to explain why the obvious  
definitions with "and" and "or" don't work, which seems like a picky,  
inconsistent implementation detail rather than a fundamental  
programming concept.

There's obviously a trade-off in what constitutes "clean, consistent"  
behavior.  Under my proposed definition, "and" and "or" would  
sometimes do short-circuit evaluation, and sometimes not... but they  
can appear anywhere in an otherwise-syntactically-legal expression,  
just like a function or a variable.  Under the current definition,  
"and" and "or" always do short-circuit evaluation... but sometimes a  
syntax check recognizes them, and sometimes it doesn't.  Which is  
more inconsistent from the user's perspective?  Remembering that my  
"users" are largely first-semester programming students, including a  
number of non-CS-majors.

Stephen Bloch
sbloch at adelphi.edu

Posted on the users mailing list.