SlideShare une entreprise Scribd logo
1  sur  52
Télécharger pour lire hors ligne
Why Won’t Lisp Just Go
      Away?
       Inroducing Lisp
      50 Years Young (2008)
http://lisperati.org/casting.html, by permission of Conrad Barski, MD
Effort vs Productivity
                   (my subjective point of view)
                                 (not to scale)
                     (this chart has no meaning, it is a joke)

100


                   PAIP, On Lisp, SICP



 75




                  The segafault that
                  made you leave C++
 50



      Java Cookbook                                                          EJB3, J5EE, JMX,
                                                                        Me   Struts, JMS,
                                                                             Exhausted Permgen
 25




                                                                             You are Here

  0


           Java                          C++                     Lisp
Overview
 What is Lisp?
 How to get started
   Some Basics
   Some Common Recipes
 Wet your appetite for more
   Not so basic things
 Where to go next
What is Lisp?
 A Programming Language
 Brought to you by John McCarthy circa 1958
 Resistance is Futile...
    Garbage Collection, Closures, Functional, Object
    Oriented, AOP, DSLs, Conditions and Restarts,
    Continuations, what else ya got?
Welcome to the Family
 Common Lisp (Lisp 2)
    LispWorks, Alegro

    OpenMCL, SBCL, Clisp, ABCL and others

 Scheme (Lisp 1) by Sussman and Steele
    PLT, Chicken, Bigloo, Clojure, SISC, JScheme, and
    others
 Less Common
    Dylan, Qi, Termite, ECL, Arc, and others...
Quick Start
LispBox
  http://gigamonkeys.com/lispbox/
  Windows, OS X, Linux

Ready Lisp
  http://www.newartisans.com/software/readylisp.html

  OS X
Roll your own
 Emacs
 SLIME
   The Superior Lisp Interaction Mode for Emacs
 Common Lisp
   SBCL, CLISP
 paraedit-el
Basics

 Parentheses, lots and lots of parentheses
 Everything is an Expression
 Prefix Notation
 Lists, ‘cons’, pair
   Singly Linked List
Basics: Cons Cells, Lists
car
                          (), nil, the empty list, false
          cdr



 1                  (list 1) (cons 1 nil)



 1    2             (cons 1 2)



 1              2         3              (list 1 2 3)

 (cons 1 (cons 2 (cons 3 nil)))
Basics: Expressions
(if test-p consequent otherwise)

(+ 1 2 3 4 5)   => 15

(let ((x 3)
      (y 2))
  (* x y))      => 6

(expt 2 42)     => 4398046511104
Basics: Functions
(defun test (n)
  (cond
    ((= n 0)
	    (+ 1 n))
	   (t
	    (- n 1))))

(funcall #'test 3)
(apply #’test ‘(3))

(mapcar #'test '(-2 -1 0 1 2))
=> (-3 -2 1 0 1)
Basics: Assignment
 (setf x '(a b c))
 => (A B C)

 (setf (car x) 1)
 => (1 B C)

 (setf (second x) 2)
 => (1 2 C)
Numeric Tower

 Ints and Floats, but also...
 Ratios
 Built in Bignum Support
 Built in Complex Numbers
Numeric Tower
1/2
(/ 1 3)               => 1/3
(* 33333 (/ 1 33333)) => 1


(expt 2 100)          => 1267650600228229401496703205376


(* #c(0 1) #c(0 1))   => -1
Familiar Data Structures
 Vectors (arrays)
 Hash Tables (map)
 Structures (records)
 Objects - CLOS
 Sequence Types (and streams)
Library System: ASDF
 ASDF - another system definition facility
   Like Ruby’s gem or Perl’s CPAN (but inscrutable)
 (require :asdf-install)
 (asdf-install:install :cl-ppcre)
 Repository: cliki.net
Example: Fetch the Web

(require :drakma)
(use-package :drakma)
(defvar content nil)
(setf content
  (http-request quot;http://google.com/quot;))
(format t quot;len:~a~" (length content))
(format t quot;~a~" (subseq content 0 100))
Example: Serve the Web
(require :hunchentoot)
(use-package :hunchentoot)
(setq *dispatch-table*
  (list
    (create-prefix-dispatcher
      quot;/indexquot; 'index-page)))
(defun index-page ()
  quot;<h1>Hunchentoot Demo</h1>.quot;)
(defvar server
  (hunchentoot:start-server :port 4242))
Example: Process Files

(require :cl-ppcre)

(with-open-file (inp quot;.../input.txtquot; :direction :input)
  (loop for line = (read-line inp nil nil)
     while line
     do
     (format t quot;~a~&quot;
	       (cl-ppcre:regex-replace quot;lis+pquot; line quot;lispquot;))))
Example: Unit Testing
(define-test test-flatten
 (assert-false (flatten))
 (assert-false (flatten '()))
 (assert-equal '(a)
               (flatten 'a))
 (assert-equal '(a)
               (flatten '(a)))
 (assert-equal '(a b c d)
               (flatten '(a (b (c (d)))))))
More Interesting Stuff

 Macros, Reader Macros, syntax-rules
 Restarts
   “To Err is Expected, To Recover, Divine” -- David B. Lamkins

 Functional Programming
 Pattern Matching (Unification)
What’s a Macro?
  A tool for Abstraction
  Code Generator
  Compiler


  defmacro
  define-macro
  syntax-rules
Macro: random-if

(defmacro random-if (prob consequent otherwise)
  `(if (< (random 1.0) ,prob))
       ,consequent
       ,otherwise))

(random-if 1/2
      (format t quot;went left~&quot;)
      (format t quot;went right~&quot;)
Macro: aprog1
(defmacro aprog1 (it &rest body)
  `(let ((it ,it))      give the thing   a name
     ,@body
                      let them use it
     it))
                 return it

(aprog1 (make-hash-table :test #’equal)
  (setf (gethash “a” it) 1)
  (setf (gethash “b” it) 2))
=> #<HASH-TABLE :TEST EQUAL :COUNT 2 {BE49831}>
Macro: rcut
(defmacro rcut (&rest body)
 (let* ((formals (list))
        (new-body
         (map-tree #'(lambda (elt)
                       (if (symbol-equal '<> elt)
                           (aprog1
                            (gensym)
                            (push it formals)
                            it)
                           elt))
                   body)))
   `#'(lambda ,(reverse formals)
        ,@new-body)))

(macroexpan-1 ‘(rcut (format “val:~a~&” <>)))
  => #'(LAMBDA (#:G2348) (FORMAT NIL quot;elt:~a~&quot; #:G2348))
Restarts: Structured Recovery
(defun file-size (file)
  (restart-case
    (if (not (probe-file file))       ‘throw’
      (error 'file-not-found)
      (sb-posix:stat-size (sb-posix:stat file)))
    (file-not-found (new-file-size)
      :report quot;Specify missing size.quot;
                                             recovery
      :interactive read-new-value
      new-file-size)))

(defun bytes-used (files)
  (loop for file in files
	   summing (file-size file)))
Restarts in action
CL-USER> (format t quot;bytes:~a~&quot; (bytes-used '(quot;/etc/passwdquot; quot;/foo/barquot;)))
Condition FILE-NOT-FOUND was signalled.
   [Condition of type FILE-NOT-FOUND]

Restarts:
 0: [FILE-NOT-FOUND] Specify missing size.
 1: [ABORT] Return to SLIME's top level.
 2: [TERMINATE-THREAD] Terminate this thread (#<THREAD quot;repl-threadquot; ...>)

Backtrace:
  0: (FILE-SIZE quot;/foo/barquot;)
  1: (BYTES-USED (quot;/etc/passwdquot; quot;/foo/barquot;))
   ...snip...
Enter a new value: 12
bytes:2900
More Interesting Stuff

 Functional Programming
   Functions are first class - composable
   list comprehensions (cl-incf)
   pattern-matching (cl-unification, pcond)
 DSLs, mini-languages
First Class Functions
(mapcar #'(lambda (x) (+ 2 x))
          '(1 2 3 4))       => ‘(3 4 5 6)

(defun curry (fn &rest args)
  #'(lambda (&rest rest)
      (apply fn (append args rest))))

(funcall (curry #'+ 2) 3)   => 5

(mapcar (curry #'+ 2)
    '(1 2 3 4))             => ‘(3 4 5 6)
First Class Functions

 (defun memoize (fn)
   (let ((cache (make-hash-table :test #'equal)))
      #’(lambda (&rest args)
         (let ((key (format nil quot;~aquot; args)))
 	        (if (gethash key cache)
 	
Return      (gethash key cache)
from
 	
cache       (aprog1
 	            (apply fn args)
   	          (setf (gethash key cache) it)))))))

Add result to
cache and return
First Class Functions
(defun myfn (a b c)
  (format t quot;called: a:~a b:~a c:~a~&quot; a b c)
  (+ a b c))

(let ((mfn (memoize #'myfn))
      (args '(1 2 3))
      (args2 '(4 5 6)))
  (format t quot;mfn ~a: ~a~&quot; args (apply mfn args))
  (format t quot;mfn ~a: ~a~&quot; args (apply mfn args))
  (format t quot;mfn ~a: ~a~&quot; args2 (apply mfn args2))
  (format t quot;mfn ~a: ~a~&quot; args2 (apply mfn args2)))
=>
called: a:1 b:2 c:3        not in cache
mfn (1 2 3): 6
mfn (1 2 3): 6             in cache
called: a:4 b:5 c:6        not in cache
mfn (4 5 6): 15
mfn (4 5 6): 15            in cache
List Comprehensions
(defun lcmp-qsort (things)
  (cond ((null things)
	 things)
	 (t
	 (destructuring-bind (pivot . tl) things
	    (append
	     (lcmp-qsort
	       (assemble x (<- x tl) (< x pivot)))
	     (list pivot)
	     (lcmp-qsort
	       (assemble x (<- x tl) (>= x pivot))))))))
List Comprehensions
(defun lcmp-qsort (things)
  (cond ((null things)
	 things)
	 (t
	 (destructuring-bind (pivot . tl) things
	    (append
	     (lcmp-qsort
	       (assemble x (<- x tl) (< x pivot)))
	     (list pivot)
	     (lcmp-qsort
	       (assemble x (<- x tl) (>= x pivot))))))))
List Comprehensions
(defun lcmp-qsort (things)
  (cond ((null things)
	 things)
	 (t
	 (destructuring-bind (pivot . tl) things
	    (append
	     (lcmp-qsort
	       (assemble x (<- x tl) (< x pivot)))
	     (list pivot)
	     (lcmp-qsort
	       (assemble x (<- x tl) (>= x pivot))))))))
List Comprehensions
(defun lcmp-qsort (things)
  (cond ((null things)
	 things)
	 (t
	 (destructuring-bind (pivot . tl) things
	    (append
	     (lcmp-qsort
	       (assemble x (<- x tl) (< x pivot)))
	     (list pivot)
	     (lcmp-qsort
	       (assemble x (<- x tl) (>= x pivot))))))))
List Comprehensions
(defun lcmp-qsort (things)
  (cond ((null things)
	 things)
	 (t
	 (destructuring-bind (pivot . tl) things
	    (append
	     (lcmp-qsort
	       (assemble x (<- x tl) (< x pivot)))
	     (list pivot)
	     (lcmp-qsort
	       (assemble x (<- x tl) (>= x pivot))))))))
List Comprehensions
(defun lcmp-qsort (things)
  (cond ((null things)
	 things)
	 (t
	 (destructuring-bind (pivot . tl) things
	    (append
	     (lcmp-qsort
	       (assemble x (<- x tl) (< x pivot)))
	     (list pivot)
	     (lcmp-qsort
	       (assemble x (<- x tl) (>= x pivot))))))))
List Comprehensions

(defun all-permutations (things)
  (cond
    ((= 1 (length things))
     (list things))
    (t
     (assemble
	       (cons Head Tail)
        (<- Head things)
        (<- Tail
            (all-permutations (remove Head things)))))))
List Comprehensions

(defun all-permutations (things)
  (cond
    ((= 1 (length things))
     (list things))
    (t
     (assemble
	       (cons Head Tail)
        (<- Head things)
        (<- Tail
            (all-permutations (remove Head things)))))))
List Comprehensions

(defun all-permutations (things)
  (cond
    ((= 1 (length things))
     (list things))
    (t
     (assemble
	       (cons Head Tail)
        (<- Head things)
        (<- Tail
            (all-permutations (remove Head things)))))))
List Comprehensions

(defun all-permutations (things)
  (cond
    ((= 1 (length things))
     (list things))
    (t
     (assemble
	       (cons Head Tail)
        (<- Head things)
        (<- Tail
            (all-permutations (remove Head things)))))))
List Comprehensions

(defun all-permutations (things)
  (cond
    ((= 1 (length things))
     (list things))
    (t
     (assemble
	       (cons Head Tail)
        (<- Head things)
        (<- Tail
            (all-permutations (remove Head things)))))))
List Comprehensions

(defun all-permutations (things)
  (cond
    ((= 1 (length things))
     (list things))
    (t
     (assemble
	       (cons Head Tail)
        (<- Head things)
        (<- Tail
            (all-permutations (remove Head things)))))))
Pattern Matching: pcond
(defun ptest (names)
  (pcond:pcond
   ((and (:pat ((?first ?last) . ?rest)
	          names)
	        (:re quot;(.+)oquot; ?first (before-o)))
    (format t quot;before-o: ~a~&quot; before-o)
    (ptest ?rest))))

(ptest '((quot;George quot; quot;Washingtonquot;) (quot;Johnquot; quot;Adamsquot;)))

=> before-o: Ge
=> before-o: J
DSLs, mini-languages
(define-syntax aprog1
  (syntax-rules (it)
    ((_ expression . body)
     (let ((it expression))
       body
       it))))

(macroexpand '(aprog1 (list) (set! it (cons ‘a it))))
=>
(let ((it (list)))
   (set! it (cons 'a it))
   it)
DSLs, mini-languages

(define m
  (automation init
    (init : (c -> more))
    (more : (a -> more)
            (d -> more)
            (r -> end))
    (end :)))
DSLs, mini-languages
(define-syntax automation
  (syntax-rules (: ->)
    ((_ init-state
	     (state : (label -> target) ...)
	     ...)
     (letrec
       ((state
	          (lambda (stream)
	 	          (cond
	 	            ((empty? stream) #t)
	 	            (else
	 	              (case (first stream)
	 	                ((label) (target (rest stream)))
	 	                ...
	 	                (else #f))))))
	      ...)
       init-state))))
DSLs, mini-languages
(letrec
  ((init (lambda (GenTemp%2)
           (cond ((empty? GenTemp%2) #t)
                 (else (case (first GenTemp%2)
                         ((c) (more (rest GenTemp%2)))
                         (else #f))))))
   (more (lambda (GenTemp%2)
           (cond ((empty? GenTemp%2) #t)
                 (else (case (first GenTemp%2)
                         ((a) (more (rest GenTemp%2)))
                         ((d) (more (rest GenTemp%2)))
                         ((r) (end (rest GenTemp%2)))
                         (else #f))))))
   (end (lambda (GenTemp%2)
           (cond ((empty? GenTemp%2) #t)
                 (else (case (first GenTemp%2)
                         (else #f)))))))
  init)
That’s the overview




 http://lisperati.org/casting.html, by permission of Conrad Barski, MD
Now where am I supposed to go?
 On-Line Resources

   Common Lisp Hyper Spec

   On Lisp (Paul Graham)

   Practical Common Lisp (Peter Siebel)

   Cliki.net

   common-lisp.net

   JRMs Syntax Rules Primer

   Casting Spells with Lisp: http://lisperati.org/casting.html

   http://del.icio.us/mortis/lisp
Now where am I supposed to go?

 Books
  PAIP (Peter Norvig)
  Practical Common Lisp (Peter Seibel)
  SICP (Ableson and Sussman)
  Common Lisp the Language (Guy Steele)
  ANSI Common Lisp (Paul Graham)

Contenu connexe

Tendances

Gentle Introduction To Lisp
Gentle Introduction To LispGentle Introduction To Lisp
Gentle Introduction To LispDamien Garaud
 
Lisp Programming Languge
Lisp Programming LangugeLisp Programming Languge
Lisp Programming LangugeYaser Jaradeh
 
Learn a language : LISP
Learn a language : LISPLearn a language : LISP
Learn a language : LISPDevnology
 
Contravariant functors in scala
Contravariant functors in scalaContravariant functors in scala
Contravariant functors in scalaPiotr Paradziński
 
Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...Piotr Paradziński
 
Scala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesTomer Gabel
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsQuark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsJohn De Goes
 
Lisp for Python Programmers
Lisp for Python ProgrammersLisp for Python Programmers
Lisp for Python ProgrammersVsevolod Dyomkin
 
Real World Haskell: Lecture 7
Real World Haskell: Lecture 7Real World Haskell: Lecture 7
Real World Haskell: Lecture 7Bryan O'Sullivan
 
BayFP: Concurrent and Multicore Haskell
BayFP: Concurrent and Multicore HaskellBayFP: Concurrent and Multicore Haskell
BayFP: Concurrent and Multicore HaskellBryan O'Sullivan
 
Haskell for data science
Haskell for data scienceHaskell for data science
Haskell for data scienceJohn Cant
 
Lambda выражения и Java 8
Lambda выражения и Java 8Lambda выражения и Java 8
Lambda выражения и Java 8Alex Tumanoff
 

Tendances (20)

Gentle Introduction To Lisp
Gentle Introduction To LispGentle Introduction To Lisp
Gentle Introduction To Lisp
 
Lisp
LispLisp
Lisp
 
Lisp Programming Languge
Lisp Programming LangugeLisp Programming Languge
Lisp Programming Languge
 
Prolog & lisp
Prolog & lispProlog & lisp
Prolog & lisp
 
Learn a language : LISP
Learn a language : LISPLearn a language : LISP
Learn a language : LISP
 
Lisp
LispLisp
Lisp
 
Haskell
HaskellHaskell
Haskell
 
LISP: Data types in lisp
LISP: Data types in lispLISP: Data types in lisp
LISP: Data types in lisp
 
LISP: Input And Output
LISP: Input And OutputLISP: Input And Output
LISP: Input And Output
 
Contravariant functors in scala
Contravariant functors in scalaContravariant functors in scala
Contravariant functors in scala
 
Java 8 Lambda Expressions
Java 8 Lambda ExpressionsJava 8 Lambda Expressions
Java 8 Lambda Expressions
 
Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...
 
Scala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type Classes
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsQuark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
 
Lisp for Python Programmers
Lisp for Python ProgrammersLisp for Python Programmers
Lisp for Python Programmers
 
Real World Haskell: Lecture 7
Real World Haskell: Lecture 7Real World Haskell: Lecture 7
Real World Haskell: Lecture 7
 
BayFP: Concurrent and Multicore Haskell
BayFP: Concurrent and Multicore HaskellBayFP: Concurrent and Multicore Haskell
BayFP: Concurrent and Multicore Haskell
 
Haskell for data science
Haskell for data scienceHaskell for data science
Haskell for data science
 
MTL Versus Free
MTL Versus FreeMTL Versus Free
MTL Versus Free
 
Lambda выражения и Java 8
Lambda выражения и Java 8Lambda выражения и Java 8
Lambda выражения и Java 8
 

Similaire à Introduction To Lisp

CL metaprogramming
CL metaprogrammingCL metaprogramming
CL metaprogrammingdudarev
 
The Magnificent Seven
The Magnificent SevenThe Magnificent Seven
The Magnificent SevenMike Fogus
 
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
[FT-11][suhorng] “Poor Man's” Undergraduate CompilersFunctional Thursday
 
Continuation Passing Style and Macros in Clojure - Jan 2012
Continuation Passing Style and Macros in Clojure - Jan 2012Continuation Passing Style and Macros in Clojure - Jan 2012
Continuation Passing Style and Macros in Clojure - Jan 2012Leonardo Borges
 
Functional Concepts for OOP Developers
Functional Concepts for OOP DevelopersFunctional Concepts for OOP Developers
Functional Concepts for OOP Developersbrweber2
 
Clojure for Java developers - Stockholm
Clojure for Java developers - StockholmClojure for Java developers - Stockholm
Clojure for Java developers - StockholmJan Kronquist
 
Meta-objective Lisp @名古屋 Reject 会議
Meta-objective Lisp @名古屋 Reject 会議Meta-objective Lisp @名古屋 Reject 会議
Meta-objective Lisp @名古屋 Reject 会議dico_leque
 
Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)Phil Calçado
 
Scala as a Declarative Language
Scala as a Declarative LanguageScala as a Declarative Language
Scala as a Declarative Languagevsssuresh
 
Clojure Intro
Clojure IntroClojure Intro
Clojure Introthnetos
 
Scala + WattzOn, sitting in a tree....
Scala + WattzOn, sitting in a tree....Scala + WattzOn, sitting in a tree....
Scala + WattzOn, sitting in a tree....Raffi Krikorian
 
Modern technologies in data science
Modern technologies in data science Modern technologies in data science
Modern technologies in data science Chucheng Hsieh
 
Class 16: Making Loops
Class 16: Making LoopsClass 16: Making Loops
Class 16: Making LoopsDavid Evans
 
AutoDesk
AutoDeskAutoDesk
AutoDeskSE3D
 

Similaire à Introduction To Lisp (20)

CL metaprogramming
CL metaprogrammingCL metaprogramming
CL metaprogramming
 
The Magnificent Seven
The Magnificent SevenThe Magnificent Seven
The Magnificent Seven
 
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
 
Scala @ TomTom
Scala @ TomTomScala @ TomTom
Scala @ TomTom
 
Continuation Passing Style and Macros in Clojure - Jan 2012
Continuation Passing Style and Macros in Clojure - Jan 2012Continuation Passing Style and Macros in Clojure - Jan 2012
Continuation Passing Style and Macros in Clojure - Jan 2012
 
Functional Concepts for OOP Developers
Functional Concepts for OOP DevelopersFunctional Concepts for OOP Developers
Functional Concepts for OOP Developers
 
Clojure for Java developers - Stockholm
Clojure for Java developers - StockholmClojure for Java developers - Stockholm
Clojure for Java developers - Stockholm
 
Meta-objective Lisp @名古屋 Reject 会議
Meta-objective Lisp @名古屋 Reject 会議Meta-objective Lisp @名古屋 Reject 会議
Meta-objective Lisp @名古屋 Reject 会議
 
Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)
 
Groovy
GroovyGroovy
Groovy
 
Scala as a Declarative Language
Scala as a Declarative LanguageScala as a Declarative Language
Scala as a Declarative Language
 
Clojure Intro
Clojure IntroClojure Intro
Clojure Intro
 
Scala + WattzOn, sitting in a tree....
Scala + WattzOn, sitting in a tree....Scala + WattzOn, sitting in a tree....
Scala + WattzOn, sitting in a tree....
 
Lisp Primer Key
Lisp Primer KeyLisp Primer Key
Lisp Primer Key
 
Eta
EtaEta
Eta
 
Pune Clojure Course Outline
Pune Clojure Course OutlinePune Clojure Course Outline
Pune Clojure Course Outline
 
Modern technologies in data science
Modern technologies in data science Modern technologies in data science
Modern technologies in data science
 
Spark_Documentation_Template1
Spark_Documentation_Template1Spark_Documentation_Template1
Spark_Documentation_Template1
 
Class 16: Making Loops
Class 16: Making LoopsClass 16: Making Loops
Class 16: Making Loops
 
AutoDesk
AutoDeskAutoDesk
AutoDesk
 

Dernier

Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 

Dernier (20)

Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 

Introduction To Lisp

  • 1. Why Won’t Lisp Just Go Away? Inroducing Lisp 50 Years Young (2008)
  • 3. Effort vs Productivity (my subjective point of view) (not to scale) (this chart has no meaning, it is a joke) 100 PAIP, On Lisp, SICP 75 The segafault that made you leave C++ 50 Java Cookbook EJB3, J5EE, JMX, Me Struts, JMS, Exhausted Permgen 25 You are Here 0 Java C++ Lisp
  • 4. Overview What is Lisp? How to get started Some Basics Some Common Recipes Wet your appetite for more Not so basic things Where to go next
  • 5. What is Lisp? A Programming Language Brought to you by John McCarthy circa 1958 Resistance is Futile... Garbage Collection, Closures, Functional, Object Oriented, AOP, DSLs, Conditions and Restarts, Continuations, what else ya got?
  • 6. Welcome to the Family Common Lisp (Lisp 2) LispWorks, Alegro OpenMCL, SBCL, Clisp, ABCL and others Scheme (Lisp 1) by Sussman and Steele PLT, Chicken, Bigloo, Clojure, SISC, JScheme, and others Less Common Dylan, Qi, Termite, ECL, Arc, and others...
  • 7. Quick Start LispBox http://gigamonkeys.com/lispbox/ Windows, OS X, Linux Ready Lisp http://www.newartisans.com/software/readylisp.html OS X
  • 8. Roll your own Emacs SLIME The Superior Lisp Interaction Mode for Emacs Common Lisp SBCL, CLISP paraedit-el
  • 9. Basics Parentheses, lots and lots of parentheses Everything is an Expression Prefix Notation Lists, ‘cons’, pair Singly Linked List
  • 10. Basics: Cons Cells, Lists car (), nil, the empty list, false cdr 1 (list 1) (cons 1 nil) 1 2 (cons 1 2) 1 2 3 (list 1 2 3) (cons 1 (cons 2 (cons 3 nil)))
  • 11. Basics: Expressions (if test-p consequent otherwise) (+ 1 2 3 4 5) => 15 (let ((x 3) (y 2)) (* x y)) => 6 (expt 2 42) => 4398046511104
  • 12. Basics: Functions (defun test (n) (cond ((= n 0) (+ 1 n)) (t (- n 1)))) (funcall #'test 3) (apply #’test ‘(3)) (mapcar #'test '(-2 -1 0 1 2)) => (-3 -2 1 0 1)
  • 13. Basics: Assignment (setf x '(a b c)) => (A B C) (setf (car x) 1) => (1 B C) (setf (second x) 2) => (1 2 C)
  • 14. Numeric Tower Ints and Floats, but also... Ratios Built in Bignum Support Built in Complex Numbers
  • 15. Numeric Tower 1/2 (/ 1 3) => 1/3 (* 33333 (/ 1 33333)) => 1 (expt 2 100) => 1267650600228229401496703205376 (* #c(0 1) #c(0 1)) => -1
  • 16. Familiar Data Structures Vectors (arrays) Hash Tables (map) Structures (records) Objects - CLOS Sequence Types (and streams)
  • 17. Library System: ASDF ASDF - another system definition facility Like Ruby’s gem or Perl’s CPAN (but inscrutable) (require :asdf-install) (asdf-install:install :cl-ppcre) Repository: cliki.net
  • 18. Example: Fetch the Web (require :drakma) (use-package :drakma) (defvar content nil) (setf content (http-request quot;http://google.com/quot;)) (format t quot;len:~a~&quot; (length content)) (format t quot;~a~&quot; (subseq content 0 100))
  • 19. Example: Serve the Web (require :hunchentoot) (use-package :hunchentoot) (setq *dispatch-table* (list (create-prefix-dispatcher quot;/indexquot; 'index-page))) (defun index-page () quot;<h1>Hunchentoot Demo</h1>.quot;) (defvar server (hunchentoot:start-server :port 4242))
  • 20. Example: Process Files (require :cl-ppcre) (with-open-file (inp quot;.../input.txtquot; :direction :input) (loop for line = (read-line inp nil nil) while line do (format t quot;~a~&quot; (cl-ppcre:regex-replace quot;lis+pquot; line quot;lispquot;))))
  • 21. Example: Unit Testing (define-test test-flatten (assert-false (flatten)) (assert-false (flatten '())) (assert-equal '(a) (flatten 'a)) (assert-equal '(a) (flatten '(a))) (assert-equal '(a b c d) (flatten '(a (b (c (d)))))))
  • 22. More Interesting Stuff Macros, Reader Macros, syntax-rules Restarts “To Err is Expected, To Recover, Divine” -- David B. Lamkins Functional Programming Pattern Matching (Unification)
  • 23. What’s a Macro? A tool for Abstraction Code Generator Compiler defmacro define-macro syntax-rules
  • 24. Macro: random-if (defmacro random-if (prob consequent otherwise) `(if (< (random 1.0) ,prob)) ,consequent ,otherwise)) (random-if 1/2 (format t quot;went left~&quot;) (format t quot;went right~&quot;)
  • 25. Macro: aprog1 (defmacro aprog1 (it &rest body) `(let ((it ,it)) give the thing a name ,@body let them use it it)) return it (aprog1 (make-hash-table :test #’equal) (setf (gethash “a” it) 1) (setf (gethash “b” it) 2)) => #<HASH-TABLE :TEST EQUAL :COUNT 2 {BE49831}>
  • 26. Macro: rcut (defmacro rcut (&rest body)  (let* ((formals (list))         (new-body          (map-tree #'(lambda (elt)                        (if (symbol-equal '<> elt)                            (aprog1                             (gensym)                             (push it formals)                             it)                            elt))                    body)))    `#'(lambda ,(reverse formals)         ,@new-body))) (macroexpan-1 ‘(rcut (format “val:~a~&” <>))) => #'(LAMBDA (#:G2348) (FORMAT NIL quot;elt:~a~&quot; #:G2348))
  • 27. Restarts: Structured Recovery (defun file-size (file) (restart-case (if (not (probe-file file)) ‘throw’ (error 'file-not-found) (sb-posix:stat-size (sb-posix:stat file))) (file-not-found (new-file-size) :report quot;Specify missing size.quot; recovery :interactive read-new-value new-file-size))) (defun bytes-used (files) (loop for file in files summing (file-size file)))
  • 28. Restarts in action CL-USER> (format t quot;bytes:~a~&quot; (bytes-used '(quot;/etc/passwdquot; quot;/foo/barquot;))) Condition FILE-NOT-FOUND was signalled. [Condition of type FILE-NOT-FOUND] Restarts: 0: [FILE-NOT-FOUND] Specify missing size. 1: [ABORT] Return to SLIME's top level. 2: [TERMINATE-THREAD] Terminate this thread (#<THREAD quot;repl-threadquot; ...>) Backtrace: 0: (FILE-SIZE quot;/foo/barquot;) 1: (BYTES-USED (quot;/etc/passwdquot; quot;/foo/barquot;)) ...snip... Enter a new value: 12 bytes:2900
  • 29. More Interesting Stuff Functional Programming Functions are first class - composable list comprehensions (cl-incf) pattern-matching (cl-unification, pcond) DSLs, mini-languages
  • 30. First Class Functions (mapcar #'(lambda (x) (+ 2 x)) '(1 2 3 4)) => ‘(3 4 5 6) (defun curry (fn &rest args) #'(lambda (&rest rest) (apply fn (append args rest)))) (funcall (curry #'+ 2) 3) => 5 (mapcar (curry #'+ 2) '(1 2 3 4)) => ‘(3 4 5 6)
  • 31. First Class Functions (defun memoize (fn) (let ((cache (make-hash-table :test #'equal))) #’(lambda (&rest args) (let ((key (format nil quot;~aquot; args))) (if (gethash key cache) Return (gethash key cache) from cache (aprog1 (apply fn args) (setf (gethash key cache) it))))))) Add result to cache and return
  • 32. First Class Functions (defun myfn (a b c) (format t quot;called: a:~a b:~a c:~a~&quot; a b c) (+ a b c)) (let ((mfn (memoize #'myfn)) (args '(1 2 3)) (args2 '(4 5 6))) (format t quot;mfn ~a: ~a~&quot; args (apply mfn args)) (format t quot;mfn ~a: ~a~&quot; args (apply mfn args)) (format t quot;mfn ~a: ~a~&quot; args2 (apply mfn args2)) (format t quot;mfn ~a: ~a~&quot; args2 (apply mfn args2))) => called: a:1 b:2 c:3 not in cache mfn (1 2 3): 6 mfn (1 2 3): 6 in cache called: a:4 b:5 c:6 not in cache mfn (4 5 6): 15 mfn (4 5 6): 15 in cache
  • 33. List Comprehensions (defun lcmp-qsort (things) (cond ((null things) things) (t (destructuring-bind (pivot . tl) things (append (lcmp-qsort (assemble x (<- x tl) (< x pivot))) (list pivot) (lcmp-qsort (assemble x (<- x tl) (>= x pivot))))))))
  • 34. List Comprehensions (defun lcmp-qsort (things) (cond ((null things) things) (t (destructuring-bind (pivot . tl) things (append (lcmp-qsort (assemble x (<- x tl) (< x pivot))) (list pivot) (lcmp-qsort (assemble x (<- x tl) (>= x pivot))))))))
  • 35. List Comprehensions (defun lcmp-qsort (things) (cond ((null things) things) (t (destructuring-bind (pivot . tl) things (append (lcmp-qsort (assemble x (<- x tl) (< x pivot))) (list pivot) (lcmp-qsort (assemble x (<- x tl) (>= x pivot))))))))
  • 36. List Comprehensions (defun lcmp-qsort (things) (cond ((null things) things) (t (destructuring-bind (pivot . tl) things (append (lcmp-qsort (assemble x (<- x tl) (< x pivot))) (list pivot) (lcmp-qsort (assemble x (<- x tl) (>= x pivot))))))))
  • 37. List Comprehensions (defun lcmp-qsort (things) (cond ((null things) things) (t (destructuring-bind (pivot . tl) things (append (lcmp-qsort (assemble x (<- x tl) (< x pivot))) (list pivot) (lcmp-qsort (assemble x (<- x tl) (>= x pivot))))))))
  • 38. List Comprehensions (defun lcmp-qsort (things) (cond ((null things) things) (t (destructuring-bind (pivot . tl) things (append (lcmp-qsort (assemble x (<- x tl) (< x pivot))) (list pivot) (lcmp-qsort (assemble x (<- x tl) (>= x pivot))))))))
  • 39. List Comprehensions (defun all-permutations (things) (cond ((= 1 (length things)) (list things)) (t (assemble (cons Head Tail) (<- Head things) (<- Tail (all-permutations (remove Head things)))))))
  • 40. List Comprehensions (defun all-permutations (things) (cond ((= 1 (length things)) (list things)) (t (assemble (cons Head Tail) (<- Head things) (<- Tail (all-permutations (remove Head things)))))))
  • 41. List Comprehensions (defun all-permutations (things) (cond ((= 1 (length things)) (list things)) (t (assemble (cons Head Tail) (<- Head things) (<- Tail (all-permutations (remove Head things)))))))
  • 42. List Comprehensions (defun all-permutations (things) (cond ((= 1 (length things)) (list things)) (t (assemble (cons Head Tail) (<- Head things) (<- Tail (all-permutations (remove Head things)))))))
  • 43. List Comprehensions (defun all-permutations (things) (cond ((= 1 (length things)) (list things)) (t (assemble (cons Head Tail) (<- Head things) (<- Tail (all-permutations (remove Head things)))))))
  • 44. List Comprehensions (defun all-permutations (things) (cond ((= 1 (length things)) (list things)) (t (assemble (cons Head Tail) (<- Head things) (<- Tail (all-permutations (remove Head things)))))))
  • 45. Pattern Matching: pcond (defun ptest (names) (pcond:pcond ((and (:pat ((?first ?last) . ?rest) names) (:re quot;(.+)oquot; ?first (before-o))) (format t quot;before-o: ~a~&quot; before-o) (ptest ?rest)))) (ptest '((quot;George quot; quot;Washingtonquot;) (quot;Johnquot; quot;Adamsquot;))) => before-o: Ge => before-o: J
  • 46. DSLs, mini-languages (define-syntax aprog1 (syntax-rules (it) ((_ expression . body) (let ((it expression)) body it)))) (macroexpand '(aprog1 (list) (set! it (cons ‘a it)))) => (let ((it (list))) (set! it (cons 'a it)) it)
  • 47. DSLs, mini-languages (define m (automation init (init : (c -> more)) (more : (a -> more) (d -> more) (r -> end)) (end :)))
  • 48. DSLs, mini-languages (define-syntax automation (syntax-rules (: ->) ((_ init-state (state : (label -> target) ...) ...) (letrec ((state (lambda (stream) (cond ((empty? stream) #t) (else (case (first stream) ((label) (target (rest stream))) ... (else #f)))))) ...) init-state))))
  • 49. DSLs, mini-languages (letrec ((init (lambda (GenTemp%2) (cond ((empty? GenTemp%2) #t) (else (case (first GenTemp%2) ((c) (more (rest GenTemp%2))) (else #f)))))) (more (lambda (GenTemp%2) (cond ((empty? GenTemp%2) #t) (else (case (first GenTemp%2) ((a) (more (rest GenTemp%2))) ((d) (more (rest GenTemp%2))) ((r) (end (rest GenTemp%2))) (else #f)))))) (end (lambda (GenTemp%2) (cond ((empty? GenTemp%2) #t) (else (case (first GenTemp%2) (else #f))))))) init)
  • 50. That’s the overview http://lisperati.org/casting.html, by permission of Conrad Barski, MD
  • 51. Now where am I supposed to go? On-Line Resources Common Lisp Hyper Spec On Lisp (Paul Graham) Practical Common Lisp (Peter Siebel) Cliki.net common-lisp.net JRMs Syntax Rules Primer Casting Spells with Lisp: http://lisperati.org/casting.html http://del.icio.us/mortis/lisp
  • 52. Now where am I supposed to go? Books PAIP (Peter Norvig) Practical Common Lisp (Peter Seibel) SICP (Ableson and Sussman) Common Lisp the Language (Guy Steele) ANSI Common Lisp (Paul Graham)