SlideShare a Scribd company logo
1 of 28
Download to read offline
Write Your Own Lisp in Clojure
Learn Lisp by making a Lisp
1
An Interpreter
2
Demo
3
Meta-circular evaluator
4
Eval
5
Apply
(defn form-apply [proc args]
(letfn [(primitive? [p] (= (first p) 'primitive))
(procedure? [p] (= (first p) 'procedure)) ;<-- from lambda
(proc-params [p] (second p))
(proc-body [p] (nth p 2))
(proc-env [p] (nth p 3))]
(cond (primitive? proc) (apply (second proc) args) ;<-- magic
(procedure? proc) (eval-seq (proc-body proc)
(extend-env (proc-env proc)
(proc-params proc)
args)))))
6
Primitive expressions
true, 123, "words" nil
var, my-fn
(defn form-eval [exp env]
(cond (self-evaluating? exp) exp
(symbol? exp) (env-get exp env)
(defn self-evaluating? [x]
(or (number? x)
(string? x)
(nil? x)
(boolean? x)))
7
Enviroment
8
Enviroment
(defn env-find [var env action not-found] ...)
(defn env-get [var env] ...)
(defn env-set [var val env] ...)
(defn extend-env [env] ...)
9
Initial Enviroment
(defn setup-env []
(-> '()
(extend-env (keys primitive-procs)
(map #(list 'primitive %) (vals primitive-procs)))
(extend-env)
(built-in!)
(extend-env)))
(def primitive-procs {'true true
'+ +
'car first
...})
primitive-procs
10
quote
(quote 1) => 1
(quote a) => a
(quote (+ 1 1)) => (+ 1 1)
(defn form-eval [exp env]
(cond (self-evaluating? exp) exp
(symbol? exp) (env-get exp env)
(= (first exp) 'quote) (second exp)) ;;<- here
11
if
(if <cond-expr> expr else-expr)
(defn form-eval [exp env]
(let [exp (macroexpand exp env)]
(cond (self-evaluating? exp) exp
(symbol? exp) (env-get exp env)
(= (first exp) 'quote) (second exp)
(= (first exp) 'if) (eval-if exp env)))) ; <- here
(defn eval-if [exp env]
(let [[a0 a1 a2 a3] exp]
(if (form-eval a1 env)
(form-eval a2 env)
(form-eval a3 env))))
12
Why is "if" a special form?
Can we just write a if function?
(defn iif [condition stat else]
(if (true? condition)
expr
else-expr))
(iif true (+ 1 2) (* 0 0)) ;=> 3
(iif false (+ 1 2) (* 0 0)) ;=> 0
(iif true (+ 1 2) (/ 0 0)) ;=> Error: ArithmeticException Divide by zero
13
begin
(begin expr1 expr2 ...)
like "do" in clojure
(defn form-eval [exp env]
(cond (self-evaluating? exp) exp
(symbol? exp) (env-get exp env)
(= (first exp) 'quote) (second exp)
(= (first exp) 'if) (eval-if exp env)
(= (first exp) 'begin) (eval-seq (rest exp) env))) ; <-- here
(defn eval-seq [exp env]
(reduce #(form-eval %2 env) nil exp))
14
lambda
(lambda (x y) (+ x y))
(lambda () 5)
(defn form-eval [exp env]
(cond (self-evaluating? exp) exp
; ...
(= (first exp) 'lambda) (eval-lambda exp env)))) ;<- here
(defn eval-lambda [exp env]
(list 'procedure ;<-- this is for form-apply
(second exp)
(drop 2 exp)
env))
15
define
(define x 1)
(define (f x y) (+ x y))
(define f (lambda (x y) (+ x y)))
(defn form-eval [exp env]
(let [exp (macroexpand exp env)]
(cond (self-evaluating? exp) exp
; ...
(= (first exp) 'define) (eval-define exp env)))) ;<-- here
16
eval-define
(defn define-var [exp]
(if (seq? (second exp)) ;function?
(first (second exp)) ;it's a function so the var is function name
(second exp)))
(defn define-val [exp env]
(let [var (second exp)
make-lambda #(cons 'lambda (cons %1 %2))]
(if (seq? var) ;function?
(form-eval (make-lambda (rest var) (drop 2 exp)) env)
(form-eval (nth exp 2) env))))
(defn eval-define [exp env]
(let [var (define-var exp)
val (define-val exp env)]
(swap! (first env) assoc var val))) 17
set!
(define x 5)
(set! x 10)
(defn form-eval [exp env]
(cond (self-evaluating? exp) exp
;...
(= (first exp) 'set!) (eval-assignment exp env))) ;<-- here
(defn eval-assignment [exp env]
(let [[op var val] exp]
(env-set var val env)))
18
let*
(let* ((var val) ...) body)
(defn form-eval [exp env]
(cond (self-evaluating? exp) exp
;...
(= (first exp) 'let*) (eval-let* exp env))) ;<--here
(defn eval-let* [exp env]
(let [eenv (extend-env env)
[op vars body] exp]
(doseq [[b e] vars]
(swap! (first eenv) assoc b (form-eval e eenv)))
(form-eval body eenv)))
19
defmacro
(defmacro binding (lambda (args) body))
(defn form-eval [exp env]
(cond (self-evaluating? exp) exp
;...
(= (first exp) 'defmacro) (eval-defmacro exp env))); <-here
(defn eval-defmacro [exp env]
(let [[a0 a1 a2] exp
mbody (with-meta (form-eval a2 env) {:ismacro true})]
(swap! (first env) assoc a1 mbody)
"ok"))
20
macroexpand
(defn form-eval [exp env]
(let [exp (macroexpand exp env)] ;<--here
(cond (self-evaluating? exp) exp
(= (first exp) 'macroexpand) (macroexpand (second exp) env)))) ;<-- here
(defn macroexpand [exp env]
(loop [exp exp]
(if (is-macro-call exp env)
(let [mac (env-get (first exp) env)]
(recur (form-apply mac (rest exp))))
exp)))
21
macroexpand (cont.)
(defn is-macro-call [exp env]
(and (seq? exp)
(symbol? (first exp))
(env-find (first exp)
env
#(:ismacro (meta (get @% (first exp))))
#(identity false))))
22
apply else
(defn form-eval [exp env]
(let [exp (macroexpand exp env)]
(cond (self-evaluating? exp) exp
;...
:else (form-apply (form-eval (first exp) env) ;<-- here
(map #(form-eval % env) (rest exp)))))
23
apply
(defn form-apply [proc args]
(letfn [(primitive? [p] (= (first p) 'primitive))
(procedure? [p] (= (first p) 'procedure)) ;;<-- from lambda
(proc-params [p] (second p))
(proc-body [p] (nth p 2))
(proc-env [p] (nth p 3))]
(cond (primitive? proc) (apply (second proc) args) ;;<-- magic
(procedure? proc) (eval-seq (proc-body proc)
(extend-env (proc-env proc)
(proc-params proc)
args)))))
24
Now you can write your own Lisp
in Clojure
25
Try it
(def env (setup-env))
(form-eval
'(define (fact x)
(if (eq? x 1)
1
(* x (fact (- x 1))))) env) ;=> ok
(form-eval
'(fact 6) env)) ;=> 720
More examples
26
Still some thing
Add your built-in functions
REPL
27
Question?
28

More Related Content

What's hot

The Ring programming language version 1.5.2 book - Part 75 of 181
The Ring programming language version 1.5.2 book - Part 75 of 181The Ring programming language version 1.5.2 book - Part 75 of 181
The Ring programming language version 1.5.2 book - Part 75 of 181Mahmoud Samir Fayed
 
The Ring programming language version 1.10 book - Part 94 of 212
The Ring programming language version 1.10 book - Part 94 of 212The Ring programming language version 1.10 book - Part 94 of 212
The Ring programming language version 1.10 book - Part 94 of 212Mahmoud Samir Fayed
 
Solving callback hell with good old function composition
Solving callback hell with good old function compositionSolving callback hell with good old function composition
Solving callback hell with good old function compositionVincent Pradeilles
 
Jscex: Write Sexy JavaScript (中文)
Jscex: Write Sexy JavaScript (中文)Jscex: Write Sexy JavaScript (中文)
Jscex: Write Sexy JavaScript (中文)jeffz
 
Reverse Engineering: C++ "for" operator
Reverse Engineering: C++ "for" operatorReverse Engineering: C++ "for" operator
Reverse Engineering: C++ "for" operatorerithion
 
The Ring programming language version 1.9 book - Part 91 of 210
The Ring programming language version 1.9 book - Part 91 of 210The Ring programming language version 1.9 book - Part 91 of 210
The Ring programming language version 1.9 book - Part 91 of 210Mahmoud Samir Fayed
 
Коварный code type ITGM #9
Коварный code type ITGM #9Коварный code type ITGM #9
Коварный code type ITGM #9Andrey Zakharevich
 
CROCHET - Checkpoint Rollback in JVM (ECOOP 2018)
CROCHET - Checkpoint Rollback in JVM (ECOOP 2018)CROCHET - Checkpoint Rollback in JVM (ECOOP 2018)
CROCHET - Checkpoint Rollback in JVM (ECOOP 2018)jon_bell
 
2013-02-21 - .NET UG Rhein-Neckar: JavaScript Best Practices
2013-02-21 - .NET UG Rhein-Neckar: JavaScript Best Practices2013-02-21 - .NET UG Rhein-Neckar: JavaScript Best Practices
2013-02-21 - .NET UG Rhein-Neckar: JavaScript Best PracticesJohannes Hoppe
 
Pratt Parser in Python
Pratt Parser in PythonPratt Parser in Python
Pratt Parser in PythonPercolate
 
Quinto Punto Parte B
Quinto Punto Parte BQuinto Punto Parte B
Quinto Punto Parte Bgustavo206
 
Implementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 reduxImplementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 reduxEleanor McHugh
 
PHP for Python Developers
PHP for Python DevelopersPHP for Python Developers
PHP for Python DevelopersCarlos Vences
 
Fine-grained Processing of CVS Archives with APFEL
Fine-grained Processing of CVS Archives with APFELFine-grained Processing of CVS Archives with APFEL
Fine-grained Processing of CVS Archives with APFELThomas Zimmermann
 

What's hot (20)

Unit test
Unit testUnit test
Unit test
 
The Ring programming language version 1.5.2 book - Part 75 of 181
The Ring programming language version 1.5.2 book - Part 75 of 181The Ring programming language version 1.5.2 book - Part 75 of 181
The Ring programming language version 1.5.2 book - Part 75 of 181
 
The Ring programming language version 1.10 book - Part 94 of 212
The Ring programming language version 1.10 book - Part 94 of 212The Ring programming language version 1.10 book - Part 94 of 212
The Ring programming language version 1.10 book - Part 94 of 212
 
Solving callback hell with good old function composition
Solving callback hell with good old function compositionSolving callback hell with good old function composition
Solving callback hell with good old function composition
 
Jscex: Write Sexy JavaScript (中文)
Jscex: Write Sexy JavaScript (中文)Jscex: Write Sexy JavaScript (中文)
Jscex: Write Sexy JavaScript (中文)
 
Reverse Engineering: C++ "for" operator
Reverse Engineering: C++ "for" operatorReverse Engineering: C++ "for" operator
Reverse Engineering: C++ "for" operator
 
Ecma script 5
Ecma script 5Ecma script 5
Ecma script 5
 
Hidden Gems of Ruby 1.9
Hidden Gems of Ruby 1.9Hidden Gems of Ruby 1.9
Hidden Gems of Ruby 1.9
 
The Ring programming language version 1.9 book - Part 91 of 210
The Ring programming language version 1.9 book - Part 91 of 210The Ring programming language version 1.9 book - Part 91 of 210
The Ring programming language version 1.9 book - Part 91 of 210
 
Google Guava
Google GuavaGoogle Guava
Google Guava
 
Коварный code type ITGM #9
Коварный code type ITGM #9Коварный code type ITGM #9
Коварный code type ITGM #9
 
CROCHET - Checkpoint Rollback in JVM (ECOOP 2018)
CROCHET - Checkpoint Rollback in JVM (ECOOP 2018)CROCHET - Checkpoint Rollback in JVM (ECOOP 2018)
CROCHET - Checkpoint Rollback in JVM (ECOOP 2018)
 
DataStructures notes
DataStructures notesDataStructures notes
DataStructures notes
 
2013-02-21 - .NET UG Rhein-Neckar: JavaScript Best Practices
2013-02-21 - .NET UG Rhein-Neckar: JavaScript Best Practices2013-02-21 - .NET UG Rhein-Neckar: JavaScript Best Practices
2013-02-21 - .NET UG Rhein-Neckar: JavaScript Best Practices
 
Pratt Parser in Python
Pratt Parser in PythonPratt Parser in Python
Pratt Parser in Python
 
Quinto Punto Parte B
Quinto Punto Parte BQuinto Punto Parte B
Quinto Punto Parte B
 
Functional programming with php7
Functional programming with php7Functional programming with php7
Functional programming with php7
 
Implementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 reduxImplementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 redux
 
PHP for Python Developers
PHP for Python DevelopersPHP for Python Developers
PHP for Python Developers
 
Fine-grained Processing of CVS Archives with APFEL
Fine-grained Processing of CVS Archives with APFELFine-grained Processing of CVS Archives with APFEL
Fine-grained Processing of CVS Archives with APFEL
 

Similar to Lisp

The Magnificent Seven
The Magnificent SevenThe Magnificent Seven
The Magnificent SevenMike Fogus
 
Monadologie
MonadologieMonadologie
Monadologieleague
 
Introduction To Lisp
Introduction To LispIntroduction To Lisp
Introduction To Lispkyleburton
 
Feel of Kotlin (Berlin JUG 16 Apr 2015)
Feel of Kotlin (Berlin JUG 16 Apr 2015)Feel of Kotlin (Berlin JUG 16 Apr 2015)
Feel of Kotlin (Berlin JUG 16 Apr 2015)intelliyole
 
Parametricity - #cljsyd - May, 2015
Parametricity - #cljsyd - May, 2015Parametricity - #cljsyd - May, 2015
Parametricity - #cljsyd - May, 2015Leonardo Borges
 
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...Philip Schwarz
 
A swift introduction to Swift
A swift introduction to SwiftA swift introduction to Swift
A swift introduction to SwiftGiordano Scalzo
 
深入浅出Jscex
深入浅出Jscex深入浅出Jscex
深入浅出Jscexjeffz
 
Programming in lua STRING AND ARRAY
Programming in lua STRING AND ARRAYProgramming in lua STRING AND ARRAY
Programming in lua STRING AND ARRAYvikram mahendra
 
Groovy puzzlers по русски с Joker 2014
Groovy puzzlers по русски с Joker 2014Groovy puzzlers по русски с Joker 2014
Groovy puzzlers по русски с Joker 2014Baruch Sadogursky
 
Are we ready to Go?
Are we ready to Go?Are we ready to Go?
Are we ready to Go?Adam Dudczak
 
Implement the following sorting algorithms Bubble Sort Insertion S.pdf
Implement the following sorting algorithms  Bubble Sort  Insertion S.pdfImplement the following sorting algorithms  Bubble Sort  Insertion S.pdf
Implement the following sorting algorithms Bubble Sort Insertion S.pdfkesav24
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with GroovyArturo Herrero
 
Damn Fine CoffeeScript
Damn Fine CoffeeScriptDamn Fine CoffeeScript
Damn Fine CoffeeScriptniklal
 

Similar to Lisp (20)

The Magnificent Seven
The Magnificent SevenThe Magnificent Seven
The Magnificent Seven
 
Monadologie
MonadologieMonadologie
Monadologie
 
Next Level Testing
Next Level TestingNext Level Testing
Next Level Testing
 
Introduction To Lisp
Introduction To LispIntroduction To Lisp
Introduction To Lisp
 
CQL 实现
CQL 实现CQL 实现
CQL 实现
 
SDC - Einführung in Scala
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in Scala
 
Feel of Kotlin (Berlin JUG 16 Apr 2015)
Feel of Kotlin (Berlin JUG 16 Apr 2015)Feel of Kotlin (Berlin JUG 16 Apr 2015)
Feel of Kotlin (Berlin JUG 16 Apr 2015)
 
Parametricity - #cljsyd - May, 2015
Parametricity - #cljsyd - May, 2015Parametricity - #cljsyd - May, 2015
Parametricity - #cljsyd - May, 2015
 
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
 
Scala for Jedi
Scala for JediScala for Jedi
Scala for Jedi
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
Pooya Khaloo Presentation on IWMC 2015
Pooya Khaloo Presentation on IWMC 2015Pooya Khaloo Presentation on IWMC 2015
Pooya Khaloo Presentation on IWMC 2015
 
A swift introduction to Swift
A swift introduction to SwiftA swift introduction to Swift
A swift introduction to Swift
 
深入浅出Jscex
深入浅出Jscex深入浅出Jscex
深入浅出Jscex
 
Programming in lua STRING AND ARRAY
Programming in lua STRING AND ARRAYProgramming in lua STRING AND ARRAY
Programming in lua STRING AND ARRAY
 
Groovy puzzlers по русски с Joker 2014
Groovy puzzlers по русски с Joker 2014Groovy puzzlers по русски с Joker 2014
Groovy puzzlers по русски с Joker 2014
 
Are we ready to Go?
Are we ready to Go?Are we ready to Go?
Are we ready to Go?
 
Implement the following sorting algorithms Bubble Sort Insertion S.pdf
Implement the following sorting algorithms  Bubble Sort  Insertion S.pdfImplement the following sorting algorithms  Bubble Sort  Insertion S.pdf
Implement the following sorting algorithms Bubble Sort Insertion S.pdf
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
 
Damn Fine CoffeeScript
Damn Fine CoffeeScriptDamn Fine CoffeeScript
Damn Fine CoffeeScript
 

Recently uploaded

The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfkalichargn70th171
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
XpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsXpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsMehedi Hasan Shohan
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - InfographicHr365.us smith
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...aditisharan08
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyFrank van der Linden
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
buds n tech IT solutions
buds n  tech IT                solutionsbuds n  tech IT                solutions
buds n tech IT solutionsmonugehlot87
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfPower Karaoke
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
What are the features of Vehicle Tracking System?
What are the features of Vehicle Tracking System?What are the features of Vehicle Tracking System?
What are the features of Vehicle Tracking System?Watsoo Telematics
 

Recently uploaded (20)

The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
XpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsXpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software Solutions
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - Infographic
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The Ugly
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
buds n tech IT solutions
buds n  tech IT                solutionsbuds n  tech IT                solutions
buds n tech IT solutions
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdf
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
What are the features of Vehicle Tracking System?
What are the features of Vehicle Tracking System?What are the features of Vehicle Tracking System?
What are the features of Vehicle Tracking System?
 

Lisp

  • 1. Write Your Own Lisp in Clojure Learn Lisp by making a Lisp 1
  • 6. Apply (defn form-apply [proc args] (letfn [(primitive? [p] (= (first p) 'primitive)) (procedure? [p] (= (first p) 'procedure)) ;<-- from lambda (proc-params [p] (second p)) (proc-body [p] (nth p 2)) (proc-env [p] (nth p 3))] (cond (primitive? proc) (apply (second proc) args) ;<-- magic (procedure? proc) (eval-seq (proc-body proc) (extend-env (proc-env proc) (proc-params proc) args))))) 6
  • 7. Primitive expressions true, 123, "words" nil var, my-fn (defn form-eval [exp env] (cond (self-evaluating? exp) exp (symbol? exp) (env-get exp env) (defn self-evaluating? [x] (or (number? x) (string? x) (nil? x) (boolean? x))) 7
  • 9. Enviroment (defn env-find [var env action not-found] ...) (defn env-get [var env] ...) (defn env-set [var val env] ...) (defn extend-env [env] ...) 9
  • 10. Initial Enviroment (defn setup-env [] (-> '() (extend-env (keys primitive-procs) (map #(list 'primitive %) (vals primitive-procs))) (extend-env) (built-in!) (extend-env))) (def primitive-procs {'true true '+ + 'car first ...}) primitive-procs 10
  • 11. quote (quote 1) => 1 (quote a) => a (quote (+ 1 1)) => (+ 1 1) (defn form-eval [exp env] (cond (self-evaluating? exp) exp (symbol? exp) (env-get exp env) (= (first exp) 'quote) (second exp)) ;;<- here 11
  • 12. if (if <cond-expr> expr else-expr) (defn form-eval [exp env] (let [exp (macroexpand exp env)] (cond (self-evaluating? exp) exp (symbol? exp) (env-get exp env) (= (first exp) 'quote) (second exp) (= (first exp) 'if) (eval-if exp env)))) ; <- here (defn eval-if [exp env] (let [[a0 a1 a2 a3] exp] (if (form-eval a1 env) (form-eval a2 env) (form-eval a3 env)))) 12
  • 13. Why is "if" a special form? Can we just write a if function? (defn iif [condition stat else] (if (true? condition) expr else-expr)) (iif true (+ 1 2) (* 0 0)) ;=> 3 (iif false (+ 1 2) (* 0 0)) ;=> 0 (iif true (+ 1 2) (/ 0 0)) ;=> Error: ArithmeticException Divide by zero 13
  • 14. begin (begin expr1 expr2 ...) like "do" in clojure (defn form-eval [exp env] (cond (self-evaluating? exp) exp (symbol? exp) (env-get exp env) (= (first exp) 'quote) (second exp) (= (first exp) 'if) (eval-if exp env) (= (first exp) 'begin) (eval-seq (rest exp) env))) ; <-- here (defn eval-seq [exp env] (reduce #(form-eval %2 env) nil exp)) 14
  • 15. lambda (lambda (x y) (+ x y)) (lambda () 5) (defn form-eval [exp env] (cond (self-evaluating? exp) exp ; ... (= (first exp) 'lambda) (eval-lambda exp env)))) ;<- here (defn eval-lambda [exp env] (list 'procedure ;<-- this is for form-apply (second exp) (drop 2 exp) env)) 15
  • 16. define (define x 1) (define (f x y) (+ x y)) (define f (lambda (x y) (+ x y))) (defn form-eval [exp env] (let [exp (macroexpand exp env)] (cond (self-evaluating? exp) exp ; ... (= (first exp) 'define) (eval-define exp env)))) ;<-- here 16
  • 17. eval-define (defn define-var [exp] (if (seq? (second exp)) ;function? (first (second exp)) ;it's a function so the var is function name (second exp))) (defn define-val [exp env] (let [var (second exp) make-lambda #(cons 'lambda (cons %1 %2))] (if (seq? var) ;function? (form-eval (make-lambda (rest var) (drop 2 exp)) env) (form-eval (nth exp 2) env)))) (defn eval-define [exp env] (let [var (define-var exp) val (define-val exp env)] (swap! (first env) assoc var val))) 17
  • 18. set! (define x 5) (set! x 10) (defn form-eval [exp env] (cond (self-evaluating? exp) exp ;... (= (first exp) 'set!) (eval-assignment exp env))) ;<-- here (defn eval-assignment [exp env] (let [[op var val] exp] (env-set var val env))) 18
  • 19. let* (let* ((var val) ...) body) (defn form-eval [exp env] (cond (self-evaluating? exp) exp ;... (= (first exp) 'let*) (eval-let* exp env))) ;<--here (defn eval-let* [exp env] (let [eenv (extend-env env) [op vars body] exp] (doseq [[b e] vars] (swap! (first eenv) assoc b (form-eval e eenv))) (form-eval body eenv))) 19
  • 20. defmacro (defmacro binding (lambda (args) body)) (defn form-eval [exp env] (cond (self-evaluating? exp) exp ;... (= (first exp) 'defmacro) (eval-defmacro exp env))); <-here (defn eval-defmacro [exp env] (let [[a0 a1 a2] exp mbody (with-meta (form-eval a2 env) {:ismacro true})] (swap! (first env) assoc a1 mbody) "ok")) 20
  • 21. macroexpand (defn form-eval [exp env] (let [exp (macroexpand exp env)] ;<--here (cond (self-evaluating? exp) exp (= (first exp) 'macroexpand) (macroexpand (second exp) env)))) ;<-- here (defn macroexpand [exp env] (loop [exp exp] (if (is-macro-call exp env) (let [mac (env-get (first exp) env)] (recur (form-apply mac (rest exp)))) exp))) 21
  • 22. macroexpand (cont.) (defn is-macro-call [exp env] (and (seq? exp) (symbol? (first exp)) (env-find (first exp) env #(:ismacro (meta (get @% (first exp)))) #(identity false)))) 22
  • 23. apply else (defn form-eval [exp env] (let [exp (macroexpand exp env)] (cond (self-evaluating? exp) exp ;... :else (form-apply (form-eval (first exp) env) ;<-- here (map #(form-eval % env) (rest exp))))) 23
  • 24. apply (defn form-apply [proc args] (letfn [(primitive? [p] (= (first p) 'primitive)) (procedure? [p] (= (first p) 'procedure)) ;;<-- from lambda (proc-params [p] (second p)) (proc-body [p] (nth p 2)) (proc-env [p] (nth p 3))] (cond (primitive? proc) (apply (second proc) args) ;;<-- magic (procedure? proc) (eval-seq (proc-body proc) (extend-env (proc-env proc) (proc-params proc) args))))) 24
  • 25. Now you can write your own Lisp in Clojure 25
  • 26. Try it (def env (setup-env)) (form-eval '(define (fact x) (if (eq? x 1) 1 (* x (fact (- x 1))))) env) ;=> ok (form-eval '(fact 6) env)) ;=> 720 More examples 26
  • 27. Still some thing Add your built-in functions REPL 27