|
|
last edited 7 years ago by test1 |
1 2 | ||
Editor: test1
Time: 2016/09/16 16:02:11 GMT+0 |
||
Note: |
added:
One can put longer programs in files and use ')read file.lisp'
to compile and run them.
It is possible to enter Lisp expressions directly into FriCAS
(including function definitions) using the )lisp
command,
but this is rather awkward for long Lisp programs.
)lisp (defun foo1 (x y) (+ x y))
Value = FOO1
)lisp (foo1 2 3)
Value = 5
One can put longer programs in files and use )read file.lisp
to compile and run them.
On the FriCAS wiki we can enter Lisp code in the same way that we enter FriCAS 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:
)lisp (load (compile-file "tempfile.lisp"))
;;; Just a silly example (defun FOO2 (x y) (+ x y))
; compiling file "/var/aw/var/LatexWiki/5467520105124776552-25px002.lisp" (written 16 SEP 2016 04:02:10 PM):
; /var/lib/zope2.10/instance/axiom-wiki/var/LatexWiki/5467520105124776552-25px002.fasl written ; compilation finished in 0:00:00.031 Value = T
Click +lisp
to check the Lisp output for errors.
We can call the function from FriCAS like this:
FOO2(3,4)$Lisp
(1) |
Or we can call the function from Lisp like this:
(format t "(FOO2 1 2) = ~a~%" (FOO2 1 2) )
; compiling file "/var/aw/var/LatexWiki/4849575266889566101-25px004.lisp" (written 16 SEP 2016 04:02:10 PM):
; /var/lib/zope2.10/instance/axiom-wiki/var/LatexWiki/4849575266889566101-25px004.fasl written ; compilation finished in 0:00:00.001 (FOO2 1 2) = 3 Value = T
Notice that the Value = T
is the result of the (load ...)
function call, not the value of the FOO2
function.
In the case of an error:
(defunny FOO3 (x y) (+ x y))
; compiling file "/var/aw/var/LatexWiki/7691373298349222252-25px005.lisp" (written 16 SEP 2016 04:02:10 PM):
; /var/lib/zope2.10/instance/axiom-wiki/var/LatexWiki/7691373298349222252-25px005.fasl written ; compilation finished in 0:00:00.013
>> System error: The variable FOO3 is unbound.
+lisp
shows the error message.
This is a lisp expression that generates some output.
(format t "hello,world")
; compiling file "/var/aw/var/LatexWiki/229055943891593707-25px006.lisp" (written 16 SEP 2016 04:02:10 PM):
; /var/lib/zope2.10/instance/axiom-wiki/var/LatexWiki/229055943891593707-25px006.fasl written ; compilation finished in 0:00:00.001 hello,world Value = T
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:
)lisp (* 2 (cos 0) (+ 4 6))
Value = 20.0f0
Here is a more complex recursive function.
(defun fibonacci (N) "Compute the N'th Fibonacci number." (if (or (zerop N) (= N 1)) 1 (+ (fibonacci (- N 1)) (fibonacci (- N 2)))))
; compiling file "/var/aw/var/LatexWiki/8805225188305955522-25px008.lisp" (written 16 SEP 2016 04:02:10 PM):
; /var/lib/zope2.10/instance/axiom-wiki/var/LatexWiki/8805225188305955522-25px008.fasl written ; compilation finished in 0:00:00.009 Value = T
We can trace its execution.
)lisp (trace fibonacci)
Value = (FIBONACCI)
)lisp (fibonacci 5)
0: (FIBONACCI 5) 1: (FIBONACCI 4) 2: (FIBONACCI 3) 3: (FIBONACCI 2) 4: (FIBONACCI 1) 4: FIBONACCI returned 1 4: (FIBONACCI 0) 4: FIBONACCI returned 1 3: FIBONACCI returned 2 3: (FIBONACCI 1) 3: FIBONACCI returned 1 2: FIBONACCI returned 3 2: (FIBONACCI 2) 3: (FIBONACCI 1) 3: FIBONACCI returned 1 3: (FIBONACCI 0) 3: FIBONACCI returned 1 2: FIBONACCI returned 2 1: FIBONACCI returned 5 1: (FIBONACCI 3) 2: (FIBONACCI 2) 3: (FIBONACCI 1) 3: FIBONACCI returned 1 3: (FIBONACCI 0) 3: FIBONACCI returned 1 2: FIBONACCI returned 2 2: (FIBONACCI 1) 2: FIBONACCI returned 1 1: FIBONACCI returned 3 0: FIBONACCI returned 8 Value = 8
http://www.lispworks.com/documentation/HyperSpec/Front/
http://www.cs.ucla.edu/classes/winter04/cs161/l1/lispLinks.html
by Michael G. Dyer http://www.cs.ucla.edu/classes/winter04/cs161/l1
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
(defun adder (n) (function (lambda (x) (+ x n))) )
; compiling file "/var/aw/var/LatexWiki/1662804482358068841-25px010.lisp" (written 16 SEP 2016 04:02:10 PM):
; /var/lib/zope2.10/instance/axiom-wiki/var/LatexWiki/1662804482358068841-25px010.fasl written ; compilation finished in 0:00:00.003 Value = T
)lisp (adder 3)
Value = #<CLOSURE (LAMBDA (X) :IN ADDER) {1004A0CE2B}>
)lisp (apply (adder 3) '(4))
Value = 7
)lisp (funcall (adder 3) 4)
Value = 7
)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:
(defun increment (i) (+ i 1) )
; compiling file "/var/aw/var/LatexWiki/4211409212481666063-25px012.lisp" (written 16 SEP 2016 04:02:10 PM):
; /var/lib/zope2.10/instance/axiom-wiki/var/LatexWiki/4211409212481666063-25px012.fasl written ; compilation finished in 0:00:00.001 Value = T
)lisp #'increment
Value = #<FUNCTION INCREMENT>
)lisp (mapcar #'increment '(1 2 3))
Value = (2 3 4)
)lisp #'(lambda (x) (increment x))
Value = #<INTERPRETED-FUNCTION NIL {1004A704BB}>
)lisp (mapcar #'(lambda (x) (increment x)) '(1 2 3))
Value = (2 3 4)
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)
(defun increment (i) (+ i 1) )
(defun square (z) (* z z) )
(defun compose (f g) #'(lambda (x) (funcall f (funcall g x))) )
; compiling file "/var/aw/var/LatexWiki/6034342207465796072-25px014.lisp" (written 16 SEP 2016 04:02:10 PM):
; /var/lib/zope2.10/instance/axiom-wiki/var/LatexWiki/6034342207465796072-25px014.fasl written ; compilation finished in 0:00:00.003 Value = T
)lisp (funcall (compose #'increment #'square) 3)
Value = 10
curry and uncurry
(defun printthree (arg1 arg2 arg3) (format *query-io* "arg1 = ~A,arg2 = ~A, arg3 = ~A~%" arg1 arg2 arg3) )
; compiling file "/var/aw/var/LatexWiki/4952192325462136804-25px016.lisp" (written 16 SEP 2016 04:02:10 PM):
; /var/lib/zope2.10/instance/axiom-wiki/var/LatexWiki/4952192325462136804-25px016.fasl written ; compilation finished in 0:00:00.006 Value = T
)lisp (printthree 3 4 4)
arg1 = 3,arg2 = 4, arg3 = 4 Value = NIL
(defun curry (function &rest args) (function (lambda (&rest more-args) (apply function (append args more-args)))))
; compiling file "/var/aw/var/LatexWiki/2878124551976497830-25px018.lisp" (written 16 SEP 2016 04:02:10 PM):
; /var/lib/zope2.10/instance/axiom-wiki/var/LatexWiki/2878124551976497830-25px018.fasl written ; compilation finished in 0:00:00.004 Value = T
)lisp (curry #'printthree 'a)
Value = #<CLOSURE (LAMBDA (&REST MORE-ARGS) :IN CURRY) {1004C45A1B}>
)lisp (apply (curry #'printthree 'a) '(b c))
arg1 = A,arg2 = B, arg3 = C Value = NIL
)lisp (curry #'printthree 'a 'b)
Value = #<CLOSURE (LAMBDA (&REST MORE-ARGS) :IN CURRY) {1004C4CC6B}>
)lisp (apply (curry #'printthree 'a 'b) '(c))
arg1 = A,arg2 = B, arg3 = C Value = NIL
(defun uncurry (f) #'(lambda (x y) (funcall (funcall f x) y)) )
(defun uncurry (f) #'(lambda (x y) (funcall (funcall f x) y)) )
; compiling file "/var/aw/var/LatexWiki/6522788210180720678-25px020.lisp" (written 16 SEP 2016 04:02:10 PM):
; /var/lib/zope2.10/instance/axiom-wiki/var/LatexWiki/6522788210180720678-25px020.fasl written ; compilation finished in 0:00:00.005 Value = T
)lisp (uncurry (curry #'+ 1))
Value = #<CLOSURE (LAMBDA (X Y) :IN UNCURRY) {1004CF334B}>