POV-Ray : Newsgroups : povray.pov4.discussion.general : Next Generation SDL Brainstorming : Re: Next Generation SDL Brainstorming Server Time
1 Jun 2024 08:12:38 EDT (-0400)
  Re: Next Generation SDL Brainstorming  
From: nemesis
Date: 27 Mar 2009 20:44:07
Message: <49cd72d7$1@news.povray.org>
clipka wrote:
> Not that I'd say Scheme or Lisp would suck, but... well, I don't have the
> slightest clue how to *decipher* it - could be ROT13-encrypted ancient egypt,
> from all I see :P

Errata: read v as vec. :P

 >> (define vec (make-vector 10))

This is clear enough, I guess:  defines vec to be the result of 
(make-vector 10), which should be self-evident as well:  makes a vector 
(array) of 10 elements.

 >> ((range 0 9) '() (lambda (i o) (vector-set! vec i (* i i)) o))

This is not plain Scheme, it's an idiom I use.  Let's decompose it.

First: in Lisp, anything in the head of a list (everything between 
parentheses) should be a function or a macro, should the list be 
evaluated.  An unevaluated list is like '(1 23 "foo") etc.  It's said to 
be quoted.

For instance:
(+ 1 2 3) results in the application arguments 1,2,3 to function +, thus 
yielding 6

'(+ 1 2 3) results in the list with the symbol + and numbers 1,2,3.

So from now on it's obvious that (range 0 9) results in a function, 
otherwise it wouldn't be in the head.

range is a handy function that returns, guess what!, another function. 
The function returned is an *iterator* for the given "range", in this 
case, 0 to 9.

The *iterator function* so returned gets 2 parameters:  the /initial 
value/ to be used as first result and a /reducer function/ that takes 
the current iteration step and the current result and returns a new result.

So, '() is the /initial value/ and (lambda (i o) (vector-set! vec i (* i 
i)) o) is the /reducer function/ I provided.  Both are fed to the 
*iterator function* returned by (range 0 9) which will successively feed 
the /reducer/ the current iteration item and the result so far.

In other words:  range returns a "functional" for loop. :) (I don't like 
Scheme's standard loop mechanism, "do")

(lambda args body ...) is Scheme's way of creating an anonymous 
function.  I could as well just previously defined it and given the name 
to the iterator, say:

(define powerize (lambda (i o) (vector-set! vec i (* i i)) o))
or sugared:
(define (powerize i o) (vector-set! vec i (* i i)) o)

and then:
((range 0 9) '() powerize)

anyway, (vector-set! vec i (* i i)) sets vector vec element i (vec[i] in 
C) to be (* i i).  And what is i?  i is the first argument to the 
/reducer function/, which represents the current iteration item, in this 
case a number in the 0-9 range.

Summing up:  given i = from range 0 to 9, it will set the current vector 
element to i*i.

Let's put c and my scheme idiom side-by-side:

((range 0 9) '() (lambda (i o) (vector-set! vec i (* i i)) o))
for(int i=0;i++<10;)vec[i]=i*i;

whoa!  Just remember it's all but a user-defined function with no 
syntatic sugar provided by macros wrapping it up.  I could just as well 
provide one such sugared version:

(define-syntax for
     (syntax-rules (=>)
       ((for i from to => body ...)
        ((range from to) #t (lambda (i o) (begin body ...) o)))))

(for i 0 9 => (@! vec i (* i i)))
for(int i=0;i++<10;)vec[i]=i*i;

Much better. :)
@! is my personal alias for vector-set!

Also, not seen here is the hability to actually have some useful result. 
  I mean, setting elements of an array is pretty much an imperative 
operation, but still you could simply pass the result of the whole call 
to yet another function using the vector just set, simply by doing:

((range 0 9) vec (lambda (i o) (vector-set! vec i (* i i)) o))

and then, using it like:
(vector-ref ((range 0 9) vec (lambda (i o) (vector-set! vec i (* i i)) 
o)) 2) => 4

Something you can't do with the built-in C for loop.


Was it really that hard? :)

BTW, aside from not mentioning it is a lexically-scoped language, you've 
just learned pretty much all the basic semantic of Scheme.  It is that 
simple a language.  Even though my particular idiom may sound a little 
daunting at first... :P


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.