This page contains the description of the following commands caaaar, caaadr, caaar, caadar, caaddr, caadr, caar, cadaar, cadadr, cadar, caddar, cadddr, caddr, cadr, car, cartesian_product_seq, case, catch, catcherror, catenate, catenate1, cdaaar, cdaadr, cdaddr, cdaar, cdadar, cdadr, cdar, cddaar, cddadr, cddar, cdddr, cdddar, cddddr, cddr, cdr, ceiling, cf-to-rational, channel, change_theta, check_bep, chrpos, circopy, cirequal, cirprinflush, cirprint, cirprint-to-string, close, close, color_tty, comline, compare, compare_eps, complex, complexp, concat, cond, cons, conjugate, consp, constantp, copy, copyarray, copylist, cos, cosh, csend, cur-line-no, current-directory,
There is no difference between (caaaar x) and (car (car (car (car x)))). The function could be define in Lisp as follows (this definition gives the right error message). See car below.
(defun caaaar (x) (unless (consp x) (error 'caaar 'errnla x)) (setq x (car x)) (unless (consp x) (error 'caaar 'errnla x)) (setq x (car x)) (unless (consp x) (error 'caaar 'errnla x)) (setq x (car x)) (unless (consp x) (error 'caaar 'errnla x)) (car x))
There is no difference between (caaadr x) and (car (car (car (cdr x)))). See car below.
There is no difference between (caaar x) and (car (car (car x))). See car below.
There is no difference between (caadar x) and (car (car (cdr (car x)))). See car below.
There is no difference between (caaddr x) and (car (car (cdr (cdr x)))). See car below.
There is no difference between (caadr x) and (car (car (cd x))). See car below.
There is no difference between (caar x) and (car (car x)). See car below.
There is no difference between (cadaar x) and (car (cdr (car (car x)))). See car below.
There is no difference between (cadadr x) and (car (cdr (car (cdr x)))). See car below.
There is no difference between (cadar x) and (car (cdr (car x))). See car below.
There is no difference between (caddar x) and (car (cdr (cdr (car x)))). See car below.
There is no difference between (cadddr x) and (car (cdr (cdr (cdr x)))). See car below.
There is no difference between (caddr x) and (car (car (cdr x))). See car below.
There is no difference between (cadr x) and (car (cdr x)). See car below.
The two functions car and cdr take as argument a list, and return, respectively, the CAR and CDR of the list. There is a symbolic version of these two functions that apply to symbolic lists. If L is a list (symbolic or not) then L["car"] and L["cdr"] can be used to get or modify the CAR or CDR of the list, see array documentation.
The Lisp functions caar cadr, cdar, cddr return the CAR of the CAR, the CAR of the CDR, etc. There are variants with three and four letters between the C and the R. In the example, we start with a big list, and show the functions car and cdr.
[Endymion] (setq caaar (cons 1 2) [Endymion] cdaar (cons 3 4) [Endymion] cadar (cons 5 6) [Endymion] cddar (cons 7 8) [Endymion] caadr (cons 9 10) [Endymion] cdadr (cons 11 12) [Endymion] caddr (cons 13 14) [Endymion] cdddr (cons 15 16) [Endymion] caar (cons caaar cdaar) [Endymion] cdar (cons cadar cdadr) [Endymion] cadr (cons cadar cdadr) [Endymion] cddr (cons caddr cdddr) [Endymion] car (cons caar cdar) [Endymion] cdr (cons cadr cddr) [Endymion] x (cons car cdr)) ((((1 . 2) 3 . 4) (5 . 6) 7 . 8) ((9 . 10) 11 . 12) (13 . 14) 15 . 16) [Endymion] (car x) (((1 . 2) 3 . 4) (5 . 6) 7 . 8) [Endymion] (cdr x) (((9 . 10) 11 . 12) (13 . 14) 15 . 16) [Endymion] (eq (car x) car) true [Endymion] (eq (cdr x) cdr) true [Endymion] (car 0) car : not a list : 0 [Endymion] (cdr 0) cdr : not a list : 0
Now the funcions c??r.
[Endymion] (caar x) ((1 . 2) 3 . 4) [Endymion] (cadr x) ((9 . 10) 11 . 12) [Endymion] (cdar x) ((5 . 6) 7 . 8) [Endymion] (cddr x) ((13 . 14) 15 . 16) [Endymion] (caar 0) caar : not a list : 0 [Endymion] (cadr 0) cadr : not a list : 0 [Endymion] (cdar 0) cdar : not a list : 0 [Endymion] (cddr 0) cddr : not a list : 0 [Endymion] (cadr '(1 . 2)) cadr : not a list : 2 [Endymion] (cadr '(1 . 2)) cadr : not a list : 2 [Endymion] (cdar '(1 . 2)) cdar : not a list : 1 [Endymion] (cddr '(1 . 2)) cddr : not a list : 2
Now the funcions c???r.
[Endymion] (caaar x) (1 . 2) [Endymion] (caadr x) (9 . 10) [Endymion] (cadar x) (5 . 6) [Endymion] (caddr x) (13 . 14) [Endymion] (cdaar x) (3 . 4) [Endymion] (cdadr x) (11 . 12) [Endymion] (cddar x) (7 . 8) [Endymion] (cdddr x) (15 . 16) [Endymion] (caaar 0) caaar : not a list : 0 [Endymion] (caaar '(0)) caaar : not a list : 0 [Endymion] (caaar '((0))) caaar : not a list : 0 [Endymion] (caaar '(((0)))) 0
Now the functions c????r.
[Endymion] (caaaar x) 1 [Endymion] (cdaaar x) 2 [Endymion] (cadaar x) 3 [Endymion] (cddaar x) 4 [Endymion] (caadar x) 5 [Endymion] (cdadar x) 6 [Endymion] (caddar x) 7 [Endymion] (cdddar x) 8 [Endymion] (caaadr x) 9 [Endymion] (cdaadr x) 10 [Endymion] (cadadr x) 11 [Endymion] (cddadr x) 12 [Endymion] (caaddr x) 13 [Endymion] (cdaddr x) 14 [Endymion] (cadddr x) 15 [Endymion] (cddddr x) 16 [Endymion] (cdadar 0) cdadar : not a list : 0 [Endymion] (cdadar '(1 . 2)) cdadar : not a list : 1 [Endymion] (cdadar '((3 . 4) . 2)) cdadar : not a list : 4 [Endymion] (cdadar '((3 . (5 . 6)) . 2)) cdadar : not a list : 5 [Endymion] (cdadar '((3 . ((7 . 8) . 6)) . 2)) 8
The cartesian_product_seq command takes some sequences as arguments and returns the cartesian product of them. In the case of two arguments, say x and y, it returns the sequence of all [xi, yj], starting with j=1, then j=2, etc. In the special case where no argument is given, the result has a single element, the empty list.
(1) cartesian_product_seq([1,2,3],[a,b,c]); (1) <UninitializedSequence: CP, <vector: <UninitializedSequence: list, [1, 2, 3]>, <UninitializedSequence: list, [a, b, c]>>> (2) makeseq(%); (2) <InitializedSequence: CP, <vector: <InitializedSequence: list, [1, 2, 3] >, <InitializedSequence: list, [a, b, c]>>, <vector: < UninitializedSequence: list, [1, 2, 3]>, <UninitializedSequence: list, [a, b, c]>>> (3) seq_to_list(%); (3) [[1, a], [2, a], [3, a], [1, b], [2, b], [3, b], [1, c], [2, c], [3, c]] (4) X:=cartesian_product_seq([1,2,3], [a,b,c], 1...5 step 2 )?; (5) seq_to_list(makeseq(X)); (5) [[1, a, 1], [2, a, 1], [3, a, 1], [1, b, 1], [2, b, 1], [3, b, 1], [1, c, 1], [2, c, 1], [3, c, 1], [1, a, 3], [2, a, 3], [3, a, 3], [1, b, 3], [2, b, 3], [3, b, 3], [1, c, 3], [2, c, 3], [3, c, 3], [1, a, 5], [2, a, 5], [3, a, 5], [1, b, 5], [2, b, 5], [3, b, 5], [1, c, 5], [2, c, 5], [3, c, 5]]
The case and ocase macros are the symbolic equivalent of selectq, with a strange syntax. See ocase
The catch special form takes three arguments. The first is the name of a tag, or a list of tags, or all, this allows to catch a single tag, a list of tags, or all tags. The second argument is an expression to be evaluated. This can be anything; if no throw occurs, the result of the evaluation of the special form if that of the second argument. If throw(A,B,C) occurs, then it will be catched. If A matches the first argurment, then the third argument is evaluated as in let([tag=A, throwed=B, function=C], action). Otherwise, the triple (A,B,C) is throwed again (if it is not catched, an error is signaled).
(1) f(x):=throw(25,x,myfct); (1) <FUNCTION: f> (2) catch(25, f(10), [throwed,tag,function]); (2) [10, 25, myfct] (3) catch(26, f(10), [throwed,tag,function]); myfct : unable to throw (value is 10) : 25 (4) f(10); myfct : unable to throw (value is 10) : 25 (5) catch(all, catch(26, f(10), [1,throwed]), [2,throwed]); (5) [2, 10] (6) catch(all, catch(25, f(10), [1,throwed]), [2,throwed]); (6) [1, 10] (7) catch(all, catch(25, g(10), [1,throwed]), [2,throwed]); (8) g(10) (9) `catcherror(all, catch(26, f(10), [1,throwed])); (9) [[myfct, errnothrow, 25], TRUE]
The symbolic macro is defined as follows; see errcatch for an example.
catcherror (a,[b])::= buildq( errcatch (a,[{;splice(b)},false],[error_occured,true]));
The catcherror special form takes at least two arguments. It starts with evaluating the first argument. The result can be true or false (false means (), true means anything else). After that, remaining arguments are evaluated, and the result of the last evaluation is returned. However, in the case where an error occurs, the errro is catched, and the result is nil. If the value of the first argument is false, the error message is not printed. A special case is used for the symbolic evaluator. If the first argument is all, and an error occurs, then nothing is printed, but the return value is a list of three items: the function, the error message, the argument.
[Endymion] (ncons (catcherror true (exit foo 1))) exit : undefined escape : foo (()) [Endymion] (ncons (catcherror () (exit foo 1))) (()) [Endymion] (ncons (catcherror () '(exit foo 1))) ((exit foo 1)) [Endymion] (ncons (catcherror true '(exit foo 1))) ((exit foo 1)) [Endymion] (ncons (catcherror all (exit foo 1))) ((exit #:endymion:errudt foo))
This fonction converts its argument into a string like catenate below. However, if any argument of catenate is a wide string, the concatenation is a wide string. The result of catenate1 is always a normal string (conversion may fail).
The function converts each argument into a string, like string, and merges all these partial results in order to get a single string. Note: the Lisp function refuses rational numbers and big integers, but accepts vectors and lists of ASCII codes.
[Endymion] (catenate 120 'foo "foo") 120foofoo [Endymion] (concat 120 'foo "foo") 120foofoo [Endymion] (catenate '(100 101 102) #:string:#[100 101 102]) defdef [Endymion] (concat '(100 101 102) #:string:#[100 101 102]) defdef [Endymion] (concat 2/3) concat : non string argument : 2/3 [Endymion] (catenate 12345678901234567890) catenate : non string argument : 12345678901234567890 [Endymion] (catenate1 "foo") foo [Endymion] (catenate #"" "José") José [Endymion] (catenate1 (catenate #"" "José")) José [Endymion] (catenate #"" "José" '(200 300)) JoséÃĬ [Endymion] (catenate1(catenate #"" "José" '(200 300))) catenate1 : argument out of bounds : 300 [Endymion]
The symbolic function refuses vectors and lists of ASCII codes, but accepts symbolic functions and arrays. See examples below.
(1) catenate(120,foo,"foo",2/3,X,12345678901234567890); (1) 120foofoo2/3X12345678901234567890 (2) concat(120,foo,"foo",2/3,X,12345678901234567890); (2) 120foofoo2/3X12345678901234567890 (3) g(x):=x+1?; (4) catenate(g,cons,nlambda("Foo",x,x+1)); (4) gconsFoo (5) concat(g,cons,nlambda("Foo",x,x+1)); (5) gconsFoo (6) concat([1,2,3]); concat : non string argument : [1, 2, 3] (9) catenate(x^2); 2 catenate : non string argument : x
There is no difference between (cdaaar x) and (cdr (car (car (car x)))). See car above.
There is no difference between (cdaadr x) and (cdr (car (car (cdr x)))). See car above.
There is no difference between (cdaar x) and (cdr (car (car x))). See car above.
There is no difference between (cdadar x) and (cdr (car (cdr (car x)))). See car above.
There is no difference between (cdaddr x) and (cdr (car (cdr (cdr x)))). See car above.
There is no difference between (cdadr x) and (cdr (car (cdr x))). See car above.
There is no difference between (cdar x) and (cdr (car x)). See car above.
There is no difference between (cddaar x) and (cdr (cdr (car (car x)))). See car above.
There is no difference between (cddadr x) and (cdr (cdr (car (cdr x)))). See car above.
There is no difference between (cddar x) and (cdr (cdr (car x))). See car above.
There is no difference between (cdddar x) and (cdr (cdr (cdr (car x)))). See car above.
There is no difference between (cddddr x) and (cdr (cdr (cdr (cdr x)))). See car above.
There is no difference between (cdddr x) and (cdr (cdr (cdr x))). See car above.
There is no difference between (cddr x) and (cdr (cdr x)). See car above.
See car above.
Returns the integer n such that n is between n-1 (excluded) and n (included); See floor.
This takes as arguments a list of integers, and evalutes it as a continuous fraction. The example below shows how this is done. The first element of the list can be a minus sign (symbol or string); in this case the opposite of the niumber is returned.
[Endymion] (cf-to-rational '(12 13 14 15)) 33307/2758 [Endymion] (+ 12 (1/ (+ 13 (1/ (+ 14 (1/ 15)))))) 33307/2758 [Endymion] (cf-to-rational '(- 12 13 14 15)) -33307/2758
The command (channel n) returns information about channel n. This is nil if the channel is closed; it is #[X Y] if the channel is associated to file X in mode Y (this is 1 for input, 3 for output, one more for binary input or output).
The chrpos function takes two or three arguments; the default value of the last argument is zero. It returns the position of cn in the string str (starting at pos). It returns nil if not found. The function could be defined as follows.
(defun chrpos (c str . p) (if p (setq p (car p)) (setq p 0)) (setq str (nthcdr p (string-to-list str))) (chr-aux c str p)) (defun chr-aux (c str p) (cond ((null str) ()) ((eq (car str) c) p) (chr-aux c (cdr str) (+ p 1))))
Example
[Endymion] (chrpos #/Y "OTYoty") 2 [Endymion] (chrpos #/N "OTYoty") () [Endymion] (chrpos #/D "0123456789ABCDEF") 13 [Endymion] (chrpos #/a 'abc 1) () [Endymion] (chrpos 100 '(80 81 82 85 87 89 100))) 6 [Endymion] (chrpos 1000 (catenate #"" '(200 400 600 800 1000 1200))) 4
You cannot use copy on objects that are circular, because you will never find the end of the list. You can use circopy instead. As the example below shows, circopy copies shared objects only once. The function can be defined in Lisp as follows
(defun circopy (x) (setq seen ()) (copy-aux x)) (defun copy-aux (x) (cond ((eq (type-of x) 'polynom) (copy x)) ((eq (type-of x) 'matrix) (copy x)) ((consp x) 'cons) (copy-cons x)) ((stringp x) (catenate x)) ((vectorp x) (copy-vector x)) (true x)) (defun copy-cons (x) (let ((y (assq x seen))) (if y (cdr y) (let ((res (cons () ()))) (setq seen (cons (cons x res) seen)) (rplaca res (copy-aux (car x))) (rplacd res (copy-aux (cdr x))) res)))) (defun copy-vector (x) (let ((y (assq x seen))) (if y (cdr y) (let ((n (vlength x)) res) (setq res (makevector n ())) (setq seen (cons (cons x res) seen)) (typevector res (typevector x)) (for (i 0 1 (- n 1)) (vset res i (copy-aux (vref x i)))) res))))
Example
[Endymion] (setq x '(1 2 3 #[4 5 6 7])) (1 2 3 #[4 5 6]) [Endymion] (progn (setq y (cadddr x)) [Endymion] (vset y 0 y) [Endymion] (vset y 1 x) [Endymion] (rplaca x x) [Endymion] (setq z (circopy x)) [Endymion] (cirprint z) [Endymion] (cirequal z x)) 12=(#1# 2 3 #2=#[#2# #1# 6 7]) true [Endymion] (setq v #[(1 2 3) 0 0]) #[(1 2 3) 0 0] [Endymion] (vset v 1 '(1 2 3)) (1 2 3) [Endymion] (vset v 2 (vref v 1)) (1 2 3) [Endymion] (setq x (list 1 2 3 v)) (1 2 3 #[(1 2 3) (1 2 3) (1 2 3)]) [Endymion] (setq y (list x x)) ((1 2 3 #[(1 2 3) (1 2 3) (1 2 3)]) (1 2 3 #[(1 2 3) (1 2 3) (1 2 3)])) [Endymion] (cirprint y) (#3=(1 2 3 #[(1 2 3) #1=(1 2 3) #1#]) #3#) ((1 2 3 #[(1 2 3) (1 2 3) (1 2 3)]) (1 2 3 #[(1 2 3) (1 2 3) (1 2 3)])) [Endymion] (cirprint (setq z (circopy y))) (#3=(1 2 3 #[(1 2 3) #1=(1 2 3) #1#]) #3#) ((1 2 3 #[(1 2 3) (1 2 3) (1 2 3)]) (1 2 3 #[(1 2 3) (1 2 3) (1 2 3)])) [Endymion] (cirequal z y) true [Endymion] (cirequal #1=#[1 1 2] #1#) true [Endymion] (cirequal '("foo" bar) '(foo "bar")) () [Endymion] (cirequal '#1=(1 1 . #1#) '#2=(1 . #2#)) ()
If you compare circular objects like #1=(1 1 . #1#) and #2=(1 . #2#), you are in trouble, because this may overflow the stack. This is because (while (and (consp x) (eq (car x) 1)) (setq x (cdr x))) never ends, where x is any of the two objects . You can use cirequal. The result will be false: both objects satisfy (eq x (cddr x)), but only one of them satisfies (eq x (cdr x)). See examples under circopy. The function can be defined as follows.
(defun cirequal (x y) (setq seen1 () seen2 ()) (cir-eq x y)) (defun cir-eq (x y) (when (eq (type-of x) (type-of y)) (if (or (consp x) (vectorp x)) (cir-eq1 x y seen1 seen2) (equal x y)))) (defun cir-eq1 (x y x1 y1) (if (null x1) (cir-eq2 x y) (if (eq x (car x1)) (eq y (car y1)) (if (eq y (car y1)) () (cir-eq1 x y (cdr x1) (cdr y1)))))) (defun cir-eq2 (x y) (setq seen1 (cons x seen1)) (setq seen2 (cons y seen2)) (if (consp x) (and (cir-eq (car x) (car y)) (cir-eq (cdr x) (cdr y))) (if (neq (typevector x) (typevector y)) () (if (neq (vlength x) (vlength y)) () (let ((n (vlength x)) (res true) (ok ()) (i 0)) (while (and (< i 0) (not ok)) (if (not (cir-eq (vref x i) (vref y i))) (setq ok true res ())) (setq i (+ i 1))) res)))))
If you print self-referencing object like #2=(#2#), you will be disappointed, because you will not see anything useful. The functions cirprint, cirprinflush and cirprint-to-string print it argument in the format shown above. For an example see circopy. The last function prints the argument in a string, and returns the string; the other two function print the object on the current channel and return it. The function cirprint prints an additional newline.
The function close closes the channel given as argument. An error is signaled if the argument is not an integer (you cannot close the terminal) or if the channel is not opened. You can call the function without arguments: this closes all channels (except the terminal).
[Endymion] (openo "foo") 19 [Endymion] (channel 19) #[foo 3] [Endymion] (channel) #[() () () () () () () () () () () () () () () () () () () #[foo 3]] [Endymion] (close "18") close : not a fixnum : 18 [Endymion] (close 18) close : channel not open : 18 [Endymion] (close 19) () [Endymion] (channel 19) () [Endymion] (close) ()
The (#:display:close f) command closes a file opened by #:display:open; see this function for examples.
The color_tty variable function controls whether or not colors should be used for printing.
[Endymion] (let ((color_tty true)) (eval(read))) [Endymion] (car 0) car : not a list : 0 [Endymion] (let ((color_tty false)) (eval(read))) [Endymion] (car 0) car : not a list : 0 [Endymion] color_tty true
The comline function takes as argument a string. It passes it to the underlying shell. The return value is true. If the argument is not a string, it will be replaced by some random string. If it is empty, it will be replaced by $SHELL; if is cd (followed by an arbibrary number of spaces), then the current directory of Endymion is changed to the home dir (the value of the shell variable HOME). If it is cd foo, then the current directory of Endymion is changed to `foo'.
[Endymion] (comline "pwd") /user/grimm/home/cvs/endymion/src [Endymion] (comline "cd abc") sh: line 1: cd: abc: No such file or directory true
This function signals an error if x and y are not real numbers. It returns the complex number with real part x and imaginary part y.
This function returns its argument if it is a complex number and false otherwise. All numbers known to Endymion are complex.
The compare function compares two objects. It returns -1 if smaller, 1 if greater and 0 if equal. The algorithm looks like this. If both arguments are lists, we compare first the CAR of the lists. If they are the same, we compare the CDR. A non-list is always smaller than a list. After that, hash codes are compared. Note that integers have hash code at most 512, symbols have hash code greater than that; in particular, an integer is smaller than the empty list.
[Endymion] (compare '(1) '(2)) -1 [Endymion] (compare '(1 2 3) '(2 4 5)) -1 [Endymion] (compare '(1 2 . 4) '(1 2 . 3)) 1 [Endymion] (compare '(1 2 . 4) '(1 2 . ())) -1 [Endymion] (compare "foo" "gee") 1 [Endymion] (compare "gee" "bar") 1 [Endymion] (compare "foo" "bar") 1 [Endymion] (defun test (x y) (unless (eq (compare x y) -1) (print "failed"))) test [Endymion] (defun test1 (x y) [Endymion] (while (consp y) (test x (car y)) (setq y (cdr y)))) test1 [Endymion] (defun test2 (x) [Endymion] (while (consp (cdr x)) (test1 (car x) (cdr x)) (setq x (cdr x)))) test2 [Endymion] (setq x '(1 2 3 a b c "a" "b" "c" #[1] #[2] (1) (2))) (1 2 3 a b c a b c #[1] #[2] (1) (2)) [Endymion] (setq y (sort1 x)) (1 2 3 a a b b c c #[1] #[2] (1) (2)) [Endymion] (test2 y) () [Endymion] (setq x (sort1 '(x1 g28679 "x1" "g28679" #"x1" #"g28679"))) (g28679 x1 g28679 x1 g28679 x1) [Endymion] (mapcar 'gethash x) (1074 1074 1074 1074 1074 1074) [Endymion] (list (type-of (nth 0 x)) (type-of (nth 2 x)) (type-of (nth 4 x))) (symbol string wstring)
This compares two numbers modulo epsilon. Let d(x,y) be the relative distance between x, y, namely abs(x-y) divided by max(abs(x),abs(y)).
[Endymion] (compare-eps 1 1 2) () [Endymion] (compare-eps 1 1 -0.5) () [Endymion] (compare-eps 0 1/100 0.1) () [Endymion] (compare-eps 0 .01 0.1) true [Endymion] (compare-eps #C(0 3) #C(0.01 3) .1) true [Endymion] (compare-eps 1.2345e0 1.2346e0 0.0001) true [Endymion] (compare-eps 1.2345e0 1.2346e0 0.00001) () [Endymion] (compare-eps 1.2345e10 1.2346e10 0.0001) true [Endymion] (compare-eps 1.2345e10 1.2346e10 0.00001) () [Endymion] (compare-eps 1.2345L10 1.2346L10 0.0001) true [Endymion] (compare-eps 1.2345L10 1.2346L10 0.00001) () [Endymion] (compare-eps 1.2345L10 1.2346b10 0.0001) true [Endymion] (compare-eps 1.2345L10 1.2346b10 0.00001) () [Endymion] (compare-eps 'x 'y 1.0) ()
The concat function uses catenate to construct a character string; this is then transformed to a symbol in the empty package. Note that the empty string is converted to (). The symbolic function behaves the same, the result is a FSYMBOL. For instance, in symbolic mode, concat(car) converts the Lisp symbol #:feval:car to the character string "car", then to the fsymbol named 'car'; and concat(car)(0) applies this to 0. This is something that prints as car(0), but if you simplify the expression, then the symbol is replaced by the function ans an
(1) concat(car); (1) car (2) concat(car)(0); (2) car(0) (3) concat(car)([1,2,3]); (3) car([1, 2, 3]) (4) #$simplify(%); (4) 1 (5) concat(car,%); (5) car1
The cond macro takes at least one argument. Each argument is a list, formed of a test and a body. Tests are evaluated in order. If one test is found true, the associated body is evaluated. This is then the result of the cond. If no test is true, the result is false. (cond (y1 y2 ... ym) x2 .. xn) is the same as (if y1 (progn y2 ... ym) (cond x2 ... xn)). In the special case where m is one, the return value is y1, the expansion of the cond is: (or y1(cond x2 ... xn)). Another special case is when m is one, and the first term has the form (prog1 () z1 ... zp). In this case, the test is always false; the expansion is (progn z1 ... zp(cond x2 ... xn))
[Endymion] (setq x '(cond (a 1 2) ((prog1 () b )) (d) (e f) (true g) (h i))) (cond (a 1 2) ((prog1 () b)) (d) (e f) (true g) (h i)) [Endymion] (eval x) eval : undefined variable : a [Endymion] x (if a (progn 1 2) (progn b (or d (if e f g)))) [Endymion] (defun f (x) (cond ((= x 1) 2) ((= x 2) 4) ((= x 3) 8) [Endymion] ((eq (type-of x) 'fix) "too big") (true "not an integer"))) f [Endymion] (list (f 1) (f 2) (f 3) (f 4) (f 'ok)) (2 4 8 too big not an integer)
This function returns its argument if it is not a complex number, and the conjugate otherwise. The function handles the case of a polynomial, a matrix and the like.
[Endymion] (conjugate 'x) x [Endymion] (conjugate 3/4) 3/4 [Endymion] (conjugate #C(2 3/4)) [-3/4i+2] [Endymion] (conjugate #PC_d 2 1 2 3 4 5 6) #PC_s (1-2*I) + (3-4*I)*z + (5-6*I)*z^2; [Endymion] (conjugate #PFC 0 2 1 2 3 4 5 6) #PFC_s (1-2*I) + (3-4*I)*z + (5-6*I)*z^2; [Endymion] (conjugate #MPC 2 2 1 2 #PC_d 1 0 0 2 3 4) #MPC 2 2 #PC_s 1; #PC_s 2; #PC_s (2-3*I)*z; #PC_s 4;
The cons function takes two arguments; it returns a cons whose car is the first argument, and whose cdr is the second argument. The symbolic function needs a symbolic list as second argument, it returns a symbolic result. Example
[Endymion] (setq x (cons 1 2)) (1 . 2) [Endymion] (eq x (cons 1 2)) () [Endymion] (equal x (cons 1 2)) true [Endymion] (cons 1 (cons 2 (cons 3 (cons 4 ())))) (1 2 3 4) [Endymion] (type-of (cons 1 2)) cons
The consp function returns its argument if it is a list, it returns nil otherwise. There is no difference between (consp x) and (eq (type-of x) 'cons)
[Endymion] (consp '(foo)) (foo) [Endymion] (consp "(foo)") () [Endymion] (consp 123) ()
The constantp function takes one argument. It returns true if its argument is a constant and nil otherwise. It returns true unless either the argument is a list, or is a symbol, but it returns true if the argument is true or nil.
[Endymion] (constantp 12) true [Endymion] (constantp ()) true [Endymion] (constantp true) true [Endymion] (constantp "foo") true [Endymion] (constantp '(foo)) () [Endymion] (constantp 'foo) ()
The copylist function copies recursively its argument if it is a list. The copy function copies also vectors.
(defun copylist (x) (if (consp x) (cons (copylist (car x)) (copylist (cdr x))) x)) (defun copy (x) (cond ((eq (type-of x) 'polynom) (copy-polynom x)) ((eq (type-of x) 'matrix) (copy-polynom x)) ((consp x) (copylist x)) ((vectorp x) (let ((n (vlength x)) res) (setq res (makevector n ())) (typevector res (typevector x)) (for (i 0 1 (- n 1)) (vset res i (copy-aux (vref x i)))) res)) ((stringp x) (catenate x)) (true x)))
[Endymion] (setq L '(1 (2) #[1 2 #[3] ] #[1 (3) (#[ "foo"] )])) (1 (2) #[1 2 #[3]] #[1 (3) (#[foo])]) [Endymion] (setq L1 (copylist L)) (1 (2) #[1 2 #[3]] #[1 (3) (#[foo])]) [Endymion] (setq L2 (copy L)) (1 (2) #[1 2 #[3]] #[1 (3) (#[foo])]) [Endymion] (equal L L1) true [Endymion] (eq L L1) () [Endymion] (eq L L2) () [Endymion] (eq L1 L2) () [Endymion] (eq (cadr L) (cadr L1)) () [Endymion] (eq (cadr L) (cadr L2)) () [Endymion] (eq (cadr L1) (cadr L2)) () [Endymion] (eq (caddr L) (caddr L1)) true [Endymion] (eq (caddr L) (caddr L2)) () [Endymion] (eq (caddr L1) (caddr L2)) () [Endymion] (setq l (cadddr L) l1 (cadddr L1) l2 (cadddr L2)) #[1 (3) (#[foo])] [Endymion] (eq l l1) true [Endymion] (eq l l2) () [Endymion] (eq (vref l 1) (vref l2 1)) () [Endymion] (equal (vref l 1) (vref l2 1)) true [Endymion] (eq (car (vref l 1)) (car (vref l2 1))) true [Endymion] (equal (vref l 2) (vref l2 2)) true [Endymion] (eq (vref l 2) (vref l2 2)) () [Endymion] (eq (car (vref l 2)) (car (vref l2 2))) () [Endymion] (equal (car (vref l 2)) (car (vref l2 2))) true
Like copy above, but copies only lists.
The csend function behaves like (send f a1 ... an). The only difference is when send does not find a method. In this case, instead of calling a generic function, it calls d, the first argument.
[Endymion] (defun #:cons:first (x) (car x)) #:cons:first [Endymion] (defun #:symbol:first (x) (packagecell x)) #:symbol:first [Endymion] (defun #:vector:first (x) (vref x 0)) #:vector:first [Endymion] (defun #:foo:first (x) (vref x 1)) #:foo:first [Endymion] (csend 'unused 'first '(1 2 3)) 1 [Endymion] (csend 'unused 'first '#:a:b:c) #:a:b [Endymion] (csend 'unused 'first '#[A B C]) A [Endymion] (csend 'unused 'first '#:foo:bar:#[A B C]) B [Endymion] (csend (lambda x (print "What can I do with " x " ?")) 'first [Endymion] 1 2 3 4) What can I do with (first 1 2 3 4) ? ?
This function returns the current line number of the current output channel (this is zero in the case of a terminal, is the number of end-of-line characters read from the current file otherwise).
The current-directory variable function holds the current directory of Endymion. If you change the value of this variable to foo, then the C library function chdir is called. If this returns false, an error is signalled. Note that executing (comline "cd foo") will change the current directory, but comline is unaware of the current-directory variable. In Unix .. is the directory above the current one; thus is a valid value of current-directory, it should be used with care
[Endymion] current-directory /user/grimm/home/cvs/endymion/src [Endymion] (setq current-directory "..") .. [Endymion] !pwd /0/ns/grimm/cvs/endymion true [Endymion] (setq current-directory "..") .. [Endymion] !pwd /0/ns/grimm/cvs true [Endymion] (setq current-directory (expand-path "$HOME")) /user/grimm/home [Endymion] (setq current-directory "$HOME") current-directory : non string argument : $HOME
back to home page © INRIA 2005, 2006 Last modified $Date: 2009/01/08 17:43:30 $