SlideShare a Scribd company logo
1 of 16
Download to read offline
The Magnificent Seven
by Michael Fogus
creating a Lisp variant in seven forms


Who am I?
       Michael Fogus
       Software Programmer

       12 years experience
       Lisp, C, CLIPS, Prolog, C++, Java, Jess, Python, Scala, Clojure
       Co-author of The Joy of Clojure
       @fogus on the Intertweets


Lisp




History
       John McCarthy
1958
      Massachusetts Institute of Technology (MIT)
      IBM 704 (origin of car and cdr)
      Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I [1]

[1] http://www-formal.stanford.edu/jmc/recursive.html


Lisp Innovations
      Dynamic types
      Garbage collection
      if-then-else (via cond)
      Tree data structures
      Homoiconicity...



McCarthy's
Magnificent Seven
McCarthy's Seven
[2]


                                     Had
      car                       cdr
      cons                      cond label and lambda, dynamic scoping [3] , lists (kinda)
      atom                      eq
      quote                          Didn't Have

closures, macros, numbers

[2] paulgraham.com/rootsoflisp.html
[3] github.com/fogus/lithp


Building from parts
(label and
  (lambda (and_x and_y)
    (cond (and_x
             (cond (and_y t)
                   (t nil)))
           (t nil))))

(and t nil)
;=> nil
(and t t)
;=> t




Building from parts (continued)
(label list
  (lambda (x y)
    (cons x (cons y (quote ())))))

(def append
  (lambda (append_x append_y)
    (cond ((null append_x) append_y)
            (t (cons (car append_x)
               (append (cdr append_x) append_y))))))

(append (list 1 2) (list 3 4))
;=> (1 2 3 4)


You can see where this is going...


Meta-circular Evaluator FTW
(def eval (lambda (expr binds)
            (cond
             ((atom expr) (assoc expr    binds))
             ((atom (car expr))
              (cond
               ((eq (car expr) (quote     quote)) (cadr expr))
               ((eq (car expr) (quote     atom)) (atom    (eval (cadr expr) binds)))
               ((eq (car expr) (quote     eq))    (eq     (eval (cadr expr) binds)
                                                          (eval (caddr expr) binds)))
                  ((eq (car expr) (quote car))    (car    (eval (cadr expr) binds)))
                  ((eq (car expr) (quote cdr))    (cdr    (eval (cadr expr) binds)))
                  ((eq (car expr) (quote cons)) (cons     (eval (cadr expr) binds)
                                                          (eval (caddr expr) binds)))
                  ((eq (car expr) (quote cond)) (eval-cond (cdr expr) binds))
                  (t (eval (cons (assoc (car expr) binds)
                                 (cdr expr))
                           binds))))
                ((eq (caar expr) (quote def))
                 (eval (cons (caddar expr) (cdr expr))
                       (cons (list (cadar expr) (car expr)) binds)))
                ((eq (caar expr) (quote lambda))
                 (eval (caddar expr)
                       (append (pair (cadar expr) (eval-args (cdr expr) binds))
                               binds)))
                (t (assoc expr binds)))))

note: not all code shown


Breathtaking!
Fojure
Feajures
      7 core funcjions and 2 spejial fjorms
      Symbolj
      Lajy
      Single immutable data strucjure
      Funcjional
      Lexical Scopjure
      Closures



The Magnificent Seven
      fn
      def



No Need For car and cdr
(def CAR (fn [[h & _]] h))
(def CDR (fn [[_ & t]] t))

(CAR [1 2 3])
;=> 1

(CDR [1 2 3])
;=> (2 3)




Wait! What?!?
I never mentioned anything about vectors


No Need For cons
(def CONS
  (fn [h t]
    (fn ([] h)
        ([_] t))))

(CONS 1 (CONS 2 (CONS 3 nil)))
;=> #<user$CONS$fn__85 user$CONS$fn__85@445e228>


A closure over the head and tail
A good start...



Closure:
A Poor Man's Object


Closure Dissection
(def CONS
  (fn [h t]
    (fn ([] h)
        ([_] t))))


A closure
head
tail
A closure is an Object with a single method .apply(...)


The New first and rest
(def FIRST (fn [s] (s)))
(def REST (fn [s] (s nil)))

(def a (CONS 1 (CONS 2 (CONS 3 nil))))

(FIRST a)
;=> 1

(REST a)
;=> #<user$CONS$fn__85 user$CONS$fn__85@375e293a>

(FIRST (REST a))
;=> 2




Saplings
   1.   1 =
   2.   2 if
   3.   3 '
   4.   4 :keywords


Yet Another CONS
(def CONS
(fn [h t]
    (fn [d]
      (if (= d :type)
        'CONS
        (if (= d :head)
          h
          t)))))

(def $ (CONS 'a (CONS 'b nil)))
;=> #<user$CONS$fn__4 user$CONS$fn__4@61578aab>

($ :type)
;=> CONS

($ :head)
;=> a

(($ :tail) :head)
;=> b


Now what does this look like?


Cons Cell




Object:
A Poor Man's Closure


A Protocol for seqs
     Call with :type to inspect the seq type
           Return CONS when type is a cons cell
     Call with :head to get the head
     Call with antyhing else to get the tail


first       and rest
(def FIRST
  (fn [x]
    (if x
      (if (= (x :type) 'CONS)
        (x :head)
(if (x)
            ((x) :head))))))

(def REST
  (fn [x]
    (if x
      (if (= (x :type) 'CONS)
        (x :tail)
        (if (x)
          ((x) :tail))))))

(FIRST $)
;=> a

(REST $)
;=> #<user$CONS$fn__17 user$CONS$fn__17@2eb0a3f5>

(FIRST (REST $))
;=> b




We can do a ton with only CONS , FIRST and REST !

seq
(def SEQ
  (fn [x]
    (if x
      (if (= (x :type) 'CONS)
         x
         (if (x)
           (SEQ (x)))))))

(SEQ $)
;=> #<user$CONS$fn__97 user$CONS$fn__97@293b9fae>

(FIRST (SEQ $))
;=> a

(SEQ (REST (REST $)))
;=> nil




prn
(def PRN
  (fn [s]
    (if (SEQ s)
      (do
         (print (FIRST (SEQ s)))
         (print " ")
         (recur (REST s)))
      (println))))

(PRN $)
; a b

(PRN (CONS 'a nil))
; a


This doesn't count


append
(def APPEND
  (fn app [l r]
    (if (FIRST l)
      (CONS (FIRST l)
            (app (REST l) r))
      r)))

(PRN (APPEND (CONS 'x nil) (CONS 'y (CONS 'z nil))))
; x y z


But this is not a convenient way to deal with lists



Lists
   1. 5   apply



list
(def LIST
  (fn ls
    ([h]    (CONS h nil))
    ([h t] (CONS h (CONS t nil)))
    ([h m & [f & r]]
       (if (CAR r)
          (if (CAR (CDR r))
            (APPEND (LIST h m) (apply ls f (CAR r) (CDR r)))
            (APPEND (LIST h m) (LIST f (CAR r))))
          (CONS h (LIST m f))))))

(PRN (LIST 'a 'b 'c 'd 'e 'f))
; a b c d e f

(SEQ (REST (LIST 'a)))
;=> nil

(PRN (APPEND (LIST 'a 'b) (LIST 'x 'y)))
; a b x y


Using CAR, CDR, and destructuring as the primordial first and rest
Being Lazy
Being Lazy
TODO


Lazy seqs
Lazy seq
(def LAZY-SEQ
  (fn [f]
    (fn
      ([x]
          (if (= x :type)
            'LAZY-SEQ))
      ([] (f)))))

(FIRST ((LAZY-SEQ (fn [] (LIST 'a 'b 'c)))))
;=> a

(PRN ((LAZY-SEQ (fn [] (LIST 'a 'b 'c)))))
; a b c


Now we have a protocol for lazy seqs


A Protocol for lazy seqs
     Wrap the part that you want to be lazy in a fn
     Pass that fn to LAZY-SEQ
     Conform to the semantics of :type
     Deal with the extra level of indirection when dealing with lazy seqs


map
(def MAP
  (fn [f s]
    (LAZY-SEQ
      (fn []
         (if (SEQ s)
           (CONS (f (FIRST s))
                 (MAP f (REST s))))))))

(PRN (MAP keyword (LIST 'a 'b 'c)))
; :a :b :c
(PRN (MAP LIST (LIST 'a 'b)))
; #<user$CONS$fn__356 user$CONS$fn__356@54cb2185> ...

(PRN (FIRST (MAP LIST (LIST 'a 'b))))
; a




Control Structures
      6 defmacro
      7 `


let
(let [a 1]
  (let [b 2]
    (println [a b]))
  (println [a b]))

; java.lang.Exception: Unable to resolve symbol: b in this context


Defines a scope for named values


LET
(defmacro LET [[bind val] & body]
  `((fn [~bind]
      ~@body)
    ~val))

(LET (a 1)
  (LET (b 2)
    (println [a b])))


produces...
((fn [a]
    ((fn [b]
       (println [a b]))
     2))
 1)


more or less


More LET
(FIRST
  (LET (x 'a)
    (CONS x nil)))

;=> a

(PRN
 (LET (x 'x)
   (LET (y 'y)
     (CONS x (CONS y $)))))

; x y a b




And the rest is mechanical

but...

We didn't need keywords...
Symbols would have worked just as well
(def CONS
  (fn [a b]
    (fn
      ([x]
          (if (= x 'lazy)
            'CONS
            (if (= x 'head)
              a
              b))))))

(def $$ (CONS 'a (CONS 'b nil)))

($$ 'head)
;=> a

($$ 'tail)
;=> #<user$CONS$fn__91 user$CONS$fn__91@58e22f2b>




The Magnificent 6
= if ' :keywords apply defmacro `
and...

We didn't need apply...
defmacro         gives us that for free
(defmacro APPLY [f args]
  `(~f ~@args))

(APPLY + [1 2 3 4])
;=> 10

(PRN (APPLY LIST '[a b c d e]))
; a b c d e




The Magnificent 5
= if ' :keywords apply defmacro `




and...

We didn't need defmacro and `...
why not?
Meta-circular Evaluator FTW
(def EVAL (fn (expr binds)
            (COND
             ((ATOM expr) (ASSOC expr binds))
             ((ATOM (FIRST expr))
              (COND
               ((= (FIRST expr) 'quote) (SECOND expr))
               ((= (FIRST expr) 'ATOM) (ATOM      (EVAL (SECOND expr) binds)))
               ((= (FIRST expr) '=)     (=        (EVAL (SECOND expr) binds)
                                                  (EVAL (THIRD expr) binds)))
               ((= (FIRST expr) 'FIRST) (FIRST    (EVAL (SECOND expr) binds)))
               ((= (FIRST expr) 'REST) (REST      (EVAL (SECOND expr) binds)))
               ((= (FIRST expr) 'CONS) (CONS      (EVAL (SECOND expr) binds)
                                                  (EVAL (THIRD expr) binds)))
               ((= (FIRST expr) 'COND) (EVAL-COND (REST expr) binds))
               ('true (EVAL (CONS (ASSOC (FIRST expr) binds)
                              (REST expr))
                        binds))))
             ((= (CAAR expr) 'def)
              (EVAL (CONS (CADDAR expr) (REST expr))
                    (CONS (LIST (CADAR expr) (FIRST expr)) binds)))
             ((= (CAAR expr) 'fn)
              (EVAL (CADDAR expr)
(APPEND (PAIR (CADAR expr) (EVAL-ARGS (REST expr) binds))
                              binds)))
               ('true (ASSOC expr binds)))))

note: not all code shown



The Magnificent 3
= if ' :keywords apply defmacro `




The Magnificent 3!?!

Our Options
deftype defprotocol reify intern . defmulti defmethod defrecord first rest [] ^ {}
 delay force new defclass proxy list* fn* fn? seq clojure.lang.RT

and so on...



The Garden of Forking Paths
Thank You




http://joyofclojure.com

More Related Content

What's hot

Better Software: introduction to good code
Better Software: introduction to good codeBetter Software: introduction to good code
Better Software: introduction to good codeGiordano Scalzo
 
Functional Programming & Event Sourcing - a pair made in heaven
Functional Programming & Event Sourcing - a pair made in heavenFunctional Programming & Event Sourcing - a pair made in heaven
Functional Programming & Event Sourcing - a pair made in heavenPawel Szulc
 
Code as data as code.
Code as data as code.Code as data as code.
Code as data as code.Mike Fogus
 
betterCode() Go: Einstieg in Go, Standard-Library und Ökosystem
betterCode() Go: Einstieg in Go, Standard-Library und ÖkosystembetterCode() Go: Einstieg in Go, Standard-Library und Ökosystem
betterCode() Go: Einstieg in Go, Standard-Library und ÖkosystemJan Stamer
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)Pavlo Baron
 
JavaForum Nord 2021: Java to Go - Google Go für Java-Entwickler
JavaForum Nord 2021: Java to Go - Google Go für Java-EntwicklerJavaForum Nord 2021: Java to Go - Google Go für Java-Entwickler
JavaForum Nord 2021: Java to Go - Google Go für Java-EntwicklerJan Stamer
 
Advanced python
Advanced pythonAdvanced python
Advanced pythonEU Edge
 
そうだ、bf処理系作ろう!もちろんSQLで!
そうだ、bf処理系作ろう!もちろんSQLで!そうだ、bf処理系作ろう!もちろんSQLで!
そうだ、bf処理系作ろう!もちろんSQLで!bleis tift
 
Hacking parse.y (RubyKansai38)
Hacking parse.y (RubyKansai38)Hacking parse.y (RubyKansai38)
Hacking parse.y (RubyKansai38)ujihisa
 
The Macronomicon
The MacronomiconThe Macronomicon
The MacronomiconMike Fogus
 
Basic C++ 11/14 for Python Programmers
Basic C++ 11/14 for Python ProgrammersBasic C++ 11/14 for Python Programmers
Basic C++ 11/14 for Python ProgrammersAppier
 
ES6 - Next Generation Javascript
ES6 - Next Generation JavascriptES6 - Next Generation Javascript
ES6 - Next Generation JavascriptRamesh Nair
 
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)(map Clojure everyday-tasks)
(map Clojure everyday-tasks)Jacek Laskowski
 
Game unleashedjavascript
Game unleashedjavascriptGame unleashedjavascript
Game unleashedjavascriptReece Carlson
 
Clojure made simple - Lightning talk
Clojure made simple - Lightning talkClojure made simple - Lightning talk
Clojure made simple - Lightning talkJohn Stevenson
 
JavaOne 2013 - Clojure for Java Developers
JavaOne 2013 - Clojure for Java DevelopersJavaOne 2013 - Clojure for Java Developers
JavaOne 2013 - Clojure for Java DevelopersJan Kronquist
 
Clojure for Java developers - Stockholm
Clojure for Java developers - StockholmClojure for Java developers - Stockholm
Clojure for Java developers - StockholmJan Kronquist
 

What's hot (20)

Better Software: introduction to good code
Better Software: introduction to good codeBetter Software: introduction to good code
Better Software: introduction to good code
 
Functional Programming & Event Sourcing - a pair made in heaven
Functional Programming & Event Sourcing - a pair made in heavenFunctional Programming & Event Sourcing - a pair made in heaven
Functional Programming & Event Sourcing - a pair made in heaven
 
Code as data as code.
Code as data as code.Code as data as code.
Code as data as code.
 
betterCode() Go: Einstieg in Go, Standard-Library und Ökosystem
betterCode() Go: Einstieg in Go, Standard-Library und ÖkosystembetterCode() Go: Einstieg in Go, Standard-Library und Ökosystem
betterCode() Go: Einstieg in Go, Standard-Library und Ökosystem
 
Groovy!
Groovy!Groovy!
Groovy!
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)
 
JavaForum Nord 2021: Java to Go - Google Go für Java-Entwickler
JavaForum Nord 2021: Java to Go - Google Go für Java-EntwicklerJavaForum Nord 2021: Java to Go - Google Go für Java-Entwickler
JavaForum Nord 2021: Java to Go - Google Go für Java-Entwickler
 
Advanced python
Advanced pythonAdvanced python
Advanced python
 
そうだ、bf処理系作ろう!もちろんSQLで!
そうだ、bf処理系作ろう!もちろんSQLで!そうだ、bf処理系作ろう!もちろんSQLで!
そうだ、bf処理系作ろう!もちろんSQLで!
 
Hacking parse.y (RubyKansai38)
Hacking parse.y (RubyKansai38)Hacking parse.y (RubyKansai38)
Hacking parse.y (RubyKansai38)
 
The Macronomicon
The MacronomiconThe Macronomicon
The Macronomicon
 
Basic C++ 11/14 for Python Programmers
Basic C++ 11/14 for Python ProgrammersBasic C++ 11/14 for Python Programmers
Basic C++ 11/14 for Python Programmers
 
ES6 - Next Generation Javascript
ES6 - Next Generation JavascriptES6 - Next Generation Javascript
ES6 - Next Generation Javascript
 
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
 
Game unleashedjavascript
Game unleashedjavascriptGame unleashedjavascript
Game unleashedjavascript
 
Sdl Basic
Sdl BasicSdl Basic
Sdl Basic
 
Clojure made simple - Lightning talk
Clojure made simple - Lightning talkClojure made simple - Lightning talk
Clojure made simple - Lightning talk
 
JavaOne 2013 - Clojure for Java Developers
JavaOne 2013 - Clojure for Java DevelopersJavaOne 2013 - Clojure for Java Developers
JavaOne 2013 - Clojure for Java Developers
 
groovy & grails - lecture 3
groovy & grails - lecture 3groovy & grails - lecture 3
groovy & grails - lecture 3
 
Clojure for Java developers - Stockholm
Clojure for Java developers - StockholmClojure for Java developers - Stockholm
Clojure for Java developers - Stockholm
 

Viewers also liked

tools and machines
tools and machinestools and machines
tools and machinesTy
 
Independencia judicial
Independencia judicialIndependencia judicial
Independencia judicialeric prado
 
Powerpoint For Linked In
Powerpoint For Linked InPowerpoint For Linked In
Powerpoint For Linked Incyndilevy
 

Viewers also liked (7)

Morner - What You See Is What You Get
Morner - What You See Is What You GetMorner - What You See Is What You Get
Morner - What You See Is What You Get
 
Magazine Ad
Magazine AdMagazine Ad
Magazine Ad
 
Launch Promo
Launch PromoLaunch Promo
Launch Promo
 
Why Scala?
Why Scala?Why Scala?
Why Scala?
 
tools and machines
tools and machinestools and machines
tools and machines
 
Independencia judicial
Independencia judicialIndependencia judicial
Independencia judicial
 
Powerpoint For Linked In
Powerpoint For Linked InPowerpoint For Linked In
Powerpoint For Linked In
 

Similar to The Magnificent Seven

Introduction To Lisp
Introduction To LispIntroduction To Lisp
Introduction To Lispkyleburton
 
CL metaprogramming
CL metaprogrammingCL metaprogramming
CL metaprogrammingdudarev
 
Recursion and Functional Programming
Recursion and Functional ProgrammingRecursion and Functional Programming
Recursion and Functional Programmingsathish316
 
Microsoft Word Practice Exercise Set 2
Microsoft Word   Practice Exercise Set 2Microsoft Word   Practice Exercise Set 2
Microsoft Word Practice Exercise Set 2rampan
 
(first '(Clojure.))
(first '(Clojure.))(first '(Clojure.))
(first '(Clojure.))niklal
 
Monadologie
MonadologieMonadologie
Monadologieleague
 
Parametricity - #cljsyd - May, 2015
Parametricity - #cljsyd - May, 2015Parametricity - #cljsyd - May, 2015
Parametricity - #cljsyd - May, 2015Leonardo Borges
 
ANSI C REFERENCE CARD
ANSI C REFERENCE CARDANSI C REFERENCE CARD
ANSI C REFERENCE CARDTia Ricci
 
Class 11: Deeper List Procedures
Class 11: Deeper List ProceduresClass 11: Deeper List Procedures
Class 11: Deeper List ProceduresDavid Evans
 
Programming Lisp Clojure - 2장 : 클로저 둘러보기
Programming Lisp Clojure - 2장 : 클로저 둘러보기Programming Lisp Clojure - 2장 : 클로저 둘러보기
Programming Lisp Clojure - 2장 : 클로저 둘러보기JangHyuk You
 
Super Advanced Python –act1
Super Advanced Python –act1Super Advanced Python –act1
Super Advanced Python –act1Ke Wei Louis
 
Groovy puzzlers по русски с Joker 2014
Groovy puzzlers по русски с Joker 2014Groovy puzzlers по русски с Joker 2014
Groovy puzzlers по русски с Joker 2014Baruch Sadogursky
 
Class 31: Deanonymizing
Class 31: DeanonymizingClass 31: Deanonymizing
Class 31: DeanonymizingDavid Evans
 
Clojure Intro
Clojure IntroClojure Intro
Clojure Introthnetos
 
Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meetMario Fusco
 
Transducers in JavaScript
Transducers in JavaScriptTransducers in JavaScript
Transducers in JavaScriptPavel Forkert
 

Similar to The Magnificent Seven (20)

Introduction To Lisp
Introduction To LispIntroduction To Lisp
Introduction To Lisp
 
CL metaprogramming
CL metaprogrammingCL metaprogramming
CL metaprogramming
 
Recursion and Functional Programming
Recursion and Functional ProgrammingRecursion and Functional Programming
Recursion and Functional Programming
 
Term Rewriting
Term RewritingTerm Rewriting
Term Rewriting
 
Microsoft Word Practice Exercise Set 2
Microsoft Word   Practice Exercise Set 2Microsoft Word   Practice Exercise Set 2
Microsoft Word Practice Exercise Set 2
 
(first '(Clojure.))
(first '(Clojure.))(first '(Clojure.))
(first '(Clojure.))
 
Monadologie
MonadologieMonadologie
Monadologie
 
Ecma script 5
Ecma script 5Ecma script 5
Ecma script 5
 
Oh Composable World!
Oh Composable World!Oh Composable World!
Oh Composable World!
 
Parametricity - #cljsyd - May, 2015
Parametricity - #cljsyd - May, 2015Parametricity - #cljsyd - May, 2015
Parametricity - #cljsyd - May, 2015
 
ANSI C REFERENCE CARD
ANSI C REFERENCE CARDANSI C REFERENCE CARD
ANSI C REFERENCE CARD
 
Class 11: Deeper List Procedures
Class 11: Deeper List ProceduresClass 11: Deeper List Procedures
Class 11: Deeper List Procedures
 
Lisp
LispLisp
Lisp
 
Programming Lisp Clojure - 2장 : 클로저 둘러보기
Programming Lisp Clojure - 2장 : 클로저 둘러보기Programming Lisp Clojure - 2장 : 클로저 둘러보기
Programming Lisp Clojure - 2장 : 클로저 둘러보기
 
Super Advanced Python –act1
Super Advanced Python –act1Super Advanced Python –act1
Super Advanced Python –act1
 
Groovy puzzlers по русски с Joker 2014
Groovy puzzlers по русски с Joker 2014Groovy puzzlers по русски с Joker 2014
Groovy puzzlers по русски с Joker 2014
 
Class 31: Deanonymizing
Class 31: DeanonymizingClass 31: Deanonymizing
Class 31: Deanonymizing
 
Clojure Intro
Clojure IntroClojure Intro
Clojure Intro
 
Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meet
 
Transducers in JavaScript
Transducers in JavaScriptTransducers in JavaScript
Transducers in JavaScript
 

More from Mike Fogus

Introduction to Zeder - a production rules toolkit for Clojure
Introduction to Zeder - a production rules toolkit for ClojureIntroduction to Zeder - a production rules toolkit for Clojure
Introduction to Zeder - a production rules toolkit for ClojureMike Fogus
 
The Shape of Functional Programming
The Shape of Functional ProgrammingThe Shape of Functional Programming
The Shape of Functional ProgrammingMike Fogus
 
ClojureScript Anatomy
ClojureScript AnatomyClojureScript Anatomy
ClojureScript AnatomyMike Fogus
 
The Return of the Living Datalog
The Return of the Living DatalogThe Return of the Living Datalog
The Return of the Living DatalogMike Fogus
 
Fertile Ground: The Roots of Clojure
Fertile Ground: The Roots of ClojureFertile Ground: The Roots of Clojure
Fertile Ground: The Roots of ClojureMike Fogus
 

More from Mike Fogus (6)

Introduction to Zeder - a production rules toolkit for Clojure
Introduction to Zeder - a production rules toolkit for ClojureIntroduction to Zeder - a production rules toolkit for Clojure
Introduction to Zeder - a production rules toolkit for Clojure
 
The Shape of Functional Programming
The Shape of Functional ProgrammingThe Shape of Functional Programming
The Shape of Functional Programming
 
Confo
ConfoConfo
Confo
 
ClojureScript Anatomy
ClojureScript AnatomyClojureScript Anatomy
ClojureScript Anatomy
 
The Return of the Living Datalog
The Return of the Living DatalogThe Return of the Living Datalog
The Return of the Living Datalog
 
Fertile Ground: The Roots of Clojure
Fertile Ground: The Roots of ClojureFertile Ground: The Roots of Clojure
Fertile Ground: The Roots of Clojure
 

Recently uploaded

Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Evaluating the top large language models.pdf
Evaluating the top large language models.pdfEvaluating the top large language models.pdf
Evaluating the top large language models.pdfChristopherTHyatt
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 

Recently uploaded (20)

Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Evaluating the top large language models.pdf
Evaluating the top large language models.pdfEvaluating the top large language models.pdf
Evaluating the top large language models.pdf
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 

The Magnificent Seven

  • 1. The Magnificent Seven by Michael Fogus creating a Lisp variant in seven forms Who am I? Michael Fogus Software Programmer 12 years experience Lisp, C, CLIPS, Prolog, C++, Java, Jess, Python, Scala, Clojure Co-author of The Joy of Clojure @fogus on the Intertweets Lisp History John McCarthy
  • 2. 1958 Massachusetts Institute of Technology (MIT) IBM 704 (origin of car and cdr) Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I [1] [1] http://www-formal.stanford.edu/jmc/recursive.html Lisp Innovations Dynamic types Garbage collection if-then-else (via cond) Tree data structures Homoiconicity... McCarthy's Magnificent Seven McCarthy's Seven [2] Had car cdr cons cond label and lambda, dynamic scoping [3] , lists (kinda) atom eq quote Didn't Have closures, macros, numbers [2] paulgraham.com/rootsoflisp.html [3] github.com/fogus/lithp Building from parts (label and (lambda (and_x and_y) (cond (and_x (cond (and_y t) (t nil))) (t nil)))) (and t nil) ;=> nil
  • 3. (and t t) ;=> t Building from parts (continued) (label list (lambda (x y) (cons x (cons y (quote ()))))) (def append (lambda (append_x append_y) (cond ((null append_x) append_y) (t (cons (car append_x) (append (cdr append_x) append_y)))))) (append (list 1 2) (list 3 4)) ;=> (1 2 3 4) You can see where this is going... Meta-circular Evaluator FTW (def eval (lambda (expr binds) (cond ((atom expr) (assoc expr binds)) ((atom (car expr)) (cond ((eq (car expr) (quote quote)) (cadr expr)) ((eq (car expr) (quote atom)) (atom (eval (cadr expr) binds))) ((eq (car expr) (quote eq)) (eq (eval (cadr expr) binds) (eval (caddr expr) binds))) ((eq (car expr) (quote car)) (car (eval (cadr expr) binds))) ((eq (car expr) (quote cdr)) (cdr (eval (cadr expr) binds))) ((eq (car expr) (quote cons)) (cons (eval (cadr expr) binds) (eval (caddr expr) binds))) ((eq (car expr) (quote cond)) (eval-cond (cdr expr) binds)) (t (eval (cons (assoc (car expr) binds) (cdr expr)) binds)))) ((eq (caar expr) (quote def)) (eval (cons (caddar expr) (cdr expr)) (cons (list (cadar expr) (car expr)) binds))) ((eq (caar expr) (quote lambda)) (eval (caddar expr) (append (pair (cadar expr) (eval-args (cdr expr) binds)) binds))) (t (assoc expr binds))))) note: not all code shown Breathtaking!
  • 5. Feajures 7 core funcjions and 2 spejial fjorms Symbolj Lajy Single immutable data strucjure Funcjional Lexical Scopjure Closures The Magnificent Seven fn def No Need For car and cdr (def CAR (fn [[h & _]] h)) (def CDR (fn [[_ & t]] t)) (CAR [1 2 3]) ;=> 1 (CDR [1 2 3]) ;=> (2 3) Wait! What?!? I never mentioned anything about vectors No Need For cons (def CONS (fn [h t] (fn ([] h) ([_] t)))) (CONS 1 (CONS 2 (CONS 3 nil))) ;=> #<user$CONS$fn__85 user$CONS$fn__85@445e228> A closure over the head and tail
  • 6. A good start... Closure: A Poor Man's Object Closure Dissection (def CONS (fn [h t] (fn ([] h) ([_] t)))) A closure head tail A closure is an Object with a single method .apply(...) The New first and rest (def FIRST (fn [s] (s))) (def REST (fn [s] (s nil))) (def a (CONS 1 (CONS 2 (CONS 3 nil)))) (FIRST a) ;=> 1 (REST a) ;=> #<user$CONS$fn__85 user$CONS$fn__85@375e293a> (FIRST (REST a)) ;=> 2 Saplings 1. 1 = 2. 2 if 3. 3 ' 4. 4 :keywords Yet Another CONS (def CONS
  • 7. (fn [h t] (fn [d] (if (= d :type) 'CONS (if (= d :head) h t))))) (def $ (CONS 'a (CONS 'b nil))) ;=> #<user$CONS$fn__4 user$CONS$fn__4@61578aab> ($ :type) ;=> CONS ($ :head) ;=> a (($ :tail) :head) ;=> b Now what does this look like? Cons Cell Object: A Poor Man's Closure A Protocol for seqs Call with :type to inspect the seq type Return CONS when type is a cons cell Call with :head to get the head Call with antyhing else to get the tail first and rest (def FIRST (fn [x] (if x (if (= (x :type) 'CONS) (x :head)
  • 8. (if (x) ((x) :head)))))) (def REST (fn [x] (if x (if (= (x :type) 'CONS) (x :tail) (if (x) ((x) :tail)))))) (FIRST $) ;=> a (REST $) ;=> #<user$CONS$fn__17 user$CONS$fn__17@2eb0a3f5> (FIRST (REST $)) ;=> b We can do a ton with only CONS , FIRST and REST ! seq (def SEQ (fn [x] (if x (if (= (x :type) 'CONS) x (if (x) (SEQ (x))))))) (SEQ $) ;=> #<user$CONS$fn__97 user$CONS$fn__97@293b9fae> (FIRST (SEQ $)) ;=> a (SEQ (REST (REST $))) ;=> nil prn (def PRN (fn [s] (if (SEQ s) (do (print (FIRST (SEQ s))) (print " ") (recur (REST s))) (println)))) (PRN $)
  • 9. ; a b (PRN (CONS 'a nil)) ; a This doesn't count append (def APPEND (fn app [l r] (if (FIRST l) (CONS (FIRST l) (app (REST l) r)) r))) (PRN (APPEND (CONS 'x nil) (CONS 'y (CONS 'z nil)))) ; x y z But this is not a convenient way to deal with lists Lists 1. 5 apply list (def LIST (fn ls ([h] (CONS h nil)) ([h t] (CONS h (CONS t nil))) ([h m & [f & r]] (if (CAR r) (if (CAR (CDR r)) (APPEND (LIST h m) (apply ls f (CAR r) (CDR r))) (APPEND (LIST h m) (LIST f (CAR r)))) (CONS h (LIST m f)))))) (PRN (LIST 'a 'b 'c 'd 'e 'f)) ; a b c d e f (SEQ (REST (LIST 'a))) ;=> nil (PRN (APPEND (LIST 'a 'b) (LIST 'x 'y))) ; a b x y Using CAR, CDR, and destructuring as the primordial first and rest
  • 10. Being Lazy Being Lazy TODO Lazy seqs Lazy seq (def LAZY-SEQ (fn [f] (fn ([x] (if (= x :type) 'LAZY-SEQ)) ([] (f))))) (FIRST ((LAZY-SEQ (fn [] (LIST 'a 'b 'c))))) ;=> a (PRN ((LAZY-SEQ (fn [] (LIST 'a 'b 'c))))) ; a b c Now we have a protocol for lazy seqs A Protocol for lazy seqs Wrap the part that you want to be lazy in a fn Pass that fn to LAZY-SEQ Conform to the semantics of :type Deal with the extra level of indirection when dealing with lazy seqs map (def MAP (fn [f s] (LAZY-SEQ (fn [] (if (SEQ s) (CONS (f (FIRST s)) (MAP f (REST s)))))))) (PRN (MAP keyword (LIST 'a 'b 'c))) ; :a :b :c
  • 11. (PRN (MAP LIST (LIST 'a 'b))) ; #<user$CONS$fn__356 user$CONS$fn__356@54cb2185> ... (PRN (FIRST (MAP LIST (LIST 'a 'b)))) ; a Control Structures 6 defmacro 7 ` let (let [a 1] (let [b 2] (println [a b])) (println [a b])) ; java.lang.Exception: Unable to resolve symbol: b in this context Defines a scope for named values LET (defmacro LET [[bind val] & body] `((fn [~bind] ~@body) ~val)) (LET (a 1) (LET (b 2) (println [a b]))) produces... ((fn [a] ((fn [b] (println [a b])) 2)) 1) more or less More LET
  • 12. (FIRST (LET (x 'a) (CONS x nil))) ;=> a (PRN (LET (x 'x) (LET (y 'y) (CONS x (CONS y $))))) ; x y a b And the rest is mechanical but... We didn't need keywords... Symbols would have worked just as well (def CONS (fn [a b] (fn ([x] (if (= x 'lazy) 'CONS (if (= x 'head) a b)))))) (def $$ (CONS 'a (CONS 'b nil))) ($$ 'head) ;=> a ($$ 'tail) ;=> #<user$CONS$fn__91 user$CONS$fn__91@58e22f2b> The Magnificent 6 = if ' :keywords apply defmacro `
  • 13. and... We didn't need apply... defmacro gives us that for free (defmacro APPLY [f args] `(~f ~@args)) (APPLY + [1 2 3 4]) ;=> 10 (PRN (APPLY LIST '[a b c d e])) ; a b c d e The Magnificent 5 = if ' :keywords apply defmacro ` and... We didn't need defmacro and `... why not?
  • 14. Meta-circular Evaluator FTW (def EVAL (fn (expr binds) (COND ((ATOM expr) (ASSOC expr binds)) ((ATOM (FIRST expr)) (COND ((= (FIRST expr) 'quote) (SECOND expr)) ((= (FIRST expr) 'ATOM) (ATOM (EVAL (SECOND expr) binds))) ((= (FIRST expr) '=) (= (EVAL (SECOND expr) binds) (EVAL (THIRD expr) binds))) ((= (FIRST expr) 'FIRST) (FIRST (EVAL (SECOND expr) binds))) ((= (FIRST expr) 'REST) (REST (EVAL (SECOND expr) binds))) ((= (FIRST expr) 'CONS) (CONS (EVAL (SECOND expr) binds) (EVAL (THIRD expr) binds))) ((= (FIRST expr) 'COND) (EVAL-COND (REST expr) binds)) ('true (EVAL (CONS (ASSOC (FIRST expr) binds) (REST expr)) binds)))) ((= (CAAR expr) 'def) (EVAL (CONS (CADDAR expr) (REST expr)) (CONS (LIST (CADAR expr) (FIRST expr)) binds))) ((= (CAAR expr) 'fn) (EVAL (CADDAR expr)
  • 15. (APPEND (PAIR (CADAR expr) (EVAL-ARGS (REST expr) binds)) binds))) ('true (ASSOC expr binds))))) note: not all code shown The Magnificent 3 = if ' :keywords apply defmacro ` The Magnificent 3!?! Our Options deftype defprotocol reify intern . defmulti defmethod defrecord first rest [] ^ {} delay force new defclass proxy list* fn* fn? seq clojure.lang.RT and so on... The Garden of Forking Paths