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

Edit detail for LispInAxiom revision 1 of 1

1
Editor: page
Time: 2007/09/12 02:27:33 GMT-7
Note:

changed:
-
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.
\begin{axiom}
)lisp (defun foo1 (x y) (+ x y))
)lisp (foo1 2 3)
\end{axiom}

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"))

\begin{lisp}
;;; Just a silly example
(defun FOO2 (x y)
  (+ x y))
\end{lisp}

Click '+lisp' to check the Lisp output for errors.

We can call the function from Axiom like this:
\begin{axiom}
FOO2(3,4)$Lisp
\end{axiom}

Or we can call the function from Lisp like this:
\begin{lisp}
(format t "(FOO2 1 2) = ~a~%" (FOO2 1 2) )
\end{lisp}

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:
\begin{lisp}
(defunny FOO3 (x y)
  (+ x y))
\end{lisp}

'+lisp' shows the error message.

This is a lisp expression that generates some output.
\begin{lisp}
(format t "hello, world")
\end{lisp}

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:

\begin{axiom}
)lisp (* 2 (cos 0) (+ 4 6))
\end{axiom}

Here is a more complex recursive function.
\begin{lisp}
(defun fibonacci (N)
  "Compute the N'th Fibonacci number."
  (if (or (zerop N) (= N 1))
      1
    (+ (fibonacci (- N 1)) (fibonacci (- N 2)))))
\end{lisp}

We can trace its execution.
\begin{axiom}
)lisp (trace fibonacci)
)lisp (fibonacci 5)
\end{axiom}

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":http://cl-cookbook.sourceforge.net

\begin{lisp}
(defun adder (n)
   (function (lambda (x) (+ x n)))
)
\end{lisp}

\begin{axiom}
)lisp (adder 3)
)lisp (apply (adder 3) '(4))
)lisp (funcall (adder 3) 4)
)lisp (mapcar (adder 3) '(1 2 3 4))
\end{axiom}

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:

\begin{lisp}
(defun increment (i)
   (+ i 1)
)
\end{lisp}

\begin{axiom}
)lisp #'increment
)lisp (mapcar #'increment '(1 2 3))
)lisp #'(lambda (x) (increment x))
)lisp (mapcar #'(lambda (x) (increment x)) '(1 2 3))
\end{axiom}

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)

\begin{lisp}
(defun increment (i)
  (+ i 1)
)

(defun square (z)
  (* z z)
)

(defun compose (f g)
   #'(lambda (x) (funcall f (funcall g x)))
)
\end{lisp}

\begin{axiom}
)lisp (funcall (compose #'increment #'square) 3)
\end{axiom}

curry and uncurry

\begin{lisp}
(defun printthree (arg1 arg2 arg3)
  (format *query-io* "arg1 = ~A, arg2 = ~A, arg3 = ~A~%" arg1 arg2 arg3)
)
\end{lisp}

\begin{axiom}
)lisp (printthree 3 4 4) 
\end{axiom}

\begin{lisp}
(defun curry (function &rest args)
  (function (lambda (&rest more-args)
   (apply function (append args more-args)))))
\end{lisp}

\begin{axiom}
)lisp (curry #'printthree 'a)
)lisp (apply (curry #'printthree 'a) '(b c))
)lisp (curry #'printthree 'a 'b)
)lisp (apply (curry #'printthree 'a 'b) '(c))
\end{axiom}

\begin{lisp}
(defun uncurry (f)
   #'(lambda (x y)  (funcall (funcall f x) y))
)

(defun uncurry (f)
   #'(lambda (x y)  (funcall (funcall f x) y))
)
\end{lisp}

\begin{axiom}
)lisp (uncurry (curry #'+ 1))
\end{axiom}

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>