missing primatives for this weeks exercises

0 views
Skip to first unread message

ozten

unread,
Sep 6, 2007, 12:26:24 PM9/6/07
to Seattle SICP Study Group
Maybe I am reading the exercises wrong, but it seems like my Scheme
implementation doesn't have either nil or proc.

I am using '() for nil and apply for proc and this seems to do the job.

Adam

unread,
Sep 7, 2007, 3:09:19 AM9/7/07
to Seattle SICP Study Group
This is scheme, don't bend to the language, make the language bend to
you! You should probably have an included definitions file for things
like this, or just stick it at the top of all your exercises for the
book, defining the symbols nil and proc.

Quux Man

unread,
Sep 7, 2007, 12:49:05 PM9/7/07
to seattle-sicp...@googlegroups.com
Yeah, I've used (define nil '()) a couple times. They're both three characters, but "nil" is a lot easier to type. I haven't noticed proc being used as anything but a variable name though.

Also note that all the general purpose list processing functions in chapter 2 are already defined with more standard names in srfi-1. In chicken (I don't know about PLT), simply:

(use srfi-1)

And then you'll have map, fold (called accumulate in the book), unfold, map-filter, and much much more. You also get things like first, second, third, fourth, etc. to replace the cryptic car, cdr, cdar, cddar, etc. Check out the following link for a complete specification of srfi-1:

http://srfi.schemers.org/srfi-1/srfi-1.html

Quux Man

unread,
Sep 7, 2007, 1:02:56 PM9/7/07
to seattle-sicp...@googlegroups.com
Actually, I made a mistake in saying cdr, cdar, and cddar is replaced. The only /c(a|d)+r/ functions that access the nth element of a list are ones with a single a after the initial c, like /cad*r/. So first, second, third, etc replace car, cadr, caddr, etc. respectively. The rest of them access items of nested lists. You can read /c(a|d)+r/ functions by adding "car of the" for each a, and "cdr of the" for each d in the middle. So (cdar foo) would be "cdr of the car of foo", meaning (b ...) in ((a b ...) (c d ...)). And caadr would be c, and cdadr would be (d ...). I think you get the idea. Kind of cool, as it's a lot more concise than something like (list-ref (list-ref foo 1) 0).

Quux Man

unread,
Sep 7, 2007, 1:08:21 PM9/7/07
to seattle-sicp...@googlegroups.com
Of course you would also think (at least I would) that foo[1][0] is almost as concise and a hell of a lot less cryptic. Also the bracket notation is useful for things like slices, like foo[0 .. 10][0 .. 1], for a list of 10 of the first two elements of a nested list.

I know at least one or two lisps have caught up and added bracket array indexing syntax, but I don't know of any schemes that have done this. Anybody know of a library that implements a few macros for this?

Quux Man

unread,
Sep 7, 2007, 5:09:58 PM9/7/07
to seattle-sicp...@googlegroups.com
I guess square bracket syntax for array indexing would be contrary both to Scheme's philosophy of minimal syntax and to the common practice of using square brackets interchangeably with parenthesis.

Also, lists in Scheme are fundamentally different from arrays, as opposed to other languages like Perl (and Python and Ruby I believe) which have fancy hybrids between linked lists and C style arrays. I don't think lists in Scheme are really meant to be indexed, as (list-ref foo N) takes N steps. Arrays in Scheme are generally implemented as a library extension on top of vectors (basically the same as 1 dimensional arrays in C, I believe), and their purpose is fast indexing and compact storage in memory.

In the R5RS spec, only heterogenous vectors are specified, but many implementations extend this to typed vectors for more efficiency. After much experimentation, I figured out how to use arrays (at least in Chicken). To set them up, run:

$> sudo chicken-setup array-lib

And to use them:

; use array lib, array slicing functions, higher order array functions, and string library (srfi-13)
(use array-lib array-lib-sub array-lib-hof srfi-13)

; make 10 vectors of 10 vectors of vectors containing 10 foo symbols
(define big-array-of-anything (make-array '#(foo) 10 10 10))

; set each element of big-array-of-anything to a string representation of each element's index
(array-for-each-index
   (lambda (x y z)
      (array-set!
         a1
         (string-append (string-join (map number->string (list x y z)) ",") "\n")
         x y z))
   a1)

; make a slice of big-array-of-anything
(define smaller-array-shared (subarray a1 '(0 1) '(0 4) '(8 9)))
; careful, because elements in smaller-array are shared by the original, so array-set! will modify both
(define smaller-array (array-copy smaller-array-shared))
; now we have an independent array

; make a 20x20 array of unsigned 16 bit integers initialized to 0
(define array-of-ints (make-array '#u16(0) 20 20))
Reply all
Reply to author
Forward
0 new messages