false is signalized by
Anything other than
nil signalizes True.
For readability reasons,
t is also provided.
Besides signalizing false values,
nil also represents the empty list
In EusLisp, global variables names are conventionally surrounded by
*, such as in
This notation allows clear understanding of each variable's scope, but is not obligatory.
Local variables can be introduced with
let. Such variables cannot be accessed from outside the
(let (a) (setq a 1)) a --> unbound variable error
Line comments start with
Block comments are surrounded by
Regarding line comments:
; is indented at fixed depth, many times at column 40.
;; is indented alongside code.
;;; is not indented.
In EusLisp linear lists are used, and there is no array. Objects of different types can be stored in the same list.
Lists can be created with the function
(setq *list* (list 0 1 2 3))
or with the
(setq *list* '(0 1 2 3))
Refer to elements
Elements of a certain index can be accessed using
(elt *list* 0) ;; 0 (nth 0 *list*) ;; 0
The first element can be referred with
(car *list*) ;; 0
cdr gives the list of all but the first element.
(cdr *list*) ;; (1 2 3)
The last element can be referred with the following.
(car (last *list*)) ;; 3
The length of the list is given by
(length *list*) ;; 4
Lists can be joined with
(setq *newlist* (append *list* (list 4 5 6))) ;; *newlist* is (0 1 2 3 4 5 6) ;; *list* remains unaltered
An element can be added with
push (destructive) or
cons (not destructive).
(push -1 *list*) ;; (-1 0 1 2 3)
pop takes out the first element of the list destructively.
(pop *list*) ;; -1 ;; *list* becomes (0 1 2 3)
when is executed when the condition is
(when condition (print "true"))
unless is the opposite of
when, being executed when the condition is
(unless condition (print "false"))
cond is used for if-else-if like statements.
(setq *val* 0) ;; Try out with different values (cond ((= *val* 0) (print "val = 0")) ((= *val* 1) (print "val = 1")) (t (print "default")))
cond, the first element of each s-expression is evaluated in order. If it is
non-nil the rest of the s-expression is executed and
cond exits; if it is
nil the next s-expression condition is evaluated.
In the above, the
t condition is executed when all of the above conditions do not apply (i.e. *val* is different from 0 and 1).
if works like an if-else clause. If the condition is
non-nil the first s-expression is executed, else the second one is executed.
(if condition (print "true") (print "false"))
if only deals with single s-expressions,
progn is used for evaluating multiple expressions in the same clause.
(if condition (progn (print "this") (print " is ") (print "true")) (print "false"))
(dotimes (i 10) (print i))
In the above,
i values from
(dolist (i (list 0 1 2 3)) (print i))
In the above,
i takes the value of each element in the list, from the start.
Loops while the condition is
(setq i 0) (while (< i 10) (print i) (setq i (+ 1 i)))
The above is similar to the
dotimes example above.
i is a global variable)
do-until-key is a special iteration form. Instead of evaluating a certain condition, it is executed until the
Enter key is pressed.
(do-until-key (print "press ENTER to stop"))
Other control clauses
return is used to exit loops such as
(dotimes (i 10) (when (= i 5) (return)) (print i))
return-from is used to exit a block with the given name, such as ones signaled by a function or method.
Details will be given afterwards.
Functions and Classes
Functions are defined with
(defun plus (a b) (+ a b))
And called as follows.
(plus 1 2)
The above is evaluates as
Functions return the last evaluated value.
Forced exit is done by
(defun plus-minus (a b c) (let (d e) (setq d (- a b)) (when (< d 0) (print "a < b, abort.") (return-from plus-minus nil)) (setq e (- (+ a b) c)) e) ;; let returns e )
In the above, try out the differences between
(plus-minus 1 2 3)
(plus-minus 2 1 3)
It is possible to give default values for function arguments as follows.
(defun negate (a &optional (b 0)) (- b a))
In the above, it is possible to use both
(negate 10 5)
Similarly, definition using key arguments is as follows.
(defun negate (a &key (b 0)) (- b a))
Which makes possible to use both
(negate 10 :b 5)
&optional, it is necessary to give key arguments by using
: followed by the variable name.
Classes and member functions can be defined as follows.
(defclass myclass :super propertied-object :slots (myname myage)) (defmethod myclass (:init (name age) (setq myname name myage age) self) (:myname (&optional (newname nil)) (when newname (setq myname newname)) myname) (:myage (&optional (newage nil)) (when newage (setq myage newage)) (unless (= myage 17) (print "something wrong.") (return-from :myage 17)) 17) ) ;; defmethod
:super indicates the parent class, which will be inherited.
Here, the class
propertied-object is used.
Member variables are signalized by
Member functions are defined with
defmethod, and have syntax similar to normal functions.
:init is the constructor, which returns
self i.e. the instance itself.
Methods are defined with
: followed by the method name.
Class objects can be created with the following.
(setq *me* (instance myclass :init "John Smith" 30))
Methods are called by
(send *me* :myname)
The above returns
(send *me* :myname "Alan Smithee")
The above replaces the member variable
This way, it is possible to use the same method for