login  home  contents  what's new  discussion  bug reports     help  links  subscribe  changes  refresh  edit

It is possible to enter Lisp expressions directly into Axiom (including function definitions) using the )lisp command, but this is rather awkward for long Lisp programs.

axiom
)lisp (defun foo1 (x y) (+ x y))
Value = FOO1
axiom
)lisp (foo1 2 3)
Value = 5

On the Axiom wiki we can enter Lisp code in the same way that we enter Axiom code. For example:

  \begin{lisp}
  (defun FOO2 (x y)
    (+ x y))
  \end{lisp}

The text between the \begin{lisp} ... \end{lisp} is saved in a temporary file (e.g. tempfile.lisp). It is then compiled and loaded into Lisp via the command:

  )list (load (compile-file "tempfile.lisp"))

lisp
;;; Just a silly example
(defun FOO2 (x y)
  (+ x y))
lisp
Value = 304

Click +lisp to check the Lisp output for errors.

We can call the function from Axiom like this:

axiom
FOO2(3,4)$Lisp
LatexWiki Image(1)
Type: SExpression?

Or we can call the function from Lisp like this:

lisp
(format t "(FOO2 1 2) = ~a~%" (FOO2 1 2) )
lisp
(FOO2 1 2) = 3
Value = 88

Notice that the Value = 40 is the result of the (load ...) function call, not the value of the FOO2 function.

In the case of an error:

lisp
(defunny FOO3 (x y)
  (+ x y))
lisp
 
   >> System error:
   The function DEFUNNY is undefined.

+lisp shows the error message.

This is a lisp expression that generates some output.

lisp
(format t "hello, world")
lisp
hello, world
Value = 88

Lisp Tutorial 1

http://www.cs.sfu.ca/CC/310/pwfong/Lisp/1/tutorial1.html

Common LISP reads in an expression, evaluates it, and then prints out the result. For example, if you want to compute the value of (2 * cos(0) * (4 + 6)), you type in:

axiom
)lisp (* 2 (cos 0) (+ 4 6))
Value = 20.0

Here is a more complex recursive function.

lisp
(defun fibonacci (N)
  "Compute the N'th Fibonacci number."
  (if (or (zerop N) (= N 1))
      1
    (+ (fibonacci (- N 1)) (fibonacci (- N 2)))))
lisp
Value = 600

We can trace its execution.

axiom
)lisp (trace fibonacci)
Value = (FIBONACCI)
axiom
)lisp (fibonacci 5)
1> (FIBONACCI 5) 2> (FIBONACCI 4) 3> (FIBONACCI 3) 4> (FIBONACCI 2) 5> (FIBONACCI 1) <5 (FIBONACCI 1) 5> (FIBONACCI 0) <5 (FIBONACCI 1) <4 (FIBONACCI 2) 4> (FIBONACCI 1) <4 (FIBONACCI 1) <3 (FIBONACCI 3) 3> (FIBONACCI 2) 4> (FIBONACCI 1) <4 (FIBONACCI 1) 4> (FIBONACCI 0) <4 (FIBONACCI 1) <3 (FIBONACCI 2) <2 (FIBONACCI 5) 2> (FIBONACCI 3) 3> (FIBONACCI 2) 4> (FIBONACCI 1) <4 (FIBONACCI 1) 4> (FIBONACCI 0) <4 (FIBONACCI 1) <3 (FIBONACCI 2) 3> (FIBONACCI 1) <3 (FIBONACCI 1) <2 (FIBONACCI 3) <1 (FIBONACCI 8) Value = 8

Lisp Links & Notes (advanced)

http://www.cs.ucla.edu/classes/winter04/cs161/l1/lispLinks.html

by Michael G. Dyer http://www.cs.ucla.edu/classes/winter04/cs161/l1

lambda, closures, apply, funcall, and mapcar

One thing to note here is that the word "thunk" is often used as a synonym for "closure".

A closure is defined as a double whose two elements are a pointer to code and a pointer to an environment. In the adder example below, the reason we need the "environment pointer" is that we need a way to remember what n was bound to at the time that (adder 3) was created.

This particular "adder" example comes from the CL Cookbook

lisp
(defun adder (n)
   (function (lambda (x) (+ x n)))
)
lisp
Value = 536

axiom
)lisp (adder 3)
Value = #<compiled-closure 0000000001efbea0>
axiom
)lisp (apply (adder 3) '(4))
Value = 7
axiom
)lisp (funcall (adder 3) 4)
Value = 7
axiom
)lisp (mapcar (adder 3) '(1 2 3 4))
Value = (4 5 6 7)

There are two slightly different ways of using mapcar. One is by passing it a lambda block, which is created by simply prepending the #' in front of the function name. The other is to pass it a closure:

lisp
(defun increment (i)
   (+ i 1)
)
lisp
Value = 304

axiom
)lisp #'increment
Value = #<compiled-function INCREMENT>
axiom
)lisp (mapcar #'increment '(1 2 3))
Value = (2 3 4)
axiom
)lisp #'(lambda (x) (increment x))
Value = (LAMBDA-CLOSURE () () () (X) (INCREMENT X))
axiom
)lisp (mapcar #'(lambda (x) (increment x)) '(1 2 3))
Value = (2 3 4)

compose

Let's take a look at a "higher-order" function, which means that it takes functions as arguments. The compose function is the same as in mathematics. f(g(x)) = compose(f,g)(x)

lisp
(defun increment (i)
  (+ i 1)
)
(defun square (z) (* z z) )
(defun compose (f g) #'(lambda (x) (funcall f (funcall g x))) )
lisp
Value = 1048

axiom
)lisp (funcall (compose #'increment #'square) 3)
Value = 10

curry and uncurry

lisp
(defun printthree (arg1 arg2 arg3)
  (format *query-io* "arg1 = ~A, arg2 = ~A, arg3 = ~A~%" arg1 arg2 arg3)
)
lisp
Value = 320

axiom
)lisp (printthree 3 4 4)
arg1 = 3, arg2 = 4, arg3 = 4 Value = NIL

lisp
(defun curry (function &rest args)
  (function (lambda (&rest more-args)
   (apply function (append args more-args)))))
lisp
Value = 744

axiom
)lisp (curry #'printthree 'a)
Value = #<compiled-closure 0000000001f25240>
axiom
)lisp (apply (curry #'printthree 'a) '(b c))
arg1 = A, arg2 = B, arg3 = C Value = NIL
axiom
)lisp (curry #'printthree 'a 'b)
Value = #<compiled-closure 0000000001f25120>
axiom
)lisp (apply (curry #'printthree 'a 'b) '(c))
arg1 = A, arg2 = B, arg3 = C Value = NIL

lisp
(defun uncurry (f)
   #'(lambda (x y)  (funcall (funcall f x) y))
)
(defun uncurry (f) #'(lambda (x y) (funcall (funcall f x) y)) )
lisp
Warning: UNCURRY has a duplicate definition in this file
Value = 1088

axiom
)lisp (uncurry (curry #'+ 1))
Value = #<compiled-closure 0000000001f347e0>




subject:
  ( 7 subscribers )  
Please rate this page: