I've been meaning to work through understanding functional programming for a while now, but just recently found out that the Structure and Interpretation of Computer Programs was online. SICP boots you up into Scheme fairly quickly, as the following program solves Exercise 1.12 (the 12th problem given).
As you can see from the code, I like indents to be able to follow how far in I'm nested, but from reading other people's code, it seems they don't. I'm still trying to figure that one out. And no, this code is not optimized for speed. ;)
; TODO: compute a given row of pascal's triangle (PT)
;
; from math, we know that each row of PT is a power of (x + 1)
; where the coefficients are the numbers in the row, therefore
; a recursive definition of PT would be:
; PT(0) = (x + 1)^0 = 1
; PT(n) = PT(n-1) * (x + 1)
; if PT's polynomial is represented as a list, multiplying a polynomial
; by (x + 1) is the same as adding the list to itself appended with 0
; both lists being right-justified
; e.g. (1 1)
; (1 1 0)
; =======
; (1 2 1)
;
; to handle the right-justification, we use reverse.
(define (math x)
(cond
( (< x 0) (display "no negative rows of Pascal's triangle\n"))
( (= x 0) (list 1) )
( (> x 0) (reverse (list-add
(reverse (append (math (- x 1)) (list 0) ))
(reverse (math (- x 1) ))
)))))
; add two lists of numbers together from left to right.
; e.g., (list-add (list 3 2 1 0)
; (list 2 1))
; => (5 3 1 0)
;
(define (list-add list0 list1)
(cond
( (> (length list1) (length list0))
(display "first *must* be longer length than second\n"))
( (= (length list1) 0 )
list0 )
( (> (length list1) 0 )
(append
(list
(+
(car list0)
(car list1)))
(list-add (cdr list0) (cdr list1) )
))))
(display (list-add (list 3 2 1 0) (list 1 1 ) ))
(display " list-add should be (4 3 1 0)\n")
(display (math 4))
(display " math should be ( 1 4 6 4 1 )\n")
That seems to work here using MIT-GNU/Scheme. A quick google didn't really answer my main question though...is it possible to comile scheme (or interpret it on the fly)? I had to do (load "foo.scm") at the scheme prompt to run it. For scheme to be somewhat useful to me, I'd really want to have it run without the commandline interpreter.
I've been using scsh, which means I just need a header like the following to make the script become executable (after chmod +x ;).
#!/usr/bin/scsh -s
!#
(display "Hello World!\n")