scheme

Functional-Programming-Revisited

Scheme

    I want to change the style of my note book because recording the procedure of discovery maybe more useful.

    1. First problem:

    hi,

    I found another question unexplainable. Please help me with following simple recursion:

    ; first I defined a simple recursion function to display list properly
    (define mydisplaylist
    (lambda (x )
    (if (null? x) (display "end\n")
    (
    (display (car x))
    (display ", ")
    (mydisplaylist (cdr x))
    )
    )
    )
    )

    ; I run it:

    > (mydisplaylist '(1 3 6 7))
    1, 3, 6, 7, end
    *** ERROR IN mydisplaylist, "recursion.txt"@31.4 -- Operator is not a PROCEDURE
    (#!void #!void #!void)
    1>

    My question is why I have this error.

    answer: The error message is actually a bit disguise because you would not expect it is due to the return value of "display". And this problem

    is due to blur idea of what a recursion MUST RETURN. In mathematics you can define whatever you want to return. However, in LISP everything is

    contained in a list and you must return a "list". What I mean a "list" here is that the internal data structure of LISP. And in above example,

    it really returns a "list" of "display" function calls and the return value which is "void" are also constructed as a list. Therefore a list of

    "void" is in syntax a procedure call. The following mail explains that:

    hi,

    Thank you for your detailed explanation. However, I do believe I got the answer for my little problem after I trace step by step in "Scheme".

    The reason for the ERROR is not from syntax of a series of expressions included in one bracket. It is from the nature of LISP lanugage that

    everything must be represented in a list which means I CANNOT give result of number BESIDES a recursive function. Let me show you another

    example similar to my old case:
    ; it return each element in a list
    (define test1
    (lambda (ls)
    (if (null? (cdr ls))
    (car ls)
    ( (car ls)
      (test1 (cdr ls))
    )
    )
    )
    )
    You run it and get a similar error message like
    1> (test1 '(1 2 3 4))
    *** ERROR IN test1, "nick.txt"@38.4 -- Operator is not a PROCEDURE
    (3 4)

    The reason is that you return a NUMBER apart from the recursion function and they are all stored in a list which will be applied as a

    PROCEDURE by scheme. Say the very last recursion will return number 4, the upper frame will have already output number 3 before the last

    recursion. Therefore 3 and 4 will be considered by "Scheme" as a procedure call. This is definitely wrong.
    So, I have to construct a list as my result like following:
    (define test2
    (lambda (ls)
    (if (null? ls )
    '()
    (cons (car ls) (test2 (cdr ls)))

    )
    )
    )

    Run it and you just copy the list:
    > (test2 '(1 2 3 4))
    (1 2 3 4)

    Therefore I modified my old simple recursion like this and it works fine:

    (define displaylist2
    (lambda (ls)
    (if (null? ls)
    '()
    (concat (cons (car ls) (list ",")) (displaylist2 (cdr ls)))
    )
    )
    )
    ;this is just like c-language strcat which concatinate two lists
    (define concat
    (lambda (ls1 ls2)
    (if (null? (cdr ls1))
    (cons (car ls1) ls2)
    (cons (car ls1) (concat (cdr ls1) ls2))
    )
    )
    )

    > (displaylist2 '(1 2 3 4))
    (1 "," 2 "," 3 "," 4 ",")

    It is a bit cheating to display my list by constructing another list which is completely different from original one. However it suits my purpose.

    Thank you so much for your time and help and I really appreciate them. And I just cannot help telling you my discovery after I suspect it is

    a bug which is IMPOSSIBLE since it is such a common one.

    2. reverse a list:

    It may seem trivial to complete this task. However, it is not. At beginning I just use my original c/c++ thinking to try it and it is rather clumsy.

    See below, I first defined a function to retrieve the last element of a list---"lastone"

    (define lastone
    	(lambda (ls)
    		(if (null? (cdr ls))
    			(car ls)
    			(lastone (cdr ls))
    		)
    	)
    )

    And then I defined another rather redundant function "popend":

    (define popend
    	(lambda (ls)
    		(if (null? (cdr ls))
    			'()
    			(cons (car ls) (popend (cdr ls)))
    		)
    	)
    )

    Then I can now fulfill my "reverse" by an iterating operation like this:

    (define reverse1
    	(lambda (ls)
    		(if (null? (cdr ls))
    			ls
    			(cons (lastone ls) (reverse1 (popend ls)) )
    		)
    	)
    )

    This is highly inefficient because you pass twice for one element, retrieve last one and pop last one. So, I find the right way after re-thinking.

    (define concat
    	(lambda (ls1 ls2)
    		(if (null? (cdr ls1))
    			(cons (car ls1) ls2)
    			(cons (car ls1) (concat (cdr ls1) ls2))
    		)
    	)
    )

    (define reverse2
    	(lambda (ls)
    		(if (null? (cdr ls))
    			ls
    			(concat (reverse2 (cdr ls))  (list (car ls)))
    		)
    	)
    )

    3. display a list

    This is a trivial task if you have solved the first problem.

    (define displaylist
    	(lambda (x )
    		(if (null?  (cdr x))
    			(
    				list (car x)
    			)

    			(
    				concat (cons  (car x) (list "," )) (displaylist (cdr x))
    			)

    		)
    	)
    )

    4. quicksort

    I guess if you can write a quicksort in scheme, probably you can write lots of programming problems in scheme. At beginning I started from wrong

    way since I forgot the algorithms I learned in data structure. The mistake is that I am not looking for a pivot, instead I am looking for the

    first occurrence of an element in a list. Even though these functions may prove useful in other cases, they are useless for quicksort:

    (define findhead
    	(lambda (f)
    		(lambda (ls x)
    			(if (null? ls)
    				'()
    				(if (f (car ls) x)
    					'()
    					(cons (car ls) ((findhead f) (cdr ls) x))
    				)
    			)
    		)
    	)
    )

    (define findhead_lessthan
    	(findhead <)
    )
    (define findhead_greatthan
    	(findhead >)
    )

    (define findtail
    	(lambda (f)
    		(lambda (ls x)
    			(if (null? ls)
    				'()
    				(if (f (car ls) x)
    					ls
    					((findtail f) (cdr ls) x)
    				)
    			)
    		)
    	)
    )

    (define findtail_lessthan
    	(findtail <)
    )
    (define findtail_equal
    	(findtail =)
    )
    (define findtail_greatthan
    	(findtail >)
    )

    After a while, I began to find the right way when I quickly review my comp352. And I also recalled why professor Grogono likes to use "filter"

    in comp348 which is concentrating on Huskel, another dialect of LISP.

    (define binary_negate
    	(lambda (f)
    		(lambda (x y)
    			(not (f x y))
    		)
    	)
    )

    (define filter
    	(lambda (f)
    		(lambda (ls x)
    			(if (null? ls)
    				'()
    				(if (f (car ls) x)
    					(cons (car ls) ((filter f) (cdr ls) x))
    					((filter f) (cdr ls) x)
    				)
    			)
    		)
    	)
    )

    (define filter_lessthan
    	(filter <)
    )

    (define filter_greaterthan
    	(filter >)
    )
    (define filter_greaterequal
    	(filter >=)
    )

    (define doquicksort_a
    	(lambda (ls)
    		(if (null? ls)
    			'()
    			(concat (doquicksort_a (filter_lessthan (cdr ls) (car ls)))
    				(cons (car ls)
    					(doquicksort_a  (filter_greaterequal (cdr ls) (car ls)))
    				)
    			)
    		)
    	)
    )

    (define concat
    	(lambda (ls1 ls2)
    		(if (null? ls1)
    			ls2
    			(cons (car ls1) (concat (cdr ls1) ls2))
    		)
    	)
    )

    (define quicksort
    	(lambda (f)
    		(lambda (ls)
    			(if (null? ls)
    				'()
    				(concat ((quicksort f) ((filter f) (cdr ls) (car ls)))
    					(cons (car ls)
    						((quicksort f) ((filter (binary_negate f)) (cdr ls) (car ls)))
    					)
    				)
    			)
    		)
    	)
    )

    The only thing I want to point out is that my quicksort can be either ascending or descending by given "<" or ">" as parameter. It takes me for

    a while to figure out how I should define a negation for an operator. Of course it must be a binary operator. (This is a difficult issue. You see

    you cannot define negation operator for any operator unless you know whether it is unary, binary etc.) Therefore in above "quicksort_a" is not

    necessary.

    5. generating permutation of a list

    This is a breaking-neck problem, at least it is the case for me. It takes me about four hours to complete the task.

    At first I have rough idea like this: Divide a list into two subset one is the set containing only first element and the other is the set containing

    all rest elements except the first element. Then we assume we can successfully generate a list which contains all permutations of second set which

    contains all elements except the first one, denoting as L. Now the total permutation of original list must include the first element in its final

    permutation. Therefore I just put the first element between each two consecutive element of list L. And this will generate all possible permutation

    between L and the first element.

    Therefore the task is reduced to generate a function so that I can insert an element between its each two consecutive elements. It is like this:

    (define findhead_n
    	(lambda (ls n)
    		(if (null? ls)
    			'()
    			(if (= n 0)
    				'()
    				(cons (car ls) (findhead_n (cdr ls) (- n 1)))
    			)
    		)
    	)
    )

    (define findtail_n
    	(lambda (ls n)
    		(if (null? ls)
    			'()
    			(if (= n 0)
    				ls
    				(findtail_n (cdr ls) (- n 1))
    			)
    		)
    	)
    )

    (define concat
    	(lambda (ls1 ls2)
    		(if (null? ls1)
    			ls2
    			(cons (car ls1) (concat (cdr ls1) ls2))
    		)
    	)
    )

    (define doinsertlist
    	(lambda (ls x n)
    		(if (= n 0)
    			(list (cons x ls))
    			(cons (concat (findhead_n ls n) (cons x (findtail_n ls n) ) )
    				(doinsertlist ls x (- n 1))
    			)
    		)
    	)
    )

    (define insertlist
    	(lambda (x ls)
    		(doinsertlist ls x (length ls))

    	)
    )

    Then I need to recursively call this "insertlist" operation to apply it to each element of function "permutation" which is also a list. Therefore

    I write a simple function like simple "map":

    (define foreach
    	(lambda (f)
    		(lambda (ls)
    			(if   (null? ls)
    				'()
    				(cons (f (car ls)) ((foreach f) (cdr ls)))
    			)
    		)
    	)
    )

    However, "insertlist" takes two parameter. So, I have to wrap it into "insertlistop" which takes a list as parameter.

    (define insertlistop
    	(lambda (x)
    		(lambda (ls)
    			(insertlist x ls)
    		)
    	)
    )

    Now I can define my "permutation":

    (define permutation
    	(lambda (ls)
    		(if (null? (cdr ls))
    			(list ls)
    			(concatlist ((foreach (insertlistop (car ls))) (permutation (cdr ls))))
    		)
    	)
    )

    But the result is a list such that each its element is a list of list. This is not acceptable since we need only a list of list. Therefore I

    defined a function to concatenate all its element of a list into a list.

    (define concatlist
    	(lambda (ls)
    		(if (null? ls)
    			'()
    			(concat (car ls) (concatlist (cdr ls)))
    		)
    	)
    )

    Now we finished with a permutation of a list.

    6. generating all combinations of a list or its super set

    After four hours practising in generating permutation, this problem is as fast as a snapping a finger. And I realized a way to simulate my

    makefile like this:

    (load "utility.txt")
    (load "combination.txt")

    And as the name suggests, in "utility.txt" file I defined all those common utility functions like "concat", "foreach" ect. Then I only need to

    type at command line: (load "makefile.txt")

    The idea is very similar with permutation. You just divide whole set into two subset with first element as one set and all other elements in

    another set. Then assume we already generate the combination list for all other elements. What we need to do now is to add the first element

    into each combination of the sub-combination and concatenate this new list with old sub-combination.

    (define addlist
    	(lambda (x)
    		(lambda (ls)
    			(cons x ls)
    		)
    	)
    )

    (define combination
    	(lambda (ls)
    		(if (null? ls)
    			(list(list))
    			(concat (combination (cdr ls))
    				((foreach (addlist (car ls))) (combination (cdr ls)))
    			)
    		)
    	)
    )

    7. Tower of Hanoi:

    Problem: Everyone should have known it.

    version1: this is a stupid version which does some useless moves.

    (define concat
    	(lambda (ls1 ls2)
    		(if (null? ls1)
    			ls2
    			(cons (car ls1) (concat (cdr ls1) ls2))
    		)
    	)
    )

    (define filltower
    	(lambda (n)
    		(if (= n 0)
    			'()
    			(cons n (filltower (- n 1)))
    		)
    	)
    )

    (define initialize
    	(lambda (n)
    		(cons '() (list (filltower n) (filltower 0) (filltower 0)))
    	)
    )

    ;(define displaytower
    ;	(lambda (ls)
    ;		(display 'container-1\n')
    ;		(displaylist (car ls))
    ;		(display 'container-2\n')
    ;		(displaylist (cadr ls))
    ;		(display 'container-3\n')
    ;		(displaylist (caddr ls))
    ;		(display '\n')
    ;	)
    ;)

    (define tgt
    	(lambda (ls)
    		(caddr (cdr ls))
    	)
    )

    (define buf
    	(lambda (ls)
    		(cadr (cdr ls))
    	)
    )

    (define src
    	(lambda (ls)
    		(car (cdr ls))
    	)
    )
    (define msg
    	(lambda (ls)
    		(car ls)
    	)
    )

    (define domovebox1_3
    	(lambda (ls)
    		(if (or (null? (tgt ls)) (> (car (src ls)) (car (tgt ls))  ))
    			(cons (cons (list 'moved (car (src ls)) 'container-1 'container-3) (msg ls))
    				(list  (cdr (src ls))  (buf ls)  (cons (car (src ls)) (tgt ls)) ) )
    				(domovebox2_3 (domovebox1_3 (domovebox3_2 ls)))
    		)
    	)
    )
    (define domovebox1_2
    	(lambda (ls)
    		(if (or (null? (buf ls)) (> (car (src ls)) (car (buf ls))))
    			(cons (cons (list 'moved (car (src ls)) 'container-1 'container-2) (msg ls))
    				(list (cdr (src ls))  (cons (car (src ls)) (buf ls)) (tgt ls)))
    				(domovebox3_2 (domovebox1_2 (domovebox2_3 ls)))
    		)
    	)
    )

    (define domovebox2_3
    	(lambda (ls)
    		(if (or (null? (tgt ls)) (> (car (buf ls)) (car (tgt ls))))
    			(cons (cons (list 'moved  (car (buf ls)) 'container-2 'container-3) (msg ls))
    				(list (src ls)   (cdr (buf ls))  (cons (car (buf ls)) (tgt ls))))
    				(domovebox1_3(domovebox2_3 (domovebox3_1 ls)))
    		)
    	)
    )

    (define domovebox2_1
    	(lambda (ls)
    		(if (or (null? (src ls)) (> (car (buf ls)) (car (src ls))))
    			(cons (cons (list 'moved  (car (buf ls)) 'container-2 'container-1) (msg ls))
    				(list (cons (car (buf ls)) (src ls)) (cdr (buf ls))  (tgt ls)))
    				(domovebox3_1(domovebox2_1 (domovebox1_3 ls)))
    		)
    	)
    )

    (define domovebox3_2
    	(lambda (ls)
    		(if (or (null? (buf ls)) (> (car (tgt ls)) (car (buf ls))))
    			(cons (cons (list 'moved  (car (tgt ls)) 'container-3 'container-2) (msg ls))
    				(list  (src ls)  (cons (car (tgt ls)) (buf ls)) (cdr (tgt ls))))
    				(domovebox1_2(domovebox3_2 (domovebox2_1 ls)))
    		)
    	)
    )

    (define domovebox3_1
    	(lambda (ls)
    		(if (or (null? (src ls)) (> (car (tgt ls)) (car (src ls))))
    			(cons (cons (list 'moved (car (tgt ls)) 'container-3 'container-1) (msg ls))
    				(list  (cons (car (tgt ls)) (src ls))  (buf ls) (cdr (tgt ls))))
    				(domovebox2_1(domovebox3_1 (domovebox1_2 ls)))
    		)
    	)
    )

    ; hanoi = (list src buf tgt)

    (define movebox
    	(lambda (ls index)
    		(if (= index (car (src ls)))
    			(domovebox1_3 ls)
    			(movebox (movebox ls (+ index 1)) index)
    		)
    	)
    )

    (define reverselist
    	(lambda (ls)
    		(if (null? ls)
    			'()
    			(if (null? (cdr ls))
    				ls
    			        (concat (reverselist (cdr ls)) (list (car ls)))
    			)
    		)
    	)
    )

    (define hanoi
    	(lambda (n)
    		(reverselist (car (movebox (initialize n) 1) ) )
    	)
    )

    version 2: this is an improved version but those idiot-like repeat functions really looks ugly.

    (define concat
    	(lambda (ls1 ls2)
    		(if (null? ls1)
    			ls2
    			(cons (car ls1) (concat (cdr ls1) ls2))
    		)
    	)
    )

    (define reverselist
    	(lambda (ls)
    		(if (null? ls)
    			'()
    			(if (null? (cdr ls))
    				ls
    			        (concat (reverselist (cdr ls)) (list (car ls)))
    			)
    		)
    	)
    )

    (define filltower
    	(lambda (n)
    		(if (= n 0)
    			'()
    			(cons n (filltower (- n 1)))
    		)
    	)
    )

    (define initialize
    	(lambda (n)
    		(cons '() (list (filltower n) (filltower 0) (filltower 0)))
    	)
    )

    ;(define displaytower
    ;	(lambda (ls)
    ;		(display 'container-1\n')
    ;		(displaylist (car ls))
    ;		(display 'container-2\n')
    ;		(displaylist (cadr ls))
    ;		(display 'container-3\n')
    ;		(displaylist (caddr ls))
    ;		(display '\n')
    ;	)
    ;)

    (define tgt
    	(lambda (ls)
    		(caddr (cdr ls))
    	)
    )

    (define buf
    	(lambda (ls)
    		(cadr (cdr ls))
    	)
    )

    (define src
    	(lambda (ls)
    		(car (cdr ls))
    	)
    )
    (define msg
    	(lambda (ls)
    		(car ls)
    	)
    )

    (define domovebox1_3
    	(lambda (ls)
    		(if (or (null? (tgt ls)) (> (car (src ls)) (car (tgt ls))  ))
    			(cons (cons (list 'moved (car (src ls)) 'container-1 'container-3) (msg ls))
    				(list  (cdr (src ls))  (buf ls)  (cons (car (src ls)) (tgt ls)) ) )
    				(domovebox2_3 (domovebox1_3 (domovebox3_2 ls)))
    		)
    	)
    )
    (define domovebox1_2
    	(lambda (ls)
    		(if (or (null? (buf ls)) (> (car (src ls)) (car (buf ls))))
    			(cons (cons (list 'moved (car (src ls)) 'container-1 'container-2) (msg ls))
    				(list (cdr (src ls))  (cons (car (src ls)) (buf ls)) (tgt ls)))
    				(domovebox3_2 (domovebox1_2 (domovebox2_3 ls)))
    		)
    	)
    )

    (define domovebox2_3
    	(lambda (ls)
    		(if (or (null? (tgt ls)) (> (car (buf ls)) (car (tgt ls))))
    			(cons (cons (list 'moved  (car (buf ls)) 'container-2 'container-3) (msg ls))
    				(list (src ls)   (cdr (buf ls))  (cons (car (buf ls)) (tgt ls))))
    				(domovebox1_3(domovebox2_3 (domovebox3_1 ls)))
    		)
    	)
    )

    (define domovebox2_1
    	(lambda (ls)
    		(if (or (null? (src ls)) (> (car (buf ls)) (car (src ls))))
    			(cons (cons (list 'moved  (car (buf ls)) 'container-2 'container-1) (msg ls))
    				(list (cons (car (buf ls)) (src ls)) (cdr (buf ls))  (tgt ls)))
    				(domovebox3_1(domovebox2_1 (domovebox1_3 ls)))
    		)
    	)
    )

    (define domovebox3_2
    	(lambda (ls)
    		(if (or (null? (buf ls)) (> (car (tgt ls)) (car (buf ls))))
    			(cons (cons (list 'moved  (car (tgt ls)) 'container-3 'container-2) (msg ls))
    				(list  (src ls)  (cons (car (tgt ls)) (buf ls)) (cdr (tgt ls))))
    				(domovebox1_2(domovebox3_2 (domovebox2_1 ls)))
    		)
    	)
    )

    (define domovebox3_1
    	(lambda (ls)
    		(if (or (null? (src ls)) (> (car (tgt ls)) (car (src ls))))
    			(cons (cons (list 'moved (car (tgt ls)) 'container-3 'container-1) (msg ls))
    				(list  (cons (car (tgt ls)) (src ls))  (buf ls) (cdr (tgt ls))))
    				(domovebox2_1(domovebox3_1 (domovebox1_2 ls)))
    		)
    	)
    )

    ; hanoi = (list src buf tgt)

    (define listmovebox1_3
    	(lambda (ls index)
    		(if (= index (car (src ls)))
    			(domovebox1_3 ls)
    			(listmovebox2_3 (listmovebox1_3 (listmovebox1_2 ls (+ index 1)) index)(+ index 1))
    		)
    	)
    )

    (define listmovebox1_2
    	(lambda (ls index)
    		(if (= index (car (src ls)))
    			(domovebox1_2 ls)
    			(listmovebox3_2 (listmovebox1_2 (listmovebox1_3 ls (+ index 1)) index) (+ index 1))
    		)
    	)
    )

    (define listmovebox3_2
    	(lambda (ls index)
    		(if (= index (car (tgt ls)))
    			(domovebox3_2 ls)
    			(listmovebox1_2 (listmovebox3_2 (listmovebox3_1 ls (+ index 1)) index) (+ index 1))
    		)
    	)
    )

    (define listmovebox3_1
    	(lambda (ls index)
    		(if (= index (car (tgt ls)))
    			(domovebox3_1 ls)
    			(listmovebox2_1 (listmovebox3_1 (listmovebox3_2 ls (+ index 1)) index)(+ index 1))
    		)
    	)
    )

    (define listmovebox2_1
    	(lambda (ls index)
    		(if (= index (car (buf ls)))
    			(domovebox2_1 ls)
    			(listmovebox3_1(listmovebox2_1 (listmovebox2_3 ls (+ index 1)) index)(+ index 1))
    		)
    	)
    )

    (define listmovebox2_3
    	(lambda (ls index)
    		(if (= index (car (buf ls)))
    			(domovebox2_3 ls)
    			(listmovebox1_3 (listmovebox2_3 (listmovebox2_1 ls (+ index 1)) index) (+ index 1))
    		)
    	)
    )

    (define hanoi
    	(lambda (n)
    		(reverselist (car (listmovebox1_3 (initialize n) 1) ) )
    	)
    )

    8. generating all partition pattern for a list

    (recall a partition for a set is the set of all its non-empty unique subset such that the union of these subset is the set and any two subset

    are disjoint.)

    (This takes me quite a lot of time! The first trial failed after hours of struggle even though I know the algorithm very clearly. The second

    trial also takes me a half night after I realized my stupid mistake.)

    (The idea is still the similar to combination and permutation. Just consider one element, how would you add it into a pattern of a partition?

    There is two kinds of "join": one is that you use this single element as one subset in each partition pattern; the other is to let this element

    become a part of each subset once and generate a series partition pattern.)

    (define foreach
    	(lambda (f)
    		(lambda (ls)
    			(if (null? ls)
    				'()
    				(cons (f (car ls)) ((foreach f) (cdr ls)))
    			)
    		)
    	)
    )

    (define dojoineach
    	(lambda (x front back)
    		(if (null? (cdr back))
    			(list (append front (list (cons x (car back)))))
    			(cons (append front (list (cons x (car back))) (cdr back))
    				(dojoineach x (append front (list(car back))) (cdr back))
    			)
    		)
    	)
    )

    (define joineachop
    	(lambda (x ls)
    		(dojoineach x '() ls)
    	)
    )

    (define joineach
    	(lambda (x ls)
    		(if (null? ls)
    			'()
    			(append (joineachop x (car ls))(joineach x (cdr ls)))
    		)

    	)
    )

    (define appendop
    	(lambda (x)
    		(lambda (ls)
    			(cons (list x) ls)
    		)
    	)
    )

    (define appendeach
    	(lambda (x ls)
    		(begin ;(pp(list "appendeach x=" x "ls=" ls))
    		((foreach (appendop x)) ls)
    		)
    	)
    )

    (define partition
    	(lambda (ls)
    		(if (null? ls)
    			'()
    			(if (null? (cdr ls))
    				(list(list ls))
    				(let ((result (partition (cdr ls))))
    					(append (appendeach (car ls) result)(joineach (car ls) result))
    				)
    			)
    		)
    	)
    )

    9. how to justify if a number is a prime or not. (not academic sense, so, 1 or negative number is not concerned)

    Actually I feel a bit embarrassed since this is the first time I understand how to do "while loop" in scheme. The "let" is called "namelet".

    And I wouldn't be surprised to hear that it is implemented by a "goto". In my mind, the argument to "let" is like an address of a code where

    you want to start to loop.

    (define prime
    	(lambda (num)
    		(let f ((i 2))
    			(if (>= i num)
    				#t
    				(if (integer? (/ num i))
    					#f
    					(f (+ i 1))
    				)
    			)
    		)
    	)
    )

    10. how to read a string from command line? and how to read a number from command line?

    (this read-string is a modified example from book. I changed it a little bit to make it special for command line input which is ended by

    new line character.)

    (define read-string
    	(lambda ()
    		(read-char); ignore the first newline
    		(list->string
    			(let loop ((c (read-char)))
    				(cond
    					((eq? c #\newline) '())
    					(else
    						(cons c (loop (read-char)))
    					)
    				)
    			)
    		)
    	)
    )

    (what do you think? are we doing assembly coding now?)

    (define numeric->integer
    	(lambda (c)
    		(- (char->integer c)(char->integer #\0))
    	)
    )

    (define read-number
    	(lambda ()
    		(read-char)
    		(let loop ((c (read-char))(result 0)(start #f))
    			(cond
    				((and start (eq? c #\newline)) result)
    				;((and (not start)(eq? #\newline)) #f)
    				((char-numeric? c)
    					(set! start #t)
    					(set! result (+ (numeric->integer c) (* result 10)))
    					(loop (read-char) result start)
    				)
    				(else (newline)#f)
    			)
    		)
    	)
    )

    11. the problem of "vector-ref"

    I am not really sure about the problem now because it seems that it appears on some day and doesn't appear on some other day.

    Basically it is like this: I have a vector of vector and the way I want to access the data is by using "vector-ref" and the way I want to

    modify data is by using "vector-set!". Then at some time, when I try to modify a "copied" vector, it even modifies the source vector no matter

    whatever method of copying I am using. However, today when I want to post the detail, it seems disappeared?!!!

    ¡¡

    ¡¡

    ¡¡

    ¡¡

    ¡¡

    ¡¡