"More Wonderful Features of Lisp"
A symbol can be created from a string
or with an automatically produced string.
(GENSYM) returns a new "uninterned"
symbol. An interned symbol is one that is associated with a package.
(INTERN "FOO") checks the current package for the existence of a symbol
named FOO and if none, creates a new symbol with this name. The symbol
(either an old one or a new one) is returned.
If a symbol is not interned, then
it cannot be referenced by its name.
It can only be referenced as the
value of something.
We can create a functional argument
for a new function without DEFUN
> (setq f #'(lambda
(x) (* x x)) )
#<function ...>
> (apply f '(17))
289
An unnamed function is one way to achieve both locality and modularity.
A functional argument may be made
from either a named function or an unnamed function.
(setq f1 #'(lambda
(x) (* x x)) )
(defun sqr (x) (* x
x))
(setq f2 #'sqr)
> (funcall f1 13)
169
> (funcall f2
13)
169
A closure is a function that captures
some state from the environment in which it is created.
It's like a "method" for an object
in an object-oriented programming system.
(let ((x 0) (y 0))
(defun xcount ()
(setq
x (1+ x))
(setq
y (* x x))
x)
(defun current-square ()
y)
)
> (xcount)
1
> (current-square)
1
> (xcount)
2
> (current-square)
4
> (current-square)
4
> (xcount)
3
> (current-square)
9
A function can return a new closure
as its value.
In this case the closures are created
using an unnamed function.
> (defun make-accumulator
( sound )
(let ((x 0))
#'(lambda (delta) (print sound)(incf x delta))
) )
MAKE-ACCUMULATOR
> (setq accumulate-cents (make-accumulator
'clink))
#<closure...>
> (setq accumulate-dollars
(make-accumulator 'klunk))
#<closure...>
> (funcall accumulate-dollars
5)
KLUNK
5
> (funcall accumulate-dollars
7)
KLUNK
12
> (funcall accumulate-cents
1)
CLINK
1
> (funcall accumulate-cents
10)
CLINK
11
Getting an S-expression from the user:
> (setq x (read))
5
5
> X
5
Another example:
(append '(I think you said)
(list (read) ) )
OK
(I THINK YOU SAID OK)
Output
Output with traditional functions:
> (print 'x)
X
X
> (prin1 'x)
X
X
> (terpri)
NIL
>
Formatted output with FORMAT,
analogous to C's printf function.
> (format t "This
is a string.~%")
This is a string.
NIL
> (format t "The
sum of ~S plus ~S equals ~S." 2 5 (+ 2 5))
The sum of 2 plus 5 equals 7.
NIL
For file output...
> (with-open-file (f
"foo.txt" :direction :output)
(format f "This goes into the file.")
)
And input ... Note that READ takes only the first S-expression:
> (with-open-file (f
"foo.txt" :direction :input)
(print (read f)) )
THIS
THIS
> (with-open-file (f
"foo.txt" :direction :input)
(setq s (read-line f)) )
"This goes into the file."
Loading a file of S-expressions to be evaluated:
> (load "myprogram.lsp")
> (setq achar #\a )
#\a
> (characterp achar)
T
> (lower-case-p achar)
T
> (upper-case-p achar)
NIL
An array can be created in two ways: with MAKE-ARRAY or with the direct array notation.
> (setq my-array
#1a(1 2 3 4))
#(1 2 3 4)
> (setq my-array2
(make-array '(4) :initial-contents '(1 2 3 4)) )
#(1 2 3 4)
To access an array, use AREF
> (aref my-array 3)
4
> (aref my-array 0)
1
To change the contents of an element,
use both SETF and AREF together.
> (setf (aref my-array 0) 'neat)
NEAT
> my-array
#(NEAT 2 3 4)
Strings are sequences of characters.
> (setq s1 "This is a string.")
"This is a string."
> (char s1 0)
#\T
> (char s1 4)
#\space
> (concatenate 'string s1
s1)
"This is a string.This is a string."
;;; SETQ2 is like SETQ but it's
the 2nd arg that's quoted.
> (defmacro setq2 (arg1
arg2)
(list 'set arg1
(list 'quote arg2)) )
SETQ2
> (macroexpand '(setq2
'a (this is a list)))
(SET 'A '(THIS IS A LIST))
T
> (setq2 'a (this is a list))
(THIS IS A LIST)
> a
(THIS IS A LIST)
;;; Macros can be used to create
new functions from symbols.
(defmacro make-predicate
(name)
(list 'defun (intern
(concatenate 'string (string name) "P"))
'(arg)
(list 'eq 'arg (list 'quote name)) ) )
;;; This one creates a new
predicate that returns T if
;;; its argument is
the symbol mentioned in NAME above.
> (make-predicate crazy)
CRAZYP
> (crazyp 'crazy)
T
> (crazyp 2)
NIL
> (make-predicate funny)
FUNNYP
> (funnyp 'crazy)
NIL
> (funnyp 'funny)
T
Last modified: October 7, 1998
Steve Tanimoto