Skip to content

Instantly share code, notes, and snippets.

@thlorenz
Last active May 22, 2020 10:19
Show Gist options
  • Save thlorenz/4c5e376e5c58b9a4450d2d12458147dd to your computer and use it in GitHub Desktop.
Save thlorenz/4c5e376e5c58b9a4450d2d12458147dd to your computer and use it in GitHub Desktop.
Notes from commander_trashdin's Lisp intro on twitch

Common Lisp Twitch Intro Video Notes

Notes for intro provided by commander_thrashdin.

Functions

(fun arg1 arg1 ...)

Cons

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

Defintiion

(defun fib (n)
  (if (or (= n 0) (= n 1))
      n
      (+ (fib (- n 1))
         (fib (- n 2)))))

Optional Arguments, Keys and Rest Args

(defun foo (a b &optional c &key named-arg &rest args) ...)

Special Forms

If

(if (= 1 2) "the world is upside down" "all good") ; => "all good"

Quote

(quote
 (if (= 1 2)
     "the world is upside down"
   "all good")) ;; => (if (= 1 2) "the world is upside down" "all good")

Lists

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

Related Functions

destucturing-bind

remove-if

reduce

Note #' extracts function value

(reduce #'+ '(1 2 3 4 5))  ; => 15

Quoted Lists

` 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

(progn (print "hello world") (+ 1 2)) ; "hello world"  => 3

Arrays

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

Macros

or is macro

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

macroexpand expands macros

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

defmacro to define macros

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.

loop

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

Debugging/Tracing

Trace function execution via trace

sbcl Lisp Repl

  • Command line: sbcl use (quit) to exit
  • From Emacs: sly-mrepl
    • hitting <Enter> on result pretty prints it in separate buffer
@commander-trashdin
Copy link

destucturing-bind is a macro, not sure if I said it right.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment