[Edu-sig] more re scheme.py
Kirby Urner
pdx4d@teleport.com
Sun, 08 Oct 2000 19:46:13 -0700
In a previous post I wrote:
>For example, you can define car and cdr of LISP fame:
>
> >>> def car(mylist):
> if len(mylist)==0: return []
> else: return mylist[0]
>
> >>> def cdr(mylist):
> if len(mylist)==0: return []
> else: return mylist[1:]
That's clearly not quite right. Here's car and cdr in
action in DrScheme:
Welcome to DrScheme, version 101.
Language: Textual Full Scheme (MzScheme).
> (car '())
car: expects argument of type <pair>; given ()
> (car '(1))
1
> (cdr '(1))
()
>
In other words, the car of an empty list is undefined.
The car of a 1-member list is that member. The cdr of
a 1 member list is the empty list (provided it's a proper
list of cons pairs -- but that's another story).
So...
def car(mylist): return mylist[0] # first member
def cdr(mylist):
if len(mylist)==1: return [] # returns empty list
else: return mylist[1:] # else, rest of list
>>> car((1,))
1
>>> cdr((1,))
[]
You get error messages if your argument to either is an empty
list.
Then:
def Reduce(operator,mylist):
if len(mylist)==1:
return car(mylist)
else:
return apply(operator, (
car(mylist),
Reduce(operator,cdr(mylist))
)
)
Usage:
>>> Reduce(operator.mul,range(1,11))
3628800
>>> 1*2*3*4*5*6*7*8*9*10
3628800
I'm not saying we should customarily program this way, simply
that it's possible to communicate some of the flavor of Scheme
by bringing analogous features of Python into the foreground.
One could go on to define caaaar, cddddr, cdadar, cdar, cadadr
-- the whole set of weird (unpronouncable) words for doing
"slice arithemetic".
http://www.cs.washington.edu/education/courses/341/99su/lectures/scheme/img0
28.GIF
shows ([lambda (x y)(+ (* 2 x) y)] 4 5) evaluating to 13.
In DrScheme:
> ([lambda (x y)(+ (* 2 x) y)] 4 5)
13
In Python:
>>> apply(lambda x,y: 2*x + y, (4,5))
13
Like in Scheme, in Python you can bind the lambda part to a name:
>>> f = lambda x,y: 2*x + y
>>> f(4,5)
13
Alternatively:
>>> def f(x,y): return apply(lambda x,y: 2*x + y,(x,y))
>>> f(4,5)
13
Which is just a rather long-winded way of just saying:
>>> def f(x,y): return 2*x + y
http://www.cs.washington.edu/education/courses/341/99su/lectures/scheme/img0
68.GIF
shows a "procedure factory":
We go
> (filter [lambda (x) (>= x 0)] '(-2 -3 -1 3 1 4))
(3 1 4)
i.e. returns x's >= 0
-- this doesn't seem to work in DrScheme (apparently filter is not
a primitive).
> (filter [lambda (x) (>= x 2)] '(-2 -3 -1 3 1 4))
(3 4)
returns x's >= 2
So we'd like to define a function which creates other functions with n
being whatever number we have to be greater than.
In Scheme, that looks like:
(define (greater-than-n?? n)
(lambda (x) (>= x n)))
Then you can say:
(define greater-than-2 (greater-than-n?? 2))
^^^^^^^^^^^^^^^^^^^^
returns a pointer to a procedure
and get a procedure, i.e.
> ((greater-than-2) '(-2 -3 -1 3 1 4))
(3 4)
In Python:
>>> def gt_n(n): return eval('lambda x: x>%s' % n)
>>> gt_2 = gt_n(2)
^^^^^^
returns a pointer to a procedure
>>> gt_2(-1)
0
>>> gt_2(3)
1
>>> filter(gt_2,[-3, -2, 1, 3, 1, 4])
[3, 4]
Thanks to Jeff Cogswell for teaching me the above.
Thanks to Greg Badros's lecture notes re Scheme at
http://www.cs.washington.edu/education/courses/341/99su/lectures/scheme/
for slide GIFs.
Thanks to John Clements, Matthias Felleisen, Robby Findler, Cormac Flanagan,
Matthew Flatt, Shriram Krishnamurthi, and Paul Steckler et al for the
Dr. Scheme software.
http://www.npr.org/ramfiles/wesun/19990404.wesun.07.ram to hear
Paul Steckler play that Sunday game program on NPR.
Also, listen to Matthias on
http://www.cs.rice.edu/CS/PLT/Miscellaneous/matthias-kuhf.mp3
Kirby