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
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 \"http://google.com/\"))
(format t \"len:~a~&\" (length content))
(format t \"~a~&\" (subseq content 0 100))
Example: Serve the Web
(require :hunchentoot)
(use-package :hunchentoot)
(setq *dispatch-table*
(list
(create-prefix-dispatcher
\"/index\" 'index-page)))
(defun index-page ()
\"<h1>Hunchentoot Demo</h1>.\")
(defvar server
(hunchentoot:start-server :port 4242))
Example: Process Files
(require :cl-ppcre)
(with-open-file (inp \".../input.txt\" :direction :input)
(loop for line = (read-line inp nil nil)
while line
do
(format t \"~a~&\"
(cl-ppcre:regex-replace \"lis+p\" line \"lisp\"))))
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: 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}>
Restarts in action
CL-USER> (format t \"bytes:~a~&\" (bytes-used '(\"/etc/passwd\" \"/foo/bar\")))
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 \"repl-thread\" ...>)
Backtrace:
0: (FILE-SIZE \"/foo/bar\")
1: (BYTES-USED (\"/etc/passwd\" \"/foo/bar\"))
...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
(defun memoize (fn)
(let ((cache (make-hash-table :test #'equal)))
#’(lambda (&rest args)
(let ((key (format nil \"~a\" 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 \"called: a:~a b:~a c:~a~&\" a b c)
(+ a b c))
(let ((mfn (memoize #'myfn))
(args '(1 2 3))
(args2 '(4 5 6)))
(format t \"mfn ~a: ~a~&\" args (apply mfn args))
(format t \"mfn ~a: ~a~&\" args (apply mfn args))
(format t \"mfn ~a: ~a~&\" args2 (apply mfn args2))
(format t \"mfn ~a: ~a~&\" 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)))))))
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)
Introduction to Lisp. A survey of lisp's history, more
Introduction to Lisp. A survey of lisp's history, current incarnations and advanced features such as list comprehensions, macros and domain-specific-language [DSL] support. less
0 comments
Post a comment