Notes for intro provided by commander_thrashdin.
(fun arg1 arg1 ...)
(cons 1 (cons 2 (cons 3 ()))) ; => (1 2 3)
(cons 1 2) ; => (1 . 2)
(cons 1 '2) ; => (1 . 2)
(cons 1 '(2 3 4)) ; => (1 2 3 4)
(defun fib (n)
(if (or (= n 0) (= n 1))
n
(+ (fib (- n 1))
(fib (- n 2)))))
(defun foo (a b &optional c &key named-arg &rest args) ...)
(if (= 1 2) "the world is upside down" "all good") ; => "all good"
(quote
(if (= 1 2)
"the world is upside down"
"all good")) ;; => (if (= 1 2) "the world is upside down" "all good")
(first '(0 1 2 3)) ;; => 0
(rest '(0 1 2 3)) ;; => (1 2 3)
(elt '(0 1 2 3) 3) ;; => 3
(subseq '(0 1 2 3) 1) ;; => (1 2 3)
(subseq '(0 1 2 3) 1 2) ;; => (1)
Note #'
extracts function value
(reduce #'+ '(1 2 3 4 5)) ; => 15
`
is similar to '
except it allows expand forms via a ,
separator see ~defmacro~ to define macros
'(1 2 3 4) ; => (1 2 3 4)
`(1 2 3 4) ; => (1 2 3 4)
`(1 2 3 4 ,(+ 2 3)) ; => (1 2 3 4 5)
`(1 2 3 4 ,'(2 3)) ; => (1 2 3 4 (2 3))
`(1 2 3 4 ,(list 2 3)) ; => (1 2 3 4 (2 3))
`(1 2 3 4 ,(list 2 3 `(4 ,(+ 3 4)))) ; => (1 2 3 4 (2 3 (4 7)))
(progn (print "hello world") (+ 1 2)) ; "hello world" => 3
(make-array 5) ; => #(0 0 0 0 0)
(make-array 5
:initial-element 3
:adjustable t
:fill-pointer 4
:element-type 'fixnum) ; => #(3 3 3 3)
Returns t
if any of the passed forms return t
evaluates left to right. Stops at first form returning t
.
(or (= 1 0) (= 1 2) (= 1 3) (= 1 1) (= 1 5)) ; => t (never evaluates (= 1 5))
or
expands to many nested if
s
Note that '
returns the literal form instead of evaluating it
(macroexpand '(or (= 1 0) (= 1 1) (= 1 5)))
; (LET ((#:G582 (= 1 0)))
; (IF #:G582
; #:G582
; (LET ((#:G583 (= 1 1)))
; (IF #:G583
; #:G583
; (= 1 5)))))
; T
Anything that’s not a function or a special form is a macro, including defun
(macroexpand '(defun add (a b) (+ a b)))
; (PROGN
; (EVAL-WHEN (:COMPILE-TOPLEVEL) (SB-C:%COMPILER-DEFUN 'ADD T NIL NIL))
; (SB-IMPL::%DEFUN 'ADD
; (SB-INT:NAMED-LAMBDA ADD
; (A B)
; (BLOCK ADD (+ A B)))))
; T
Note &body
is a synonym for @rest
and only important for readability and possibly as a hint for formatters
(defmacro my-when (condition &body body)
`(if ,condition
,(cons 'progn body)
nil))
(macroexpand '(my-when
condition
(do-this)
(do-that)))
; (IF CONDITION
; (PROGN ((DO-THIS) (DO-THAT)))
; NIL)
; T
Alternative via macro specific splice notation ,@
(defmacro my-when (condition &body body)
`(if ,condition
(progn ,@body)
nil))
Emacs Lisp supports both the above forms as well.
Note the below does not work in elisp
(loop :for i :from 0 :upto 10
:when (evenp i)
:do (print i))
; 0
; 2
; 4
; 6
; 8
; 10 => NIL
(macroexpand
'(loop :for i :from 0 :upto 10
:when (evenp i)
:do (print i))); => (BLOCK NIL
; (LET ((I 0))
; (DECLARE (TYPE (AND REAL NUMBER) I))
; (TAGBODY
; SB-LOOP::NEXT-LOOP
; (WHEN (> I '10) (GO SB-LOOP::END-LOOP))
; (IF (EVENP I)
; (PRINT I))
; (SB-LOOP::LOOP-DESETQ I (1+ I))
; (GO SB-LOOP::NEXT-LOOP)
; SB-LOOP::END-LOOP)))
; T
- Command line:
sbcl
use(quit)
to exit - From Emacs:
sly-mrepl
- hitting
<Enter>
on result pretty prints it in separate buffer
- hitting
destucturing-bind
is a macro, not sure if I said it right.