++
++
++
++ Berlin Brown
++
++ some scheme notes
++
++
++  $Id: scheme.html,v 1.1 2004/06/13 11:47:19 bigbinc Exp $
++


To run scheme from spiritbot; typically you can do

./scheme.sh

(as of 4/30/2004)

++
++ Note: there is not much format to this document
++
++ It is a lot of typical scheme syntax thrown together in
++ 
++ in one file.
++.........................................................

*New JScheme version*

Working with JScheme 6.3 - sourceforge.net


Most of the code below should work with the Spiritbot system

...........................................................


*6/2/2004*
	
	- Interesting -

	(define abc '(a b c))

	(define xyz (cons 'a abc))


	(cons 'a (list mm))
	-->(a (a b c))

	> (cdr '(a (a b c)))
	((a b c))


*Misc-B*


	// - Distinct - //
	--- [ See if every element is distinct ] -------------

	(define (distinct? items)
		(cond ((null? items) #t)
		      ((null? (cdr items)) #t)
		      ((member (car items) (cdr items)) #f)
		      (else (distinct? (cdr items)))))
 

	// - use standard list-ref //

	** Finding an element at a certain location **
	0  ... 1

	> (list-ref x 4)
	5
	> (list-ref x 1)
	2
	> (list-ref x 0)
	1
	> (define y '(#t #t #f))
	(#t #t #f)
	> (list-ref y 0)
	#t
	
	--------------------------
	

	** Good - way to define LISTS **
	(define colors '(red green blue))


	--------------------------


	(define x (cons 1 (cons 2 ())))

	(1 2)

	==> x

	(cons x y)

	==> ((1 2) 1 2)

	------------
	another way
	
	'x
	==> x
	

	(define (x) (cons 1 (cons 2 ())))

	(x)

	(1 2)

	x ==> gives the declaration(what it is)

	(lambda x ()...)

	It expects an object or proc

	(cons (x) (cons 2 ()))

	((1 2) 2)

	----------------------------------------

*Noun-Finder*

	(define simple-nouns '(dog cat))
	
	(define (nouns Items)
		(find-it Items simple-nouns)))

	(nouns 'cat)

	==> #t
	
	(nouns 'person)
	#f

	(map nouns '(berlin berlin))
	==> (#f #f)
	
		
	----------------------------------------------


	(define (find-it Item List)
        (cond ((null? List) #f)
                ((equal? Item (car List)) #t)
                (else (find-it Item (cdr List)))))

	(define (nouns Items)
		(find-it Items '(a b c))
        )

	
	(map nouns '(e f c))
	     (#f #f #t)
	            
         (map nouns '(e f g))
	 (#f #f #f)


*Maps*

	$$$ Map is similar to using for-each
	 - returns a list of the applied procedure -

	(map abs (list -10 4))

	(for-each (lambda (x) (newline) (display x))
           (list 57 321 88))
 
	57
	321
	88

	(map display '(a b c))
	abc(a b c)

	(cons (list 1 2) (list 3 4))


*Misc-A*

	(set! identifier expr)
	      This expression evaluates expr and changes the values associated with identifier. 
	      That identifier must have been previously bound.
	      
      (let (bindings) exp1 ... expN)
	   Each expr is evaluated and its value bound to the corresponding identifier.

*Natural Language*
	 
        (define ( ) )

	*Find member*

	
	(define (member thing lis)
		(if (null? lis)
		#f
		(if (equal? (car lis) thing)
		lis
		     (member thing (cdr lis)))))



	Note: member  = jscheme primitive
	(memq ................
	(member 'c '(a b c d e f g))

	---------------------------------

	*Find member of a list*

	(define (find-it Item List)
        (cond ((null? List) #f)
                ((equal? Item (car List)) #t)
                (else (find-it Item (cdr List)))))

	(find-it 'a noun)
	#t

	(define noun (list 'dog 'cat 'person))

	(define (nouns Items)
		 (find-it Items '(a b c))
        )

	(nouns 'a)

	


 
	==>>> (find-it 'v '(a b c d))
	==>> #f

	----------------------------------

	(define x (cons 1 2))
	(car x)
	(cdr x)
	

	(define nouns '(noun student dog cat))
	
	(define verbs '(verb study jump))

	(define articles '(article))

	----------------------

	(define (count-leaves x)
	   (cond ((null? x) 0)  
		 ((not (pair? x)) 1)
         (else (+ (count-leaves (car x))
                  (count-leaves (cdr x))))))
 

	-----------------
	
	(cons x L ) the list obtained by adding x to the beginning

	(eq? A B) ) <== when they are both the same object

	(equal? x y) <== 

	(for-each P L ) <== apply P to every element in L

	(list-tail L N) <== remove N elements

	(null? L ) return #t if L is the empty list

	(set-car!)
	
	(set-cdr!)

	(string-set!)

	(string-ref)

	(zero? z) return #t if z equals 0

	((list-ref L N ) returns the (N+1)st element of L. 
		   So (list-ref L 0) returns the first element of L. 
 
	-------------------------------------------------

	*Find a value in a list*
	
	 (define (ff item x)
		 (cond ((null? x) false)
		 ((eq? item (car x)) x)
		 (else (memq item (cdr x)))))
 	 (lambda ff (item x)...)

	(ff 'pear (list 'pear 'dog 'cat))
	(ff 'dog (list 'pear 'dog 'cat))
	 
	(dog cat)

	(equal? '(this is a list) '(this is a list)) 


	----------------------------------------------
		
*Quotes*

	We need a way to distinguish between symbols and their
	values

	(define a 1)
	(list a)

	==> (1)

	(list 'a)
	(a)

*Lists Again*

	(list 1 2)
	
	 is equivalent to

	(cons 1 (cons 2 ()))


	* also *
	(cons 1 (cons 2 (cons 3 (cons 4 (cons 5 ())))))
	(1 2 3 4 5)
	

	(define one-to-three (list 1 2 3))

	==> one-to-three    [ not (one-to-three), duh ]

	 (car one-to-three)
	 ==> 1

	'car' is the first element

	'cdr' is everything not the first

	(car (cons 1 2))
	==> 1

	(cdr (cons 1 2))
	==> 2

	cons -- Think of *cons*truct ....

	find an index on a list:
		
	--------------------------------------
			
	(define (list-ref items n)	
		(if (= n 0)
		  (car items)
		   (list-ref (cdr items) (- n 1))))

	
	-----------------------------------------

	*New function added for setting a list-ref CAR*

	(define (set-list-ref items n val)	
		(if (= n 0)
		  (set-car! items val)
		   (set-list-ref (cdr items) (- n 1) val)))


	-----------------------------------------

	(list-ref (list 1 2 3) 0)

	and of course define the list
	* (define alist (list 1 2 3)) *

	
	--------------------------------------

	(define (list-copy lis)
           (cond ((null? lis)
                '())
            (else
                (cons (car lis)
             (list-copy (cdr lis))))))


	------------------------------------

	 (define (lxb items)
	         (if (null? items)
	                 0
	                 (+ 1 (lxb (cdr items)))))

	(length (list 1 2 3 4))
	


	(define (lx x)
		(if (null? (cdr x))
		x
		(lx (cdr x))))

	(lx (list 'a 'b 'c))
	    
	


	--------------------------------

	(define (sq x)
		(* x x))

	==>>

	(define sq
		(lambda (x) (* x x)))
	
		

(define new-withdraw
   (let ((balance 100))
     (lambda (amount)
       (if (>= balance amount)
           (begin (set! balance (- balance amount))
                  balance)
           "Insufficient funds"))))

(new-withdraw 10)

------------------------------------------

(define balance 100)
 
 (define (withdraw amount)
   (if (>= balance amount)
       (begin (set! balance (- balance amount))
              balance)
       "Insufficient funds"))
 
(withdraw 10)
 
	 
*Strings*

	(string #\b)
	==> "b"


	(string? "Hello")
	==>#t
	
	(string? 'Hello)
	
	(string=? "Pie" "Pie")
	
	(substring "berlin" 2 4)

	(define bigTable '(
		(a b c d e f g)
		(x y z l m n o))


== [ From UT - Texas Website - Scheme Intro book ] ==
   [ user: wilson/schintro 			 ]

*More on Lists*

	(cdr '(1 2 3))
	==> (2 3)

	(reverse '(1 2 3 4))

	(let .... used with variable defining local

	(let* 
	  ==> used for multiple let statements

	(lambda (x) (+ x x)) <<== lambda just returns PTR to objects


	(define (db x)
		(+ x x))

	 ====> equals

	 (define db (lambda (x)
	 	(+ x x)))

	(cons 1 2)
	==> (1 . 2)

	extract values 'car' and 'cdr'


	$$ Looping Example $$

	(let loop ((x 0))
		 (display "Hello")  <$$ body    $$>
		 (newline)	    <$$ newline $$>
		 	(if (< x 10)
				(loop (+ x 1))))


 	[ ALSO ]

		 (define (list-sum lis)
		 	 (if (null? lis)
			 	0
				(+ (car lis)
					(list-sum (cdr lis)))))


		==>> (list-sum '(1 2 3))

		==> 6


		(list-sum (cons 1 (cons 2 (cons 3 '()))))

		==> 6

		$$ String Manip $$

		(map .toLowerCase '("BerLiN" "Brown"))
		==> ("berlin" "brown")



*Quote*

	scheme does not evaluate 'quote' expressions

	it will return exactly as is

	(define (foo)
		(list 1 2 3))

	return a new list




*Variable assignment*
	
	(set! foo 3)
	==> foo
	==> 3

	[ above not the best way ]
	(define foo 5)


	(define (foo) 15)
	==> (foo)
	==> 15

	(define (foo)
		15)

	define or set! == define allocates storage for variable	

	if 1 
	else if 2
	else if 3
	else 

	=== USE COND

	(cond	(1
		 (blah))
	 	(2
		 (blah2))
		(else
		 (blah3)))

	(cond	(1 (blah)) (2 (blah2)) (else (blah3)))

	=== [ END OF HOW to use COND ]




== [ JScheme Dot Notation ] ==

(define L '(1 2 3)) ===>
	
	Pair L = new Pair(new Integer("1"), ......

Note: some scheme code may be wrapped around java String code
   be warned...

sc.append("(define my-str (String. \"Yea\"))");
(eval)
sc.append("(.length my-str)");


Note: println just prints to system, doesnt return an object

sc = new StringBuffer();
sc.append("(.println System.out$ \"What?\")");


(list->vector '(1 2 3 4))
#(1 2 3 4)


(define (px x) (.println System.$out x))
px 'Berlin

== [ Working Scheme code ] ==

* Factorial and recursion

 (define ft (lambda (n) (if (= n 0) 1 (* n (ft (- n 1))))))
 (ft 12)
 ====> 479001600

 (define x 28)
 x   - output = 28


 ((if #f + *) 3 4)

 ====> 12

 ((if #t + *) 3 4)

 ====> 7


 (define add3 (lambda (x) (+ x 3)))
 (add3 3)
 ====> 6


 ## Lists ##
 (define x (list 'a 'b 'c))

 (define y x)
 
 y

 (a b c)

 (append '(Pat Kim) '(Robin Sandy))

 ====> (pat kim robin sandy)


 (length '(berlin brown was here))

 (define p '(Berlin Brown))

 (p)

 (berlin brown)

 (first p)

 (rest p)
 
 # types
 boolean?
 char?
 null?
 number?
 pair?
 procedure?
 string?
 symbol?
 vector?


#################################################
++ In Pure java ++

	res = schemeObject.getStringInput("(+ 1 1 1 1 1 2 4)");
	System.out.println(" |||" + res + "|||");

	res = schemeObject.getStringInput("(floor 1.4)");
	System.out.println(" |||" + res + "|||");

	res = schemeObject.getStringInput("(equal? 'A 'B)");
	System.out.println(" |||" + res + "|||");

	res = schemeObject.getStringInput("(equal? #(2 3) (vector 2 3))");
	System.out.println(" |||" + res + "|||");

	res = schemeObject.getStringInput("(define (xyz) display \"Yea\")");
	System.out.println(" |||" + res + "|||");


	(define (xyz)
	        display 'yes)

	==> (xyz)
	==> yes
	
	res = schemeObject.getStringInput("(xyz)");
	System.out.println(" |||" + res + "|||");

	res = schemeObject.getStringInput("(xyz)");
	System.out.println(" |||" + res + "|||");

	res = schemeObject.getStringInput("(Math.round 24.984709)");
	System.out.println(" |||" + res + "|||");
	
	StringBuffer sc = new StringBuffer();
	sc.append("(define my-str (String. \"Yea\")) (eval)");
	
	// [ big Scheme chunk ]
	
	try {

	    // [ Place volatile scheme code in a try catch block ]

	    res = schemeObject.getStringInput(sc.toString());
	    tmpMsg = res;
	    System.out.println(" @@@@" + res + "@@@@");

	} catch (SchemeException  e) {	    
	    
	    System.out.println("@@ Caught Exception @@------------------------------------------");
	    e.printStackTrace();
	    System.out.println("------------------------------------------");

	} // end of the try - catch ........


	sc = new StringBuffer();
	sc.append("(.println System.out$ \"What?\")");
	res = schemeObject.getStringInput(sc.toString());
	tmpMsg = res;

 
#################################################

== [ Related Links ]==

http://cvs.sourceforge.net/viewcvs.py/jscheme/jscheme/doc/

http://www-swiss.ai.mit.edu/~jaffer/r4rs_8.html


#################################################

6.8 Vectors



Vectors are heterogenous structures whose elements are indexed by integers. 
A vector typically occupies less space than a list of the same length, 
and the average time required to access a randomly chosen element 
is typically less for the vector than for the list. 

The length of a vector is the number of elements that it contains. 
This number is a non-negative integer that is fixed when the vector is created. 
The valid indexes of a vector are the exact non-negative integers less than the 
length of the vector. The first element in a vector is indexed by zero, and 
the last element is indexed by one less than the length of the vector. 


Vectors are written using the notation #(obj ...). For example, a vector of 
length 3 containing the number zero in element 0, the list `(2 2 2 2)' in 
element 1, and the string `"Anna"' in element 2 can be written as following: 


#(0 (2 2 2 2) "Anna")


 

Note that this is the external representation of a vector, not an expression 
evaluating to a vector. Like list constants, vector constants must be quoted: 


'#(0 (2 2 2 2) "Anna")  
          ==>  #(0 (2 2 2 2) "Anna")


 

essential procedure: vector? obj 
Returns #t if obj is a vector, otherwise returns #f. 

essential procedure: make-vector k 
procedure: make-vector k fill 

Returns a newly allocated vector of k elements. If a second argument is given, 
then each element is initialized to fill. Otherwise the initial 
contents of each element is unspecified. 


essential procedure: vector obj ... 

Returns a newly allocated vector whose elements contain the given arguments. Analogous to list. 

(vector 'a 'b 'c)                      ==>  #(a b c)


 

essential procedure: vector-length vector 

Returns the number of elements in vector. 


essential procedure: vector-ref vector k 

k must be a valid index of vector. Vector-ref returns the contents of element k of vector. 

(vector-ref '#(1 1 2 3 5 8 13 21)
            5)  
          ==>  8
(vector-ref '#(1 1 2 3 5 8 13 21)
            (inexact->exact
              (round (* 2 (acos -1))))) 
          ==> 13


 

essential procedure: vector-set! vector k obj 

k must be a valid index of vector. Vector-set! stores obj in element k 
of vector. The value returned by vector-set! is unspecified. 

(let ((vec (vector 0 '(2 2 2 2) "Anna")))
  (vector-set! vec 1 '("Sue" "Sue"))
  vec)      
          ==>  #(0 ("Sue" "Sue") "Anna")

(vector-set! '#(0 1 2) 1 "doe")  
          ==>  error  ; constant vector


 

essential procedure: vector->list vector 
essential procedure: list->vector list 

Vector->list returns a newly allocated list of the objects contained in
 the elements of vector. List->vector returns a newly created 
vector initialized to the elements of the list list. 

(vector->list '#(dah dah didah))  
          ==>  (dah dah didah)
(list->vector '(dididit dah))   
          ==>  #(dididit dah)


 



(a b c d e)


 

and 


(a . (b . (c . (d . (e . ())))))


 

are equivalent notations for a list of symbols. 



(a b c . d)


 

is equivalent to 


(a . (b . (c . d)))


 


(define x (list 'a 'b 'c))
(define y x)
y                                      ==>  (a b c)
(list? y)                              ==>  #t
(set-cdr! x 4)                         ==>  unspecified
x                                      ==>  (a . 4)
(eqv? x y)                             ==>  #t
y                                      ==>  (a . 4)
(list? y)                              ==>  #f
(set-cdr! x x)                         ==>  unspecified
(list? x)                              ==>  #f


 
Pair? returns #t if obj is a pair, and otherwise returns #f. 

(pair? '(a . b))                       ==>  #t
(pair? '(a b c))                       ==>  #t
(pair? '())                            ==>  #f
(pair? '#(a b))                        ==>  #f


 

essential procedure: cons obj1 obj2 


(cons 'a '())                          ==>  (a)
(cons '(a) '(b c d))                   ==>  ((a) b c d)
(cons "a" '(b c))                      ==>  ("a" b c)
(cons 'a 3)                            ==>  (a . 3)
(cons '(a b) 'c)                       ==>  ((a b) . c)


 

essential procedure: car pair 

Returns the contents of the car field of pair. Note that it is an error to take the car of the empty list. 

(car '(a b c))                         ==>  a
(car '((a) b c d))                     ==>  (a)
(car '(1 . 2))                         ==>  1
(car '())                              ==>  error


 


essential procedure: cdr pair 

Returns the contents of the cdr field of pair. Note that it is an error to take the cdr of the empty list. 

(cdr '((a) b c d))                     ==>  (b c d)
(cdr '(1 . 2))                         ==>  2
(cdr '())                              ==>  error


 


essential procedure: set-car! pair obj 

Stores obj in the car field of pair. The value returned by set-car! is unspecified. 

(define (f) (list 'not-a-constant-list))
(define (g) '(constant-list))
(set-car! (f) 3)                       ==>  unspecified
(set-car! (g) 3)                       ==>  error


 

essential procedure: set-cdr! pair obj 

Stores obj in the cdr field of pair. 
The value returned by set-cdr! is unspecified. 


essential procedure: caar pair 
essential procedure: cadr pair 

...: ... 

essential procedure: cdddar pair 
essential procedure: cddddr pair 

These procedures are compositions of car and cdr, 
where for example caddr could be defined by 

(define caddr (lambda (x) (car (cdr (cdr x))))).


 

Arbitrary compositions, up to four deep, are provided. 
There are twenty-eight of these procedures in all. 


essential procedure: null? obj 

Returns #t if obj is the empty list, otherwise returns #f. 



essential procedure: list? obj 

Returns #t if obj is a list, otherwise returns #f. By definition, all lists have 
finite length and are terminated by the empty list. 

        (list? '(a b c))               ==>  #t
        (list? '())                    ==>  #t
        (list? '(a . b))               ==>  #f
        (let ((x (list 'a)))
          (set-cdr! x x)
          (list? x))                   ==>  #f


 

essential procedure: list obj ... 

Returns a newly allocated list of its arguments. 

(list 'a (+ 3 4) 'c)                   ==>  (a 7 c)
(list)                                 ==>  ()


 

essential procedure: length list 

Returns the length of list. 

(length '(a b c))                      ==>  3
(length '(a (b) (c d e)))              ==>  3
(length '())                           ==>  0


 

essential procedure: append list ... 

Returns a list consisting of the elements of the first list followed by the elements of the other lists. 

(append '(x) '(y))                     ==>  (x y)
(append '(a) '(b c d))                 ==>  (a b c d)
(append '(a (b)) '((c)))               ==>  (a (b) (c))


The resulting list is always newly allocated, except that it 
shares structure with the last list argument. The last argument 
may actually be any object; an improper list results if the last argument is not a proper list. 

(append '(a b) '(c . d))               ==>  (a b c . d)
(append '() 'a)                        ==>  a


 

essential procedure: reverse list 

Returns a newly allocated list consisting of the elements of list in reverse order. 

(reverse '(a b c))                     ==>  (c b a)
(reverse '(a (b c) d (e (f))))  
          ==>  ((e (f)) d (b c) a)


 

procedure: list-tail list k 

Returns the sublist of list obtained by omitting the first k elements. 
List-tail could be defined by 

(define list-tail
  (lambda (x k)
    (if (zero? k)
        x
        (list-tail (cdr x) (- k 1)))))


 


essential procedure: list-ref list k 

Returns the kth element of list. (This is the same as the car of (list-tail list k).) 

(list-ref '(a b c d) 2)                 ==>  c
(list-ref '(a b c d)
          (inexact->exact (round 1.8))) 
          ==>  c


 

essential procedure: memq obj list 
essential procedure: memv obj list 
essential procedure: member obj list 

These procedures return the first sublist of list whose car is obj, 
where the sublists of list are the non-empty lists returned 
by (list-tail list k) for k less than the length of list. 
If obj does not occur in list, then #f (not the empty list) is 
returned. Memq uses eq? to compare obj with the elements of list, 
while memv uses eqv? and member uses equal?. 

(memq 'a '(a b c))                     ==>  (a b c)
(memq 'b '(a b c))                     ==>  (b c)
(memq 'a '(b c d))                     ==>  #f
(memq (list 'a) '(b (a) c))            ==>  #f
(member (list 'a)
        '(b (a) c))                    ==>  ((a) c)
(memq 101 '(100 101 102))              ==>  unspecified
(memv 101 '(100 101 102))              ==>  (101 102)


 


essential procedure: assq obj alist 
essential procedure: assv obj alist 
essential procedure: assoc obj alist 

Alist (for "association list") must be a list of pairs. 
These procedures find the first pair in alist whose car field is obj, 
and returns that pair. If no pair in alist has obj as its car, 
then #f (not the empty list) is returned. Assq uses eq? to compare 
obj with the car fields of the pairs in alist, while assv uses eqv? 
and assoc uses equal?. 

(define e '((a 1) (b 2) (c 3)))
(assq 'a e)                            ==>  (a 1)
(assq 'b e)                            ==>  (b 2)
(assq 'd e)                            ==>  #f
(assq (list 'a) '(((a)) ((b)) ((c))))
                                       ==>  #f
(assoc (list 'a) '(((a)) ((b)) ((c))))   
                                       ==>  ((a))
(assq 5 '((2 3) (5 7) (11 13)))    
                                       ==>  unspecified
(assv 5 '((2 3) (5 7) (11 13)))    
                                       ==>  (5 7)


 

Rationale: Although they are ordinarily used as predicates, memq, memv, 
member, assq, assv, and assoc do not have question marks in their 
names because they return useful values rather than just #t or #f.