All commands, alphabetic order; letter L

This page contains the description of the following commands lambda, land, last, lastn, last_object_evaluated, last_object_read, lcm, length, lenstra, lenstra_b, lenstra_c, let, lisp_catch, lisp-io-chan lisp_throw, list, list2, list4, listify, lmargin, lnot, load, loaded-from-file, log10, log, logexpand, logsimp, long-div, loopforever, lor, lsh, lxor,


(lambda argl . body) (Lisp macro/ special form)

lambda (argl, b1, ... bn) (Symbolic macro)

In the symbolic case, the expansion of lambda (a,b,c) is nlambda("u",a,b,c). See nlambda for details. The result is an anonymous function (in fact, it is named "u"), with argument list a and body b,c. We shall describe below the Lisp macro, and associated special form.

There are three symbols in Endymion with name lambda. The one in the empty package is a macro. The expansion of this macro is of the form (#:system:lambda n argl . body). At least one argument is required, this should be a valid argument list specification. The argument list is checked, and the number of arguments is added.

[Endymion] (lambda (1))
eval : not a variable : 1
[Endymion] (lambda (a b a))
eval : illegal binding : a
[Endymion] (lambda)
lambda : wrong number of arguments : 0 this should be at least 1
[Endymion] (setq x '(lambda (x) x))
(lambda (x) x)
[Endymion] (eval x)
(#:system:lambda 1 (x) x)
[Endymion] (eval (eval x))
(#:system:lambda 1 (x) x)
[Endymion] (eq (car x) '#:system:lambda)
()

The test in the previous example shows that the expansion of lambda contains an uninterned symbol. The next example shows that the interned symbol #:system:lambda behaves like lambda, but ignores the number of arguments.

[Endymion] (setq y '(#:system:lambda 2 (x) x))
(#:system:lambda 2 (x) x)
[Endymion] (eq (car y) '#:system:lambda)
true
[Endymion] (eval y)
(#:system:lambda 1 (x) x)
[Endymion] (eq (car y) '#:system:lambda)
()

Finally, the uninterned #:system:lambda is a special form that evaluated to itself. This object is a function, that can be called via funcall, apply or directly.

[Endymion] y
(#:system:lambda 1 (x) x)
[Endymion] (setq z (eval y))
(#:system:lambda 1 (x) x)
[Endymion] (and (eq (car z) (car y)) (eq (cdr z) (cdr y)))
true
[Endymion] (funcall z 1 2 3)
(#:system:lambda 1 (x) x) : wrong number of arguments : 3 this should be 1
[Endymion] (funcall z 1)
1
[Endymion] (funcall (lambda (x y) (list y x)) 1 2)
(2 1)
[Endymion] ((lambda (x y) (list x y)) 1 2)
(1 2)

(land x y) (Lisp function)

(lor x y) (Lisp function)

(lxor x y) (Lisp function)

(lnot x) (Lisp function)

These functions take as arguments bit sequences. An integer like 5 is the bit sequence ...00101, with an infinite number of zeros on the left. Negative numbers are expressed in 2's complement. This means that -5 corresponds to ...11011. The lnot operations toggles all bits. By definition of 2's complement -5 is (1+ (lnot 5)). In fact, (lnot n) is -n-1. It is however defined as (lxor -1 n). According to the conventions above, -1 is the sequence ...11 containing only ones. The three functions land, lor and lxor perform bit operations, respectively AND, OR and XOR. Remember that AND(a,b) is 1 if both bits are 1, and 0 otherwise, OR(a,b) is 1 is one bit is 1 and 0 otherwise, and XOR(a,b) is 1 if the bits are different, and 0 otherwise. In particalur, (land x y) is negative if both arguments are, (lor x y) is negative if one arguments iq, (lxor x y) is negative if one argument is positive, then other is negative. Note that if a and b are distint bits then AND(a,b) is 0, XOR(a,b) is 1, OR(a,b)=1 hence AND(a,b) + XOR(a,b) = OR(a,b). If bothe bits are the same, the previous relation holds, because XOR is zero, AND(a,b), and OR(a,b) are a. As a consequence land(x,y) + lxor(a,b)=lor(a,b)

[Endymion] (lnot 17)
-18
[Endymion] (lnot 0)
-1
[Endymion] (lnot -17)
16
[Endymion] (land 12604 4)
4
[Endymion] (lor 12604 4)
12604
[Endymion] (lxor 12604 4)
12600
[Endymion] (land 12604 -4)
12604
[Endymion] (lor 12604 -4)
-4
[Endymion] (lxor 12604 -4)
-12608

(last L) (Lisp function)

The last function takes one argument. If this is not a list, it is returned. Otherwise, the last cons of the list is returned. The function could be defined in Lisp as

(defun last (L)
  (if (or (atom x) (atom (cdr x))) 
      x
      (last (cdr x))))

Examples

[Endymion] (last 12)
12
[Endymion] (last '(1 . 2))
(1 . 2)
[Endymion] (setq x '(a b c . d))
(a b c . d)
[Endymion] (last x)
(c . d)
[Endymion] (eq (last x) (cddr x))
true

(lastn n L) (Lisp function)

The lastn function takes two arguments, an integer and a list. It returns the last n elements of the list. In the case where n is not an integer, an error is signalled. In the case where n is negative, the empty list is returned; if n is too large, a copy of the whole list is returned, otherwise a copy of a sublist is returned.

(defun lastn (n l)
  (if (neq (type-of n) 'fix) (error 'lastn errnia n))
  (setq n (- (length l) n))
  (while (> n 0) (setq  n (- n 1) l (cdr l)))
  (append l ()))

Examples

[Endymion] (setq l '(a b c d e))
(a b c d e)
[Endymion] (lastn 3 l)
(c d e)
[Endymion] (lastn 5 l)
(a b c d e)
[Endymion] (lastn 1 l)
(e)
[Endymion] (lastn -1 l)
()
[Endymion] (lastn 19 l)
(a b c d e)
[Endymion] (eq l (lastn 19 l))
()

last_object_evaluated (Lisp variable)

last_object_read (Lisp variable)

These two variables are set by the load funtion to the last expression read from a file, and the value after evaluation.

(length L) (Lisp/symbolic function)

The length function takes on argument. Ir returns the length of it (number of items in the list). If the argument is not a list, the return value is zero. The function can be defined as

(defun length (x)
  (let ((n 0))
       (while (consp x) (setq n (+ n 1) x (cdr x)))
       n))
(defun length (x)
  (if (atom x) 
      0
      (+ 1 (length (cdr x)))))

Examples

[Endymion] (length 1)
0
[Endymion] (length '(a b c d e))
5
[Endymion] (length '(a b c d . e))
4
[Endymion] (length ())
0
[Endymion] (length (#:feval:|[| 1 2 3 4))
0
[Endymion] (#:feval:length (#:feval:|[| 1 2 3 4))
4
[Endymion] (#:feval:length '(a b c d e))
0

(lenstra n) (Lisp function)

(lenstra_b n) (Lisp function)

(lenstra_c n) (Lisp function)

The lentra function takes as argument an integer, and returns a factor, or zero if this is not possible. The function uses the Elliptic Curves Method. For each curve, some point is chosen, and raised to the power m, where m is a power of a prime p, a little smaller than B. The lenstra_b function allows you to change the value of B (between 1000 and 1.e9, default 1.e6). The lenstra_c function can be used to change the number of curves (between 5 and 100000, default 30). The following table indicated the value of the largest prime number tested, and the runtime, for the number (+ 1 (fact 20)), namely 2432902008176640001 (it has two prime factors).

318726711977397393738234312393211
1.781.570.170.590.600.310.660.351.440.18

Same, with 7 curves

26714791973733894312111373467613
2.210.560.250.430.450.50.251.320.550.7

Same, with 10 curves

26711973734312114676135317233
3.120.340.620.710.350.790.980.130.050.39

Same, with 15 curves

197373431211531723319753157
0.520.941.060.530.180.080.580.50.190.43

Same, with 20 curves

197373211531719753109229179
0.681.240.710.250.100.670.250.450.740.62

Same, with 30 curves

197211171975310983 17269269
0.910.960.130.910.330.61 0.490.141.191.2

Same, with 40 curves

19753175317917269 175337
1.210.450.180.451.10.18 1.560.180.450.31

Same, with 60 curves

1971753172691737 12711127
1.820.260.670.282.380.27 0.481.290.191.29

Same, with 80 curves

53171717373711 1091123
0.90.360.340.360.640.64 0.261.620.250.47

Same, with 120 curves

17171737111123 115311
0.540.530.530.960.390.37 0.710.391.320.39

Same, with 150 curves

17171711111111 111717
0.680.690.680.490.490.5 0.490.490.680.68

Same, with 250 curves

1711111111177 372311
1.140.820.820.820.821.14 0.622.051.480.82

Same, with 350curves

1711111172317 111717
1.591.161.161.160.882.09 1.611.141.611.61

Same, with 500 curves

1111117111717 131111
1.641.651.631.251.632.28 2.281.971.641.64

-------- B =10^8 Same, with 30 curves

197211171975310983 17269269
1.151.220.161.170.4 0.780.610.171.781.76

Same, with 60 curves

1971753172691737 12711127
2.710.370.950.374.09 0.370.701.920.26 1.92

Same, with 80 curves

53171717373711 1091123
1.250.50.50.490.920.93 0.352.430.350.64

Same, with 120 curves

17171737111123 115311
0.740.750.751.390.520.53 0.960.521.90.52

Same, with 150 curves

17171711111111 111717
0.930.930.940.650.66 0.660.660.650.94 0.93

Same, with 250 curves

1711111111177 372311
1.541.111.11.111.11.56 0.822.912.031.1

Same, with 350 curves

1711111172317 111717
2.171.551.531.541.152.84 2.181.542.22.21

Same, with 500 curves

1111117111717 131111
2.172.212.211.662.23.12 3.182.652.192.19

(lisp-io-chan arg) (Lisp function)

If the argument is a file opened for printing, this function returns the Lisp channel associated to it, returns false otherwise. As the example below shows, you can open a file with #:display:open if it is opened with openo. This function knows only of #:display:open. What happens in such a situation is undefined. One possibility could be that, if you print nothing on channel 19, and close it, this gives an empty file for `foo', no matter what is printed on channel 18.

[Endymion] (lisp-io-chan 'foo) 
()
[Endymion] (openo 'foo) 
19
[Endymion] (lisp-io-chan 'foo) 
()
[Endymion] (#:display:open 'foo true) 
true
[Endymion] (lisp-io-chan 'foo) 
18
[Endymion] (channel) 
#[() () () () () () () () () () () () () () () () () () #[foo 3] #[foo 3]]

(let args . body) (Lisp macro)

The let macro takes at least one argument; it evaluates to an expression involving lambda. The first argument args is a list of pairs, variable and value. If u is the list of variables, and v the list of values, the expansion of the let is ((lambda u . body) v). See lambda for details about this command.

When you say (let ((u1 v1) (u2 v2)) a b c d), quantities a b c d are evaluated in order, the result is the evaluation of the last term, namely d. However, u1 is locally bound to the evaluation of v1 and u2 is locally bound to the evaluation of v2. The quantity u1 can be more complex than a variable, it could be a tree. In the case where the value is nil, you can replace the pair variable-value by the variable.

[Endymion] (setq x 1) 
1
[Endymion] (list x (let ((x 2)) x) x)
(1 2 1)
[Endymion] (let (((a b c) '(1 2 3)) d)  (list a b c d))
(1 2 3 ())
[Endymion] (let ((x 1) (y 2)) (let (((x y) (list y x))) (list x y)))
(2 1)
[Endymion] (setq X '(let ((a 1) u) (list a u)))
(let ((a 1) u) (list a u))
[Endymion] (eval X)
(1 ())
[Endymion] X
((#:system:lambda 2 (a u) (list a u)) 1 ())
[Endymion] (let)
let : wrong number of arguments : 0 this should be at least 1
[Endymion] (let ((x 1)(x 2)) 3)
eval : illegal binding : x
[Endymion] (let (((x) 1)) 3)
eval : illegal binding : 1

lisp_catch(tag, expr, action) (Special form)

In the case of lisp_catch(a, b, c), expression b is evaluated as usual. In the case where a throw to a occurs, it will be catched, and c will be evaluated in a context where throwed is the throwed value. In the case where c has the special value done, the code is optimised, and the value throwed is simply returned. The value of a must be a valid tag, a Lisp symbol, after evaluation. As examples below show, you can use a string or the construct #'foo, for an unevaluated tag. As examples (1) and (2) show, tags are evaluated by evtag or evexit, and example (9) shows that tag or exit are used in the case where the value is not evaluated (in example (9), the list L is replaced by its value by the compiler). For example (5), we show the Lisp code that is executed.

(1) lisp_catch(12,13,14);
evtag : not a symbol : 12
(2) lisp_throw(12,13,14);
evexit : not a symbol : 12
(3) L:=[a,b,c,d]; x:=a+b;

(3)                              [a, b, c, d]

(4)                                 a + b

(5) lisp_catch(x-a, lisp_throw(L[1], foo), [throwed]);

(let ((#:gensym:g9 ()) (#:gensym:g10 ()))
     (setq #:gensym:g9 
            (evtag (:- '#:fexpression:#[+ (a b)] 'a)
                   (prog1 (evexit (:array '[a b c d] 1) 'foo) 
                          (setq #:gensym:g10 true)
     )      )      )
     (if #:gensym:g10 #:gensym:g9 (let ((throwed #:gensym:g9)) (:[ throwed)))
)

(5)                                 [foo]

(6) lisp_catch("A", lisp_throw("A", foo), done);

(6)                                  foo

(7) f(x):=lisp_throw("L", x);

(7)                             <FUNCTION: f>

(8) lisp_catch(#'L, f(10), done);

(8)                                   10

(9) lisp_catch(L, f(10), done);
tag : not a symbol : [a b c d]
(10) lisp_catch("foo", 11, x);

(10)                                  11

lisp_throw(tag, e1, ..., en) (Special form)

This special form behaves lisk the lisp form evexit. The first argument must be a Lisp symbol after evaluation. If you do not want to have it evaluated, you can use a string or a construct like #'foo. It is an error if you do not catch the tag. See lisp_catch above for examples.

(list x1 ... xn) (Lisp function)

The list function takes N arguments, and returns them as a list.

[Endymion] (list)
()
[Endymion] (list 1)
(1)
[Endymion] (list 1 2)
(1 2)
[Endymion] (list 1 2 3)
(1 2 3)
[Endymion] (list 1 2 3 4)
(1 2 3 4)
[Endymion] (list 1 2 3 4 5)
(1 2 3 4 5)

(list2 a b) (Lisp function)

The list2 function behaves exactly like list, but it takes two arguments. It can be defined as

(defun list2 (x y)
  (list x y))

Example

[Endymion] (list2 'foo 'bar)
(foo bar)
[Endymion] (type-of (list2 'foo 'bar))
cons

(list4 a b c d) (Lisp function)

The list4 function behaves exactly like list, but it takes four arguments. It can be defined as

(defun list4 (x y z t)
  (list x y z t))

listify (Keyword)

Inside the body of a macro, you can use listify(x), see the compiler.

lmargin (Lisp function)

This variable controls the left margin. You can say (setq lmargin (+ lmargin 1)) or (lmargin (+ (lmargin) 1)), these calls increment the left margin by one.

(load file) (Lisp function)

The load function loads a file. It is equivalent to (let ((inchan (openi file)))(tag eof (while ...)). If the first character of the file is a slash, it is a assumed that this is a symbolic file, starting with a comment like /* this */. or // like that. If the first character is a semi-colon, it is assumed to be a Lisp file. If the file starts with # it is also assumed to be a Lisp file. If the file start with a letter, it is assumed to be a symbolic file. The default is a Lisp file.

In the case of a symbolic file, expressions are read and evaluated symbolically. In the case of a Lisp file, expressions are read via read and evaluated via eval. The reader stores in last_object_read each expression read, and the evaluator puts its result in last_object_evaluated. The return value of load is nil. Note the variable #:sys-package:colon is local to a file (it is restored at the end of load).

#:system:loaded-from-file (Lisp property)

Property set by defvar on a variable when it is loaded from a file.

(log10 x) (Lisp function)

This function returns the ten-base logarithm of x, that is, the quotient of (log x) by (log 10).

(log x) (Lisp/symbolic function)

In the case where the argument is a number both Lisp and symbolic functions behave the same.

(1) log(100);

(1)                            4.60517018598809

(2) log(-100);

(2)                 4.60517018598809 + 3.14159265358979 %i

(3) log(1/100);

(3)                           - 4.60517018598809

(4) log(log(-100));

(4)                1.71823716488268 + 0.598671427740728 %i

(5) log(1.2L0);

(5)                 0.182321556793954626211718025154515L0

(6) log(1.2b0);

(6)               0.18232155679395462621171802515451463320e0

(7) log(0);
log : division by zero : 0

In symbolic mode, the behavior depends on the variable logexpand. If this is set, then the logarithm is a power is expanded; in particular, the logarithm of the exponential of z simplifies to z. If this is all, the logarithm of a product is expanded.

(1) [log(a+b), log(a^b), log(a*b)];

                                         b
(1)                    [log(a + b), log(a ), log(a b)]

(2) logexpand := true?; [log(a+b), log(a^b), log(a*b)];

(3)                    [log(a + b), b log(a), log(a b)]

(4) logexpand := all?; [log(a+b), log(a^b), log(a*b)];

(5)                [log(a + b), b log(a), log(a) + log(b)]

(6) log(exp(x));

(6)                                   x

(7) logexpand := false?; log(exp(x));

                                         x
(8)                                log(%e )

(9) log(a=b);
log : Cannot compute : log(a = b)
(10) log(a^b*a^c);

                                      b + c
(10)                             log(a     )

(11) let([logexpand=true], log(a^b*a^c));

(11)                            (b + c) log(a)

(12) let([logexpand=true,expop=1], log(a^b*a^c));

(12)                         b log(a) + c log(a)

logexpand (Symbolic variable)

This variable can be true, false, or all (everything else is consider true). If non-false, log(a**b) is transformed into b*log(a); if all, log(a*b) is transformed into log(a)+log(b).

(1) [log(a**b), let(logexpand=true, log(a**b)) ];

                                   b
(1)                          [log(a ), b log(a)]
(2) [log(a*a*b), let(logexpand=all, log(a*a*b)) ];

                              2
(2)                     [log(a  b), 2 log(a) + log(b)]

(3) logexpand:=23;

(3)                                  TRUE

logsimp (Symbolic variable)

This variable can be true, false, or all (everything else is consider true). If non-false, exp(a*log(b)) is transformed into b**a; if all, exp(W) is simplified if W is a product containing a single logarithm. If non-false, exp(a+b) is converted into a product of exponentials, each exponential is simplified; as the example line 8 shows, after these simplications exp(a)*exp(b) is converted back to exp(a+b).

(1) [exp(22*log(a)), exp(a*b*log(c)), exp(a*log(b) *log(c)) ];

                   22 log(a)    a b log(c)    a log(b) log(c)
(1)             [%e         , %e          , %e               ]

(2) logsimp:= true;

(2)                                  TRUE

(3) [exp(22*log(a)), exp(a*b*log(c)), exp(a*log(b) *log(c)) ];

                      22    a b log(c)    a log(b) log(c)
(3)                 [a  , %e          , %e               ]

(4) logsimp:= all;

(4)                                  all

(5) [exp(22*log(a)), exp(a*b*log(c)), exp(a*log(b) *log(c)) ];

                          22   a b    a log(b) log(c)
(5)                     [a  , c   , %e               ]

(6) exp(22*log(a) + a*b*log(c) + a*log(b) *log(c)) ;

                           22  a b   a log(b) log(c)
(6)                       a   c    %e

(7) logsimp:=true;

(7)                                  TRUE

(8) exp(22*log(a) + a*b*log(c) + a*log(b) *log(c)) ;

                       22   a b log(c) + a log(b) log(c)
(8)                   a   %e

(9) logsimp:=false;

(9)                                 FALSE

(10) exp(22*log(a) + a*b*log(c) + a*log(b) *log(c)) ;

                    22 log(a) + a b log(c) + a log(b) log(c)
(10)              %e

loopforever(x1,...,xn) (Symbolic macro)

The macro executes its body endlessly. The loop can be broken via an error, or a return from the current function. The definition is trivial.

loopforever([c])::=
      buildq(a=gensym, 
         tagbody(label(a),splice(c),goto(a)));

The example that follows shows the expansion of the macro, but not that of x++ or RETURN(y).

(1) f(x,y):=  { block(out,
(1)                loopforever(x++,print(x), 
(1)                   if(x==10) then car(0),
(1)                   if(x==13) then RETURN(y),
(1)                   if(x==17) then return(out)),
(1)                  unreachable_code()),
(1)              print(y), 
(1)              done };

Macro expansion -> loopforever(incr1(x), print(x), if x == 10 then car(0)
 else false, if x == 13 then RETURN(y) else false, if x == 17
 then return(out) else false)

Macro expansion <- tagbody(label(g10), incr1(x), print(x), if x == 10
 then car(0) else false, IF x == 13 then RETURN(y) else false, 
 if x == 17 then return(out) else false, goto(g10))

(1)                             <FUNCTION: f>

(2) f(4,10);
5
6
7
8
9
10
car : not a list : 0
(3) f(11,10);
12
13

(3)                                   10

(4) f(13,10);
14
15
16
17
10

(4)                                  done

(long-div p q m) (Lisp function)

This function computes the long division of p/q with m terms. Assume that q is of degree n, and is monic (otherwise, p and q and first divided by the leading coefficient of q). We assume p is of smaller degree the q (otherwise, the remainder of p in the division by z^n is used; a better solution would be divide by q). If q is constant, the result is zero.

At stage i, we compute in a_i the coefficient of order n-1 of p, and replace p by z*p-a_i*q. The result is the sum of all a_iz^i. The function call (scal-prod p q f) assumes that f is a polynomial, say sum f_iz^i; the return value is the sum of a_i*f_i. If p, q, and f are quadruple or octuple precision, the expansion is computed with the maximal precision. The scalar product is returned as a double precision number (real or complex). If p is a matrix, the long division produces a matrix of the same size, the scalar product requires that f have the same dimensions as p.

[Endymion] (long-division #PD 0 1 #PD 1 1 -2 10)
#PD_s -0.5-0.25*z-0.125*z^2-0.0625*z^3-0.03125*z^4-0.015625*z^5-0.0078125*z^6
-0.00390625*z^7-0.001953125*z^8-0.0009765625*z^9;
[Endymion] (scal-prod #PD 0 1 #PD 1 1 -2 #PD_s z^9;)
-0.0009765625
[Endymion] (long-division #PD 0 1 #PC 1 0 1 2 0 10)
#PC_s 0.5-0.25*I*z-0.125*z^2 + 0.0625*I*z^3 + 0.03125*z^4-0.015625*I*z^5
-0.0078125*z^6 + 0.00390625*I*z^7 + 0.001953125*z^8-0.0009765625*I*z^9;
[Endymion] (setq m1 #MPC 1 4 #PD 0 1 #PD 0 10 #PD 0 100 #PD 0 1000)
#MPC 1 4 #PC_s 1; #PC_s 10; #PC_s 100; #PC_s 1000;
[Endymion] (setq res ())
()
[Endymion] (for (i 0 1 3) (setq res (cons (scal-prod (mref m1 0 i) 
[Endymion] #PC 1 0 1 2 0 (mref m2 0 i)) res)))
()
[Endymion] (apply '+ res)
[1.9521484375i+0.205078125]
[Endymion] (scal-prod m1 #PC 1 0 1 2 0 m2)
[1.9521484375i+0.205078125]
[Endymion] (scal-prod m1 #PC 1 0 1 2 0 (transpose m2))
scal-prod : Bad dimensions : (#MPC 1 4 #PC_s 1; #PC_s 10; #PC_s 100; #PC_s 
1000; #MPC 4 1 #PC_s 1*z^9; #PC_s 1*I*z^9; #PC_s 1*z^8; #PC_s 1*I*z^8;)

(lsh x n) (Lisp function)

The function (power-of-two n) computes 2 power n ibn an efficient way. The (lsh x n) function multiplies x by 2 power n; if n is negative the integer part of the result is taken.

[Endymion] (lsh 1234567890 -5)
38580246
[Endymion] (lsh -1234567890 -5)
-38580246
[Endymion] (lsh -2 10)
-2048
[Endymion] (lsh 2 10)
2048
[Endymion] (power-of-two 10)
1024
[Endymion] (power-of-two -10)
1/1024
[Endymion] (lsh 2 1.0)
lsh : not a number : 1
[Endymion] (lsh 1/2 10)
lsh : not a number : 1/2
[Endymion] (power-of-two 1/2)
** : not a fixnum : 1/2

Valid XHTML 1.0 Strict back to home page © INRIA 2005, 2006 Last modified $Date: 2009/01/08 17:43:30 $