<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blog 4 &#187; Lispy</title>
	<atom:link href="http://nickzarr.com/blog4/category/programming-2/lispy/feed/" rel="self" type="application/rss+xml" />
	<link>http://nickzarr.com/blog4</link>
	<description>Chosen by fair dice roll. Guaranteed random.</description>
	<lastBuildDate>Sun, 22 Apr 2012 18:29:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Introducing Evo: The Original Purpose of Lispy</title>
		<link>http://nickzarr.com/blog4/2011/03/introducing-evo-the-original-purpose-of-lispy/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=introducing-evo-the-original-purpose-of-lispy</link>
		<comments>http://nickzarr.com/blog4/2011/03/introducing-evo-the-original-purpose-of-lispy/#comments</comments>
		<pubDate>Fri, 25 Mar 2011 22:36:38 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Lispy]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Scheme]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[artificial intelligence]]></category>
		<category><![CDATA[evolutionary programming]]></category>
		<category><![CDATA[genetic programming]]></category>
		<category><![CDATA[Language Design]]></category>
		<category><![CDATA[optimization]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=880</guid>
		<description><![CDATA[When I first envisioned the Lispy project I had only one goal in mind, which I&#8217;ll get to soon. As I started writing code, first in Scheme, then C then again in Scheme, the Lispy project evolved into something else. It changed into a platform for me to learn more about programming and the implementation [...]]]></description>
			<content:encoded><![CDATA[<p>When I first envisioned the Lispy project I had only one goal in mind, which I&#8217;ll get to soon.  As I started writing code, first in Scheme, then C then again in Scheme, the Lispy project evolved into something else.  It changed into a platform for me to learn more about programming and the implementation of language features.  Writing Lispy, in all its variations, has been a very educational and rewarding experience, so much so that I consider the project an overwhelming success, even though I didn&#8217;t realize the original purpose.</p>
<p>So what was the original purpose of Lispy?  I&#8217;ll give you the tag line that I wrote when Lispy was nothing but an idea&#8230;  <strong>Lispy is a distributed self-optimizing program by example language</strong>.</p>
<p>What does that mean?  When I first became interested in programming I had 2 goals; to create a program like MetaStock (I&#8217;ve since written <a href="https://github.com/jacktrades/pyTrade">pyTrade</a>) and to create Artificial Intelligence.  Modest goals, I know.  In my AI research I came across genetic programming and immediately took a liking to it, probably because I was still new to writing code and the idea that I could write code that wrote code fascinated me.</p>
<p>The main problem with genetic programming is that it is often difficult to write fitness tests for your problems.  Somewhere along the way I noticed that programmers were writing fitness tests all the time in the form of unit tests for their code.  In addition, the fact that 99% of the time the CPU sits idle while we browse reddit, kept rattling around in my head.  Why not take advantage of those wasted cycles by using a programming language that used those cycles to optimize the code you just wrote?</p>
<p>Then I had another idea.  Why write code at all?  Why not just write the unit tests and let the code evolve on its own?  It took me about an hour to realize that this wasn&#8217;t going to work on anything but the smallest applications.  However another few weeks and I realized that, maybe it could work, given enough computers were running Lispy.</p>
<p>Anyway I have about 25 half-finished papers on Evo which I might get around to finishing and posting here.  I&#8217;ll give the highlights and post a link to the github account where you can find more info.  Evo is meant to be integrated with Lispy (though I don&#8217;t know when I&#8217;ll get around to that).</p>
<p>Evo is an evolutionary search based function optimizer.  It provides an interface for defining new modules and functions as well as an evolutionary programming based method for optimizing those functions.  Evo does not use the standard generational approach to GP, rather it uses &#8220;gene pools&#8221;, that contain functions of indefinite life, from which new functions can be evolved and tested one at a time.</p>
<p>When defining an Evo function you can choose to optimize it for speed, space or code length.  Each function can have multiple gene pools that are each optimized for a different purpose.  Using gene pools instead of a single population generational approach helps to avoid stagnation within the population as is a common occurrence with the standard generational model.</p>
<p>Evo is very much unfinished, however it can successfully run on its own and evolve solutions to problems.  Because of this I am going to put the code out there in case anyone wishes to contribute.  I used the implementation of Evo as an excuse to firm up my understanding of closures, as a result the majority of the program is written in a slightly OOP fashion.  There is also a Tk based GUI for browsing modules and adding new functions and fitness tests, though its use is completely optional.</p>
<p>Without further ado, <a href="https://github.com/jacktrades/Evo">here&#8217;s the link to the Evo repo</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/03/introducing-evo-the-original-purpose-of-lispy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scheme in Lispy</title>
		<link>http://nickzarr.com/blog4/2011/03/scheme-in-lispy/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=scheme-in-lispy</link>
		<comments>http://nickzarr.com/blog4/2011/03/scheme-in-lispy/#comments</comments>
		<pubDate>Sun, 13 Mar 2011 15:00:53 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Lispy]]></category>
		<category><![CDATA[Chicken]]></category>
		<category><![CDATA[interpreter]]></category>
		<category><![CDATA[Language Design]]></category>
		<category><![CDATA[lispy in scheme]]></category>
		<category><![CDATA[meta-circular evaluator]]></category>
		<category><![CDATA[Scheme]]></category>
		<category><![CDATA[sicp]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=740</guid>
		<description><![CDATA[Now that we have our basic interpreter set up, it&#8217;s time to start writing some languages. Before we start experimenting with Lispy, we will implement a small subset of Scheme. Implementing Scheme will let us test our implementation with a language that is already specified. Create a new file, I&#8217;ll call it scheme_in_lispy.lispy, but you [...]]]></description>
			<content:encoded><![CDATA[<p>Now that we have our basic interpreter set up, it&#8217;s time to start writing some languages.  Before we start experimenting with Lispy, we will implement a small subset of Scheme.</p>
<p>Implementing Scheme will let us test our implementation with a language that is already specified.</p>
<p>Create a new file, I&#8217;ll call it scheme_in_lispy.lispy, but you can name it whatever you like.  We&#8217;ll be doing most of our work here so I&#8217;ll leave out the main lispy file.</p>
<p>We&#8217;ll start with <strong>define-primitive</strong> which we&#8217;ll simply copy from the old syntax.chicken, though we won&#8217;t use it until later.</p>
<pre class="brush: plain; title: ; notranslate">
(scheme-syntax define-primitive
  (lambda (expr env)
    (set-symbol! (car expr)
                 (make-primitive (eval (cadr expr)))
                 env)))
</pre>
<p>The first primitive form we&#8217;ll introduce is <strong>define</strong>.  For this we&#8217;re going to do a little more copy and paste.  Scheme&#8217;s define form is just a combination of our previous define and function.  define sets a value to a symbol, but it also provides a shorthand for setting a lambda to a symbol (define (a x) x) is equivalent to (define a (lambda (x) x)).  To figure out which one we need to produce, we only have to look at the first value in expr.  If it is a symbol we just set the symbol name to the evaluated value.  If it is a list we create a proc and set that as the value to symbol.</p>
<pre class="brush: plain; title: ; notranslate">
(scheme-syntax define
  (lambda (expr env)
    (if (list? (car expr))
        (set-symbol! (caar expr)
                     (make-proc (cdar expr)
                                (cdr expr)
                                env) env)
        (set-symbol! (car expr) (lispy-eval (cadr expr) env) env))))
</pre>
<pre class="brush: plain; gutter: false; title: ; notranslate">
(define a 42)
;===&gt; #&lt;unspecified&gt;
a
;===&gt; 42
(define (b x) x)
;===&gt; #&lt;unspecified&gt;
(b 42)
;===&gt; 42
</pre>
<p><strong>lambda</strong> is simple after that.  All we have to do is rip out the (make-proc &#8230;) procedure and drop it into lambda with one small change.  With define we received a procedure definition as ((name arg-1 arg-2 arg-n) body), however an anonymous function does not have a name.  We receive a lambda definition as ((arg-1 arg-2 arg-n) body).</p>
<pre class="brush: plain; title: ; notranslate">
(scheme-syntax lamb
  (lambda (expr env)
    (make-proc (car expr)
               (cdr expr)
               env)))
</pre>
<pre class="brush: plain; gutter: false; title: ; notranslate">
(define c (lambda (x) x))
;===&gt; #&lt;unspecified&gt;
(c 42)
;===&gt; 42
((lambda (y) y) 42)
;===&gt; 42
</pre>
<p><strong>if</strong> is a straight copy/paste from our old syntax file.</p>
<pre class="brush: plain; title: ; notranslate">
(scheme-syntax if
  (lambda (expr env)
    (if (lispy-eval (car expr) env)
        (lispy-eval (cadr expr) env)
        (lispy-eval (caddr expr) env))))
</pre>
<pre class="brush: plain; gutter: false; title: ; notranslate">
(if 1 2 3)
;===&gt; 2
(if #f 2 3)
;===&gt; 3
</pre>
<p><strong>quote</strong> is one of the simplest forms in Scheme.  All quote does is return its argument unevaluated.</p>
<pre class="brush: plain; title: ; notranslate">
(scheme-syntax quote
  (lambda (expr env)
    (car expr)))
</pre>
<pre class="brush: plain; gutter: false; title: ; notranslate">
(quote (+ 1 2))
;===&gt; (+ 1 2)
</pre>
<p><strong>set!</strong> is pretty simple too, it&#8217;s basically just a limited form of define.</p>
<pre class="brush: plain; title: ; notranslate">
(scheme-syntax set!
  (lambda (expr env)
    (set-symbol! (car expr) (lispy-eval (cadr expr) env) env)))
</pre>
<pre class="brush: plain; gutter: false; title: ; notranslate">
(set! a 42)
;===&gt; #&lt;unspecified&gt;
a
;===&gt; 42
(set! b (if #f 2 3))
;===&gt; #&lt;unspecified&gt;
b
;===&gt; 3
(set! c (lambda (x) x))
;===&gt; #&lt;unspecified&gt;
(c 42)
;===&gt; 42
</pre>
<p><strong>begin</strong> is pretty straightforward, in fact we have already implemented it as eval-body (we used it for procedures).</p>
<pre class="brush: plain; title: ; notranslate">
(scheme-syntax begin
  (lambda (expr env)
    (eval-body expr env)))
</pre>
<pre class="brush: plain; gutter: false; title: ; notranslate">
(begin 1 2 3)
;===&gt; 3
(begin (define x 42) x)
;===&gt; 42
</pre>
<p><strong>let</strong> is almost the same as begin, except we have to extend the environment with the given bindings before we evaluate the body of the let.  This version uses cons cells instead of 2 element lists to set symbols.  You could add support for (let ((x 35) (y 7)) &#8230;) if you like.  Since making a Scheme is not my goal, I will not do that now.</p>
<pre class="brush: plain; title: ; notranslate">
(scheme-syntax let
  (lambda (expr env)
    (eval-body (cdr expr) (extend-environment (car expr) env))))
</pre>
<pre class="brush: plain; gutter: false; title: ; notranslate">
(let ((x . 35) (y . 7)) (if x x y))
;===&gt; 35
x
;===&gt; Error: Unbound symbol: x
</pre>
<p><strong>equal?</strong> is easily snarfed from the underlying Scheme.  equal? could also be defined using define-primitive (define-primitive equal? equal?).</p>
<pre class="brush: plain; title: ; notranslate">
(scheme-syntax equal?
  (lambda (expr env)
    (equal? (lispy-eval (car expr) env)
            (lispy-eval (cadr expr) env))))
</pre>
<pre class="brush: plain; gutter: false; title: ; notranslate">
(equal? 2 2)
;===&gt; #t
(equal? 2 (if 1 2 3))
;===&gt; #t
(equal? 1 2)
;===&gt; #f
</pre>
<p>Finally we&#8217;ll snarf some primitives from the underlying Scheme to make our mini-Scheme a little more usable.</p>
<pre class="brush: plain; title: ; notranslate">
(define-primitive + +)
(define-primitive - -)
(define-primitive &lt; &lt;)
(define-primitive &gt; &gt;)
(define-primitive car car)
(define-primitive cdr cdr)
(define-primitive cons cons)
(define-primitive print print)
</pre>
<pre class="brush: plain; gutter: false; title: ; notranslate">
(+ 1 2)
;===&gt; 3
(- 3 2)
;===&gt; 1
(&lt; 1 2)
;===&gt; #t
(&gt; 1 2)
;===&gt; #f
(cons 1 2)
;===&gt; (1 . 2)
(car (cons 1 2))
;===&gt; 1
(cdr (cons 1 2))
;===&gt; 2
(define (loop x) (if (&lt; x 0) (print 'finished) (begin (print x) (loop (- x 1)))))
;===&gt; #&lt;unspecified&gt;
(loop 3)
3
2
1
0
finished
;===&gt; #&lt;unspecified&gt;
</pre>
<p>There is a lot that is left out, error handling and advanced features like call-with-current-continuation or macros, for example.  But for a simple Scheme to help test the implementation of our interpreter this is just about all we need.</p>
<p>Most of the rest of Scheme can be implemented as derived forms from the primitives we just defined.  What cannot be, can be implemented using our scheme-syntax macro.</p>
<p>Finally, here&#8217;s the full source of scheme_in_lispy.lispy for you to play with.  </p>
<pre class="brush: plain; title: ; notranslate">
(scheme-syntax define-primitive
  (lambda (expr env)
    (set-symbol! (car expr)
                 (make-primitive (eval (cadr expr)))
                 env)))

(scheme-syntax define
  (lambda (expr env)
    (if (list? (car expr))
        (set-symbol! (caar expr)
                     (make-proc (cdar expr)
                                (cdr expr)
                                env) env)
        (set-symbol! (car expr) (lispy-eval (cadr expr) env) env))))

(scheme-syntax lambda
  (lambda (expr env)
    (make-proc (car expr)
               (cdr expr)
               env)))

(scheme-syntax if
  (lambda (expr env)
    (if (lispy-eval (car expr) env)
        (lispy-eval (cadr expr) env)
        (lispy-eval (caddr expr) env))))

(scheme-syntax quote
  (lambda (expr env)
    (car expr)))

(scheme-syntax set!
  (lambda (expr env)
    (set-symbol! (car expr) (lispy-eval (cadr expr) env) env)))

(scheme-syntax begin
  (lambda (expr env)
    (eval-body expr env)))

(scheme-syntax let
  (lambda (expr env)
    (eval-body (cdr expr) (extend-environment (car expr) env))))

(scheme-syntax equal?
  (lambda (expr env)
    (equal? (lispy-eval (car expr) env)
            (lispy-eval (cadr expr) env))))

(define-primitive + +)
(define-primitive - -)
(define-primitive &lt; &lt;)
(define-primitive &gt; &gt;)
(define-primitive car car)
(define-primitive cdr cdr)
(define-primitive cons cons)
(define-primitive print print)
</pre>
<p><a href="http://nickzarr.com/blog4/lispy-in-scheme/">GOTO Table of Contents</a></p>
<p><a title="Lispy in Chicken" href="http://nickzarr.com/blog4/lispy-in-scheme/">GOTO Table of Contents</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/03/scheme-in-lispy/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Lispy in Scheme &#124; Lispy Procedures</title>
		<link>http://nickzarr.com/blog4/2011/03/lispy-in-scheme-lispy-procedures/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=lispy-in-scheme-lispy-procedures</link>
		<comments>http://nickzarr.com/blog4/2011/03/lispy-in-scheme-lispy-procedures/#comments</comments>
		<pubDate>Wed, 09 Mar 2011 11:00:29 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Lispy]]></category>
		<category><![CDATA[Chicken]]></category>
		<category><![CDATA[interpreter]]></category>
		<category><![CDATA[Language Design]]></category>
		<category><![CDATA[lispy in scheme]]></category>
		<category><![CDATA[meta-circular evaluator]]></category>
		<category><![CDATA[Scheme]]></category>
		<category><![CDATA[sicp]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=665</guid>
		<description><![CDATA[The goal for this part is to implement procedures in Lispy. To begin implementing Lispy procedures we have to define a procedure type, just like we did with primitives. A procedure has 3 basic parts. A list of parameters, a body and an environment. So we&#8217;ll set up our new procedure type with these fields [...]]]></description>
			<content:encoded><![CDATA[<p>The goal for this part is to implement procedures in Lispy.</p>
<p>To begin implementing Lispy procedures we have to define a <strong>procedure</strong> type, just like we did with primitives.  A procedure has 3 basic parts.  A list of <strong>parameters</strong>, a <strong>body</strong> and an <strong>environment</strong>.  So we&#8217;ll set up our new procedure type with these fields and call it <strong>proc</strong> to avoid a name clash with Scheme&#8217;s procedure?.  </p>
<p>Like primitives, procedures are handled by the <strong>lispy-apply</strong> procedure.  We&#8217;ll change lispy-apply to use a cond instead of nested ifs and temporarily put in a placeholder for procedures.  In addition we need a way to define new procedures from within Lispy.  If we were writing a Scheme, the <strong>define</strong> form would allow us to both set symbols and procedures.  For the moment we&#8217;ll separate the two usual jobs of define and create a new form (function (parameters) body) to set procedures.</p>
<pre class="brush: plain; highlight: [5,40,41,42,43,44,45]; title: ; wrap-lines: false; notranslate">
(use srfi-69)

(define global-syntax-definitions (make-hash-table))
(define-record primitive function)
(define-record proc parameters body environment)

(define (current-environment env) (car env))
(define (enclosing-environment env) (cdr env))

(define (extend-environment bindings base-environment)
  (cons (alist-&gt;hash-table bindings) base-environment))

(define the-global-environment (extend-environment '() '()))

(define (set-symbol! symbol value env)
  (hash-table-set! (current-environment env) symbol value))

(define (lookup-symbol-value symbol environment)
  (if (null? environment)
    (error 'unbound-symbol &quot;Unbound symbol:  &quot; symbol)
    (if (hash-table-exists? (current-environment environment) symbol)
        (hash-table-ref (current-environment environment) symbol)
        (lookup-symbol-value symbol (enclosing-environment environment)))))

(define (self-evaluating? expr)
  (or (number? expr) (string? expr) (char? expr) (boolean? expr)))

(define (lispy-eval expr env)
  (cond ((self-evaluating? expr) expr)
        ((symbol? expr) (lookup-symbol-value expr env))
        (else
          (if (hash-table-exists? global-syntax-definitions (car expr))
              ((hash-table-ref global-syntax-definitions (car expr)) (cdr expr) env)
              (lispy-apply (lispy-eval (car expr) env) (eval-arguments (cdr expr) env))))))

(define (eval-arguments args env)
  (map (lambda (x) (lispy-eval x env)) args))

(define (lispy-apply procedure arguments)
  (cond ((primitive? procedure)
           (apply (primitive-function procedure) arguments))
        ((proc? procedure)
           &quot;Attempted to apply a Lispy procedure&quot;)
        (else
           &quot;Error: Undefined procedure&quot;)))

(hash-table-set! global-syntax-definitions 'scheme-syntax
  (lambda (expr env)
    (hash-table-set! global-syntax-definitions (car expr) (eval (cadr expr)))))

(hash-table-set! global-syntax-definitions 'load
  (lambda (expr env)
    (define f (open-input-file (car expr)))
    (let loop ((e (read f)))
      (if (equal? e #!eof) &quot;Successfully Loaded!&quot;
                           (begin
                             (lispy-eval e env)
                             (loop (read f)))))))

((hash-table-ref global-syntax-definitions 'load) '(&quot;syntax.chicken&quot;) the-global-environment)

(define (repl)
  (define input (read))
  (print &quot;;===&gt; &quot; (lispy-eval input the-global-environment))
  (repl))
</pre>
<p><strong>syntax.chicken</strong></p>
<pre class="brush: plain; highlight: [16,17,18,19,20,21]; title: ; notranslate">
(scheme-syntax define
  (lambda (expr env)
    (set-symbol! (car expr) (lispy-eval (cadr expr) env) env)))

(scheme-syntax if
  (lambda (expr env)
    (if (lispy-eval (car expr) env)
        (lispy-eval (cadr expr) env)
        (lispy-eval (caddr expr) env))))

(scheme-syntax define-primitive
  (lambda (expr env)
    (set-symbol! (car expr)
                 (make-primitive (eval (cadr expr))))))

(scheme-syntax function
  (lambda (expr env)
    (set-symbol! (caar expr)
                 (make-procedure (cdar expr)
                                 (cdr expr)
                                 env) env)))
</pre>
<pre class="brush: plain; gutter: false; title: ; notranslate">
(function (a x) x)
;===&gt; &lt;unspecified&gt;
a
;===&gt; #&lt;proc&gt;
(a 42)
;===&gt; Attempted to apply a Lispy procedure
</pre>
<p>Now that we have a basic outline for what our procedures will look like, we can focus on making them work!</p>
<p>To apply a procedure we have to evaluate the <strong>body</strong>.  In the example above the body of the procedure is just <strong>x</strong>.  However we can&#8217;t just evaluate <strong>x</strong> because <strong>x</strong> is not bound to anything yet.  </p>
<p>First we need to create a new environment and bind the parameters to the arguments supplied in the procedure call.  In this case we have to bind <strong>x</strong> to the value <strong>42</strong>.  For this we&#8217;ll use a helper procedure called <strong>assign-values</strong>.</p>
<p>The <strong>body</strong> is evaluated in the same way that we evaluate arguments.  The difference is that we only return the last expression of the body.  For now we&#8217;ll create a procedure named <strong>eval-body</strong> that will call <strong>eval-arguments</strong>, then return the last evaluated argument (it&#8217;s not the most efficient implementation, but it is simple and reuses code that we have already wrote).</p>
<pre class="brush: plain; highlight: [2,40,41,42,43,44,47,48,49,50,51,52,53,54]; title: ; wrap-lines: false; notranslate">
(use srfi-69)
(use srfi-1)

(define global-syntax-definitions (make-hash-table))
(define-record primitive function)
(define-record proc parameters body environment)

(define (current-environment env) (car env))
(define (enclosing-environment env) (cdr env))

(define (extend-environment bindings base-environment)
  (cons (alist-&gt;hash-table bindings) base-environment))

(define the-global-environment (extend-environment '() '()))

(define (set-symbol! symbol value env)
  (hash-table-set! (current-environment env) symbol value))

(define (lookup-symbol-value symbol environment)
  (if (null? environment)
    &quot;Error: Unbound symbol&quot;;(error 'unbound-symbol &quot;Unbound symbol:  &quot; symbol)
    (if (hash-table-exists? (current-environment environment) symbol)
        (hash-table-ref (current-environment environment) symbol)
        (lookup-symbol-value symbol (enclosing-environment environment)))))

(define (self-evaluating? expr)
  (or (number? expr) (string? expr) (char? expr) (boolean? expr)))

(define (lispy-eval expr env)
  (cond ((self-evaluating? expr) expr)
        ((symbol? expr) (lookup-symbol-value expr env))
        (else
          (if (hash-table-exists? global-syntax-definitions (car expr))
              ((hash-table-ref global-syntax-definitions (car expr)) (cdr expr) env)
              (lispy-apply (lispy-eval (car expr) env) (eval-arguments (cdr expr) env))))))

(define (eval-arguments args env)
  (map (lambda (x) (lispy-eval x env)) args))

(define (eval-body args env)
  (last (eval-arguments args env)))

(define (assign-values procedure args)
  (map cons (proc-parameters procedure) args))

(define (lispy-apply procedure arguments)
  (cond ((primitive? procedure)
           (apply (primitive-function procedure) arguments))
        ((proc? procedure)
           (eval-body (proc-body procedure)
                      (extend-environment (assign-values procedure arguments)
                                          (proc-environment procedure))))
        (else
           &quot;Error: Undefined procedure&quot;)))

(hash-table-set! global-syntax-definitions 'scheme-syntax
  (lambda (expr env)
    (hash-table-set! global-syntax-definitions (car expr) (eval (cadr expr)))))

(hash-table-set! global-syntax-definitions 'load
  (lambda (expr env)
    (define f (open-input-file (car expr)))
    (let loop ((e (read f)))
      (if (equal? e #!eof) &quot;Successfully Loaded!&quot;
                           (begin
                             (lispy-eval e env)
                             (loop (read f)))))))

((hash-table-ref global-syntax-definitions 'load) '(&quot;syntax.chicken&quot;) the-global-environment)

(define (repl)
  (define input (read))
  (print &quot;;===&gt; &quot; (lispy-eval input the-global-environment))
  (repl))
</pre>
<pre class="brush: plain; gutter: false; title: ; notranslate">
(function (test pred conseq alt)
  (if pred conseq alt))
;===&gt; #&lt;unspecified&gt;
(test 1 2 3)
;===&gt; 2
</pre>
<p>With that, we have implemented procedures in Lispy!  In 58 lines we have defined an interpreter framework that we can use to write just about any parenthesized, applicative-order, lexically scoped language.  In the next few parts we&#8217;ll implement a very basic Scheme, then McCarthy&#8217;s LISP and finally begin work on the implementation of Lispy.  </p>
<p>Also note that there is very little error-checking going on here.  For instance calling a procedure with the wrong number of arguments results in the whole interpreter crashing.  This would not be good in a production language.  However including error checking in this code would probably triple its size at least.  The point of this exercise is to learn the concepts, not write a bullet-proof language.</p>
<p><a href="http://nickzarr.com/blog4/2011/03/scheme-in-lispy/" title="Scheme in Lispy">GOTO Part 8 | Scheme in Lispy</a></p>
<p><a title="Lispy in Chicken" href="http://nickzarr.com/blog4/lispy-in-scheme/">GOTO Table of Contents</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/03/lispy-in-scheme-lispy-procedures/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lispy in Scheme &#8211; Environments</title>
		<link>http://nickzarr.com/blog4/2011/03/lispy-in-scheme-environments/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=lispy-in-scheme-environments</link>
		<comments>http://nickzarr.com/blog4/2011/03/lispy-in-scheme-environments/#comments</comments>
		<pubDate>Sun, 06 Mar 2011 08:39:09 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Lispy]]></category>
		<category><![CDATA[Chicken]]></category>
		<category><![CDATA[meta-circular evaluator]]></category>
		<category><![CDATA[Scheme]]></category>
		<category><![CDATA[write an interpreter]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=614</guid>
		<description><![CDATA[We&#8217;ve been dealing with an environment ever since part 2 in this series when we implemented define, except we&#8217;ve been calling it a frame. Until now our frame has served us well, it has provided a simple environment where we could set and retrieve the value of symbols. However implementing procedures requires us to add [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve been dealing with an <strong>environment</strong> ever since <a href="http://nickzarr.com/blog4/2011/02/25/assignment-and-define/">part 2</a> in this series when we implemented define, except we&#8217;ve been calling it a <strong>frame</strong>.  Until now our frame has served us well, it has provided a simple environment where we could set and retrieve the value of symbols.  However implementing procedures requires us to add a few features to our frame.  Consider the code below.</p>
<pre class="brush: plain; title: ; notranslate">
(define x 5)
(define (func x)
  x)
(func 100)
;===&gt; 100
</pre>
<p>With our frame this wouldn&#8217;t work as expected.  Because we have already defined x in the global environment, there will be one of two problems with the x in <strong>func</strong>.  Our function could use the global value of x (5) instead of the supplied value (100) or when the supplied value (100) is mapped onto the function body it will overwrite the value of the global value of x (5) with the supplied value (100).</p>
<p>Currently we do not make any distinction between variables in a function body and in the global environment.  To properly implement procedures we will have to figure out a way to do that.  Consider the next bit of code.</p>
<pre class="brush: plain; title: ; notranslate">
(define x 5)
(define (func y)
  (+ x y))
(func 10)
;===&gt; 15
</pre>
<p>Even though we need to make a distinction between environments they also need to be connected.  In the example above we use the global variable x in func without ever declaring it.  This is accomplished by a method called chaining environments.  </p>
<pre class="brush: plain; title: ; notranslate">
(define x 1)
(define (outer-func y)
  (define (inner-func z)
    (+ x y z)
  (inner-func 3))
(outer-func 2)
;===&gt; 6
</pre>
<p>The environments produced by the above code are best described by the diagram below.</p>
<p><img src="https://docs.google.com/drawings/pub?id=1ODj7-OmaC-KHAITY2fvGrQIFqCn9sxMbit2iNjWrj2E&amp;w=580&amp;h=568"></p>
<p>So when x appears in inner-func we have to check inner-func&#8217;s environment for x, then outer-func&#8217;s environment for x and finally the global environment for x before we raise an undefined symbol error.</p>
<p>You may have noticed that the diagram above looks a lot like a <a href="http://nickzarr.com/blog4/2011/02/20/what-in-the-hell-are-linked-lists/">linked list</a>.  We can take our frame and combine it with linked lists to form an environment.  It is more informative (and closer to the actual design) to view environments from the point of view of eval.  This diagram is a view of the environment structure when the code (+ x y z) is evaluated.</p>
<p><img src="https://docs.google.com/drawings/pub?id=1RkD5O0pGCY08TLdkPzRIIp0fsxkPrB7z2vXqY37ZyZs&amp;w=580&amp;h=568"></p>
<p>I used the names <strong>current-environment</strong> to refer to the inner-func environment and <strong>enclosing-environment</strong> to refer to the outer-func environment.  We will use these same names in our source code.  Note that the <strong>global-environment</strong> is just the <strong>enclosing-environment</strong> of outer-func, the only thing special about it is that its <strong>enclosing-environment</strong> is the empty list.</p>
<p>In addition we need to replace our global frame with <strong>the-global-environment</strong>, which we&#8217;ll do by providing a procedure <strong>extend-environment</strong>, and change <strong>lookup-symbol-value</strong> to check enclosing-environments if the symbol is not found.</p>
<pre class="brush: plain; highlight: [6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,29]; title: ; wrap-lines: false; notranslate">
(use srfi-69)

(define global-syntax-definitions (make-hash-table))
(define-record primitive function)

(define (current-environment env) (car env))
(define (enclosing-environment env) (cdr env))

(define (extend-environment bindings base-environment)
  (cons (alist-&gt;hash-table bindings) base-environment))

(define the-global-environment (extend-environment '() '()))

(define (set-symbol! symbol value)
  (hash-table-set! (current-environment the-global-environment) symbol value))

(define (lookup-symbol-value symbol environment)
  (if (null? environment)
    (error 'unbound-symbol &quot;Unbound symbol:  &quot; symbol)
    (if (hash-table-exists? (current-environment environment) symbol)
        (hash-table-ref (current-environment environment) symbol)
        (lookup-symbol-value symbol (enclosing-environment environment)))))

(define (self-evaluating? expr)
  (or (number? expr) (string? expr) (char? expr) (boolean? expr)))

(define (lispy-eval expr)
  (cond ((self-evaluating? expr) expr)
        ((symbol? expr) (lookup-symbol-value expr the-global-environment))
        (else
          (if (hash-table-exists? global-syntax-definitions (car expr))
              ((hash-table-ref global-syntax-definitions (car expr)) (cdr expr))
              (lispy-apply (lispy-eval (car expr)) (eval-arguments (cdr expr)))))))

(define (eval-arguments args)
  (map (lambda (x) (lispy-eval x)) args))

(define (lispy-apply procedure arguments)
  (if (primitive? procedure)
    (apply (primitive-function procedure) arguments)
    &quot;Error: Undefined procedure&quot;)) 

(hash-table-set! global-syntax-definitions 'scheme-syntax
  (lambda (expr)
    (hash-table-set! global-syntax-definitions (car expr) (eval (cadr expr)))))

(hash-table-set! global-syntax-definitions 'load
  (lambda (expr)
    (define f (open-input-file (car expr)))
    (let loop ((e (read f)))
      (if (equal? e #!eof) &quot;Successfully Loaded!&quot;
                           (begin
                             (lispy-eval e)
                             (loop (read f)))))))

((hash-table-ref global-syntax-definitions 'load) '(&quot;syntax.chicken&quot;))

(define (repl)
  (define input (read))
  (print &quot;;===&gt; &quot; (lispy-eval input))
  (repl))
</pre>
<pre class="brush: plain; gutter: false; title: ; notranslate">
(define a 5)
;===&gt; #&lt;unspecified&gt;
a
;===&gt; 5
</pre>
<p>To use the full potential of our new environments we are going to have to rewrite our program a little bit to pass them around correctly.  Since eval is the main method of dispatch for our interpreter we&#8217;ll supply our environment as an argument to eval.  We&#8217;ll also have to pass an environment variable to procedures like set-symbol! and lookup-symbol-value.  One final place we&#8217;ll need environments is in scheme-syntax, we&#8217;ll have to change the stored procedures there to use (lambda (expr env) &#8230;) instead of just (lambda (expr) &#8230;).</p>
<pre class="brush: plain; highlight: [14,15,27,29,32,44,48,53,56,60]; title: ; wrap-lines: false; notranslate">
(use srfi-69)

(define global-syntax-definitions (make-hash-table))
(define-record primitive function)

(define (current-environment env) (car env))
(define (enclosing-environment env) (cdr env))

(define (extend-environment bindings base-environment)
  (cons (alist-&gt;hash-table bindings) base-environment))

(define the-global-environment (extend-environment '() '()))

(define (set-symbol! symbol value env)
  (hash-table-set! (current-environment env) symbol value))

(define (lookup-symbol-value symbol environment)
  (if (null? environment)
    (error 'unbound-symbol &quot;Unbound symbol:  &quot; symbol)
    (if (hash-table-exists? (current-environment environment) symbol)
        (hash-table-ref (current-environment environment) symbol)
        (lookup-symbol-value symbol (enclosing-environment environment)))))

(define (self-evaluating? expr)
  (or (number? expr) (string? expr) (char? expr) (boolean? expr)))

(define (lispy-eval expr env)
  (cond ((self-evaluating? expr) expr)
        ((symbol? expr) (lookup-symbol-value expr env))
        (else
          (if (hash-table-exists? global-syntax-definitions (car expr))
              ((hash-table-ref global-syntax-definitions (car expr)) (cdr expr) env)
              (lispy-apply (lispy-eval (car expr)) (eval-arguments (cdr expr)))))))

(define (eval-arguments args)
  (map (lambda (x) (lispy-eval x)) args))

(define (lispy-apply procedure arguments)
  (if (primitive? procedure)
    (apply (primitive-function procedure) arguments)
    &quot;Error: Undefined procedure&quot;)) 

(hash-table-set! global-syntax-definitions 'scheme-syntax
  (lambda (expr env)
    (hash-table-set! global-syntax-definitions (car expr) (eval (cadr expr)))))

(hash-table-set! global-syntax-definitions 'load
  (lambda (expr env)
    (define f (open-input-file (car expr)))
    (let loop ((e (read f)))
      (if (equal? e #!eof) &quot;Successfully Loaded!&quot;
                           (begin
                             (lispy-eval e env)
                             (loop (read f)))))))

((hash-table-ref global-syntax-definitions 'load) '(&quot;syntax.chicken&quot;) the-global-environment)

(define (repl)
  (define input (read))
  (print &quot;;===&gt; &quot; (lispy-eval input the-global-environment))
  (repl))
</pre>
<p><strong>syntax.chicken</strong></p>
<pre class="brush: plain; highlight: [2,3,6,7,8,9,12]; title: ; notranslate">
(scheme-syntax define
  (lambda (expr env)
    (set-symbol! (car expr) (lispy-eval (cadr expr) env) env)))

(scheme-syntax if
  (lambda (expr env)
    (if (lispy-eval (car expr) env)
        (lispy-eval (cadr expr) env)
        (lispy-eval (caddr expr) env))))

(scheme-syntax define-primitive
  (lambda (expr env)
    (set-symbol! (car expr)
                 (make-primitive (eval (cadr expr))))))
</pre>
<pre class="brush: plain; gutter: false; title: ; notranslate">
(define a 5)
;===&gt; #&lt;unspecified&gt;
a
;===&gt; 5
</pre>
<p>If you still don&#8217;t fully understand environments, that&#8217;s OK.  You&#8217;ll get a chance to play around with them in the next part where we&#8217;ll finally cover implementing procedures in Lispy!</p>
<p><a href="http://nickzarr.com/blog4/2011/03/lispy-in-scheme-lispy-procedures/" title="Lispy in Scheme | Lispy Procedures">GOTO Part 7 | Lispy Procedures</a></p>
<p><a title="Lispy in Chicken" href="http://nickzarr.com/blog4/lispy-in-scheme/">GOTO Table of Contents</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/03/lispy-in-scheme-environments/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lispy in Scheme &#124; Primitive Procedures and apply</title>
		<link>http://nickzarr.com/blog4/2011/02/lispy-in-scheme-primitive-procedures-and-apply/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=lispy-in-scheme-primitive-procedures-and-apply</link>
		<comments>http://nickzarr.com/blog4/2011/02/lispy-in-scheme-primitive-procedures-and-apply/#comments</comments>
		<pubDate>Sun, 27 Feb 2011 00:25:51 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Lispy]]></category>
		<category><![CDATA[Chicken]]></category>
		<category><![CDATA[chicken scheme]]></category>
		<category><![CDATA[interpreter]]></category>
		<category><![CDATA[Language Design]]></category>
		<category><![CDATA[lispy in scheme]]></category>
		<category><![CDATA[meta-circular evaluator]]></category>
		<category><![CDATA[metacircular]]></category>
		<category><![CDATA[metacircular evaluator]]></category>
		<category><![CDATA[Scheme]]></category>
		<category><![CDATA[sicp]]></category>
		<category><![CDATA[structure and interpretation of computer programs]]></category>
		<category><![CDATA[write an interpreter]]></category>
		<category><![CDATA[writing a programming language]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=389</guid>
		<description><![CDATA[The goal for this part is to implement primitive procedures, apply and a method of setting new primitives. The first thing we need to do is figure out a way to represent our primitive procedures. SICP uses tagged lists, which are just regular lists with the first element designated as a tag. We&#8217;re going to [...]]]></description>
			<content:encoded><![CDATA[<p>The goal for this part is to implement primitive procedures, apply and a method of setting new primitives.</p>
<p>The first thing we need to do is figure out a way to represent our primitive procedures. <a href="http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-26.html#%_sec_4.1.3"> SICP</a> uses tagged lists, which are just regular lists with the first element designated as a tag.  We&#8217;re going to use define-record to define a primitive type, which is more flexible and a little easier to use.</p>
<p>If the symbol of an expression of the form (symbol args &#8230;) is not found in global-syntax-definitions it must be a primitive procedure application (or not exist).  To apply a primitive procedure we evaluate all the arguments using lispy-eval.  We use that list as the args value to (apply primitive args).  The primitive returns a Lispy value and we continue on.</p>
<p>For now we&#8217;re going to hardcode one primitive + into our interpreter.  We&#8217;ll come up with something a little more elegant next.</p>
<pre class="brush: plain; highlight: [5,24,25,26,27,28,29,30,31,32,33,34]; title: ; wrap-lines: false; notranslate">
(use srfi-69)

(define global-syntax-definitions (make-hash-table))
(define frame (make-hash-table))
(define-record primitive function)

(define (set-symbol! symbol value)
  (hash-table-set! frame symbol value))

(define (lookup-variable-value symbol)
  (if (hash-table-exists? frame symbol)
      (hash-table-ref frame symbol)
      &quot;Error: Unbound variable&quot;))

(define (self-evaluating? expr)
  (or (number? expr) (string? expr) (char? expr) (boolean? expr)))

(define (lispy-eval expr)
  (cond ((self-evaluating? expr) expr)
        ((symbol? expr) (lookup-variable-value expr))
        (else
          (if (hash-table-exists? global-syntax-definitions (car expr))
              ((hash-table-ref global-syntax-definitions (car expr)) (cdr expr))
              (lispy-apply (lispy-eval (car expr)) (eval-arguments (cdr expr)))))))

(define (eval-arguments args)
  (map (lambda (x) (lispy-eval x)) args))

(define (lispy-apply procedure arguments)
  (if (primitive? procedure)
    (apply (primitive-function procedure) arguments)
    &quot;Error: Undefined procedure&quot;))

(set-symbol! '+ (make-primitive +))

(hash-table-set! global-syntax-definitions 'scheme-syntax
  (lambda (expr)
    (hash-table-set! global-syntax-definitions (car expr) (eval (cadr expr)))))

(hash-table-set! global-syntax-definitions 'load
  (lambda (expr)
    (define f (open-input-file (car expr)))
    (let loop ((e (read f)))
      (if (equal? e #!eof) &quot;Successfully Loaded!&quot;
                           (begin
                             (lispy-eval e)
                             (loop (read f)))))))

((hash-table-ref global-syntax-definitions 'load) '(&quot;syntax.chicken&quot;))

(define (repl)
  (define input (read))
  (print &quot;;&gt;&gt;&gt; &quot; (lispy-eval input))
  (repl))

(repl)
</pre>
<pre class="brush: plain; title: ; notranslate">
(+ 3 4)
;===&gt; 7
(- 3 4)
;===&gt; Error: Undefined procedure
</pre>
<p>The next step is to open up that functionality to Lispy.  We&#8217;ll implement define-primitive as a scheme-syntax macro.  First remove the line that sets the + symbol.  We&#8217;re only going to be modifying the syntax.chicken file for now so that&#8217;s all I&#8217;ll show you.</p>
<p>We need to create a scheme-syntax macro that makes a procedure type and sets it as the value of a symbol.  This macro is a lot like the define macro that we wrote earlier.  The only difference is instead of calling lispy-eval on the cadr we call eval and pass that result to make-primitive.</p>
<p>syntax.chicken</p>
<pre class="brush: plain; highlight: [11,12,13,14]; title: ; notranslate">
(scheme-syntax define
  (lambda (expr)
    (set-symbol! (car expr) (lispy-eval (cadr expr)))))

(scheme-syntax if
  (lambda (expr)
    (if (lispy-eval (car expr))
        (lispy-eval (cadr expr))
        (lispy-eval (caddr expr)))))

(scheme-syntax define-primitive
  (lambda (expr)
    (set-symbol! (car expr)
                 (make-primitive (eval (cadr expr))))))
</pre>
<p>With that we can define all sorts of primitives for our language&#8230;</p>
<pre class="brush: plain; title: ; notranslate">
(repl)
(define-primitive + +)
;===&gt; #&lt;unspecified&gt;
(+ 3 4)
;===&gt; 7
(- 3 4)
;===&gt; Error: Undefined procedure

(define-primitive - -)
;===&gt; #&lt;unspecified&gt;
(- 3 4)
;===&gt; -1

(define-primitive square (lambda (x) (* x x)))
;===&gt; #&lt;unspecified&gt;
(square 4)
;===&gt; 16
</pre>
<p>You can start a new file and define a bunch of primitives, load it the same way you load syntax.chicken.  I&#8217;m not going to define any primitives just yet but you are more than welcome to.  Instead in the next post we&#8217;ll implement environments and then it&#8217;s on to implementing lambda!</p>
<p><a href="http://nickzarr.com/blog4/2011/03/06/lispy-in-scheme-environments/">GOTO Part 6 &#8211; Environments</a></p>
<p><a title="Lispy in Chicken" href="http://nickzarr.com/blog4/lispy-in-scheme/">GOTO Table of Contents</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/02/lispy-in-scheme-primitive-procedures-and-apply/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lispy in Scheme &#124; Refactor and load</title>
		<link>http://nickzarr.com/blog4/2011/02/lispy-in-scheme-refactor-and-load/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=lispy-in-scheme-refactor-and-load</link>
		<comments>http://nickzarr.com/blog4/2011/02/lispy-in-scheme-refactor-and-load/#comments</comments>
		<pubDate>Sat, 26 Feb 2011 10:25:04 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Lispy]]></category>
		<category><![CDATA[Chicken]]></category>
		<category><![CDATA[chicken scheme]]></category>
		<category><![CDATA[interpreter]]></category>
		<category><![CDATA[Language Design]]></category>
		<category><![CDATA[lispy in scheme]]></category>
		<category><![CDATA[meta-circular evaluator]]></category>
		<category><![CDATA[metacircular]]></category>
		<category><![CDATA[metacircular evaluator]]></category>
		<category><![CDATA[Scheme]]></category>
		<category><![CDATA[sicp]]></category>
		<category><![CDATA[structure and interpretation of computer programs]]></category>
		<category><![CDATA[write an interpreter]]></category>
		<category><![CDATA[writing a programming language]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=363</guid>
		<description><![CDATA[In the last part I said that we were going to be doing some refactoring. Let&#8217;s start with a little of that and a recap. The first thing that we&#8217;re going to do is remove define and if from our language. We&#8217;ll put them back in later, but first let&#8217;s look at what our language [...]]]></description>
			<content:encoded><![CDATA[<p>In the last part I said that we were going to be doing some refactoring.  Let&#8217;s start with a little of that and a recap.  The first thing that we&#8217;re going to do is remove define and if from our language.  We&#8217;ll put them back in later, but first let&#8217;s look at what our language looks like with only scheme-syntax defined.</p>
<pre class="brush: plain; title: ; wrap-lines: false; notranslate">
(use srfi-69)

(define global-syntax-definitions (make-hash-table))
(define frame (make-hash-table))

(define (set-symbol! symbol value)
  (hash-table-set! frame symbol value))

(define (lookup-variable-value symbol)
  (if (hash-table-exists? frame symbol)
      (hash-table-ref frame symbol)
      &quot;Error: Unbound variable&quot;))

(define (self-evaluating? expr)
  (or (number? expr) (string? expr) (char? expr) (boolean? expr)))

(define (lispy-eval expr)
  (cond ((self-evaluating? expr) expr)
        ((symbol? expr) (lookup-variable-value expr))
        (else
          (if (hash-table-exists? global-syntax-definitions (car expr))
              ((hash-table-ref global-syntax-definitions (car expr)) (cdr expr))
              &quot;Not implemented&quot;))))

(hash-table-set! global-syntax-definitions 'scheme-syntax
  (lambda (expr)
    (hash-table-set! global-syntax-definitions (car expr) (eval (cadr expr)))))

(define (repl)
  (define input (read))
  (print &quot;;===&gt; &quot; (lispy-eval input))
  (repl))
</pre>
<p>Let&#8217;s take a moment to consider what these 25 lines of code can do.  We now have a language that can understand self-evaluating Scheme values and lookup symbol values.  In addition to that it has exactly one primitive, a macro that defines other primitives and gives us access to the underlying Scheme.</p>
<p>You may consider this language lacking, and I admit it does not have many features.  However it is now possible to define any language construct (including procedures, eval and apply) from within Lispy with the help of scheme-syntax and the Scheme underneath.  After writing these 25 lines we could define the rest of the language 100% from within Lispy.</p>
<p>However there are a few more things that conceptually belong in the core language.  One of those things is the ability to load a Lispy file.  This will let us break out our syntax definitions into another file and load it automatically before we start the repl.</p>
<pre class="brush: plain; highlight: [29,30,31,32,33,34,35,36]; title: ; wrap-lines: false; notranslate">
(use srfi-69)

(define global-syntax-definitions (make-hash-table))
(define frame (make-hash-table))

(define (set-symbol! symbol value)
  (hash-table-set! frame symbol value))

(define (lookup-variable-value symbol)
  (if (hash-table-exists? frame symbol)
      (hash-table-ref frame symbol)
      &quot;Error: Unbound variable&quot;))

(define (self-evaluating? expr)
  (or (number? expr) (string? expr) (char? expr) (boolean? expr)))

(define (lispy-eval expr)
  (cond ((self-evaluating? expr) expr)
        ((symbol? expr) (lookup-variable-value expr))
        (else
          (if (hash-table-exists? global-syntax-definitions (car expr))
              ((hash-table-ref global-syntax-definitions (car expr)) (cdr expr))
              &quot;Not implemented&quot;))))

(hash-table-set! global-syntax-definitions 'scheme-syntax
  (lambda (expr)
    (hash-table-set! global-syntax-definitions (car expr) (eval (cadr expr)))))

(hash-table-set! global-syntax-definitions 'load
  (lambda (expr)
    (define f (open-input-file (car expr)))
    (let loop ((e (read f)))
      (if (equal? e #!eof) &quot;Successfully Loaded!&quot;
                           (begin
                             (lispy-eval e)
                             (loop (read f)))))))

(define (repl)
  (define input (read))
  (print &quot;;===&gt; &quot; (lispy-eval input))
  (repl))
</pre>
<p>Now that we have load, we need something to load.  Create a new file called syntax.chicken, or whatever you prefer.  This is where we will define our primitive syntax forms like define, if and lambda.</p>
<pre class="brush: plain; highlight: [38]; title: ; wrap-lines: false; notranslate">
(use srfi-69)

(define global-syntax-definitions (make-hash-table))
(define frame (make-hash-table))

(define (set-symbol! symbol value)
  (hash-table-set! frame symbol value))

(define (lookup-variable-value symbol)
  (if (hash-table-exists? frame symbol)
      (hash-table-ref frame symbol)
      &quot;Error: Unbound variable&quot;))

(define (self-evaluating? expr)
  (or (number? expr) (string? expr) (char? expr) (boolean? expr)))

(define (lispy-eval expr)
  (cond ((self-evaluating? expr) expr)
        ((symbol? expr) (lookup-variable-value expr))
        (else
          (if (hash-table-exists? global-syntax-definitions (car expr))
              ((hash-table-ref global-syntax-definitions (car expr)) (cdr expr))
              &quot;Not implemented&quot;))))

(hash-table-set! global-syntax-definitions 'scheme-syntax
  (lambda (expr)
    (hash-table-set! global-syntax-definitions (car expr) (eval (cadr expr)))))

(hash-table-set! global-syntax-definitions 'load
  (lambda (expr)
    (define f (open-input-file (car expr)))
    (let loop ((e (read f)))
      (if (equal? e #!eof) &quot;Successfully Loaded!&quot;
                           (begin
                             (lispy-eval e)
                             (loop (read f)))))))

((hash-table-ref global-syntax-definitions 'load) '(&quot;syntax.chicken&quot;))

(define (repl)
  (define input (read))
  (print &quot;;===&gt; &quot; (lispy-eval input))
  (repl))
</pre>
<p>syntax.chicken</p>
<pre class="brush: plain; title: ; notranslate">
(scheme-syntax define
  (lambda (expr)
    (set-symbol! (car expr) (lispy-eval (cadr expr)))))

(scheme-syntax if
  (lambda (expr)
    (if (lispy-eval (car expr))
        (lispy-eval (cadr expr))
        (lispy-eval (caddr expr)))))
</pre>
<pre class="brush: plain; title: ; notranslate">
(repl)
(define a 5)
;===&gt; #&lt;unspecified&gt;
a
;===&gt; 5
(if 1 2 3)
;===&gt; 2
</pre>
<p>Now that we have implemented load we are one step closer to having a platform that we can build any language we want with.  To change languages all we would have to do is load a different syntax file.</p>
<p>I encourage you to play around with that concept for a little while.  Write two different syntax.chicken files and implement a couple of basic forms like define, or and if.  Try to make your two implementations as different as possible even if making it different doesn&#8217;t make sense.  For instance in one implementation if could take a mandatory keyword before the alternate branch (if pred consequent else alt) or it could act like and, taking two predicates and only evaluating the consequent branch if both predicates evaluate to true.</p>
<p>Since one of the goals of Lispy is to experiment with language features this ability will come in very useful.  In the future we will extend this concept to make our interpreter more of a language platform than a language itself.</p>
<p>This article is a little short on code because we made some larger conceptual changes that I did not want to breeze past.  In the next article we&#8217;ll implement primitive procedures and apply.  The ability to define procedures from within Lispy is just around the corner.</p>
<p><a title="Lispy in Scheme | Primitive Procedures and apply" href="http://nickzarr.com/blog4/2011/02/26/lispy-in-scheme-primitive-procedures-and-apply/">GOTO Part 5 | Primitive Procedures and apply</a></p>
<p><a title="Lispy in Chicken" href="http://nickzarr.com/blog4/lispy-in-scheme/">GOTO Table of Contents</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/02/lispy-in-scheme-refactor-and-load/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lispy in Scheme &#124; scheme-syntax macro</title>
		<link>http://nickzarr.com/blog4/2011/02/scheme-syntax/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=scheme-syntax</link>
		<comments>http://nickzarr.com/blog4/2011/02/scheme-syntax/#comments</comments>
		<pubDate>Sat, 26 Feb 2011 02:57:57 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Lispy]]></category>
		<category><![CDATA[Chicken]]></category>
		<category><![CDATA[chicken scheme]]></category>
		<category><![CDATA[interpreter]]></category>
		<category><![CDATA[Language Design]]></category>
		<category><![CDATA[lispy in scheme]]></category>
		<category><![CDATA[meta-circular evaluator]]></category>
		<category><![CDATA[metacircular]]></category>
		<category><![CDATA[metacircular evaluator]]></category>
		<category><![CDATA[Scheme]]></category>
		<category><![CDATA[sicp]]></category>
		<category><![CDATA[structure and interpretation of computer programs]]></category>
		<category><![CDATA[write an interpreter]]></category>
		<category><![CDATA[writing a programming language]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=341</guid>
		<description><![CDATA[The goal for this part is to implement (if predicate consequent alternate). We&#8217;re going to start by implementing if the same way we implemented define. The first thing to do is test if the car of the pair equals if, then call apply-if. We know that if will have to evaluate the predicate argument to [...]]]></description>
			<content:encoded><![CDATA[<p>The goal for this part is to implement (if predicate consequent alternate).</p>
<p>We&#8217;re going to start by implementing if the same way we implemented define.  The first thing to do is test if the car of the pair equals if, then call apply-if.</p>
<p>We know that if will have to evaluate the predicate argument to determine whether to evaluate the consequent or alternate arguments.  If the predicate is true we will evaluate the consequent expression and not the alternate.  If the predicate is false we will evaluate the alternate expression and not the consequent.</p>
<pre class="brush: plain; highlight: [24,25,26,29,30,31,32]; title: ; wrap-lines: false; notranslate">
(use srfi-69)

(define frame (make-hash-table))

(define (set-symbol! symbol value)
  (hash-table-set! frame symbol value))

(set-symbol! 'test &quot;Value retrieved successfully&quot;)

(define (lookup-variable-value symbol)
  (if (hash-table-exists? frame symbol)
      (hash-table-ref frame symbol)
      &quot;Error: Unbound variable&quot;))

(define (self-evaluating? expr)
  (or (number? expr) (string? expr) (char? expr) (boolean? expr)))

(define (lispy-eval expr)
  (cond ((self-evaluating? expr) expr)
        ((symbol? expr) (lookup-variable-value expr))
        ((pair? expr)
          (if (equal? (car expr) 'define)
              (set-symbol! (cadr expr) (lispy-eval (caddr expr)))
              (if (equal? (car expr) 'if)
                  (apply-if (lispy-eval (cadr expr)) (caddr expr) (cadddr expr))
                  &quot;Not implemented&quot;)))
        (else &quot;Not implemented&quot;)))

(define (apply-if pred consequent alternate)
  (if pred
      (lispy-eval consequent)
      (lispy-eval alternate)))

(define (repl)
  (define input (read))
  (print &quot;;===&gt;&quot; (lispy-eval input))
  (repl))
</pre>
<pre class="brush: plain; title: ; notranslate">
(repl)
(if 1 2 3)
;===&gt; 2
</pre>
<p>Anyone who has ever used Scheme or Lisp is probably cringing at the use of nested ifs here, when I could have used a cond (like <a href="http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-26.html#%_sec_4.1.1">SICP</a>).  I did this to illustrate a point, using if or cond is fine while you have a small number of primitive syntax forms.  However once you implement a large number of primitive syntax forms this method of dispatch becomes cumbersome.  Also note that it is not possible to extend the primitive syntax forms except by modifying the original source by hand.</p>
<p>&nbsp;</p>
<h2>Reusing the Frame</h2>
<p>On top of that we have already implemented a mechanism of associating and storing symbol and value pairs.  Let&#8217;s try something like that first, we&#8217;ll start by making another global hash table called global-syntax-definitions.  Then we&#8217;ll modify eval to check these definitions.</p>
<pre class="brush: plain; highlight: [3,22,23,24,24,25,26,27,28,29,30,31,32,33,34,35]; title: ; wrap-lines: false; notranslate">
(use srfi-69)

(define global-syntax-definitions (make-hash-table))
(define frame (make-hash-table))

(define (set-symbol! symbol value)
  (hash-table-set! frame symbol value))

(set-symbol! 'test &quot;Value retrieved successfully&quot;)

(define (lookup-variable-value symbol)
  (if (hash-table-exists? frame symbol)
      (hash-table-ref frame symbol)
      &quot;Error: Unbound variable&quot;))

(define (self-evaluating? expr)
  (or (number? expr) (string? expr) (char? expr) (boolean? expr)))

(define (lispy-eval expr)
  (cond ((self-evaluating? expr) expr)
        ((symbol? expr) (lookup-variable-value expr))
        (else
          (if (hash-table-exists? global-syntax-definitions (car expr))
              ((hash-table-ref global-syntax-definitions (car expr)) (cdr expr))
              &quot;Not implemented&quot;))))

(hash-table-set! global-syntax-definitions 'define
  (lambda (expr)
    (set-symbol! (car expr) (lispy-eval (cadr expr)))))

(hash-table-set! global-syntax-definitions 'if
  (lambda (expr)
    (if (lispy-eval (car expr))
        (lispy-eval (cadr expr))
        (lispy-eval (caddr expr)))))

(define (repl)
  (define input (read))
  (print &quot;;===&gt;&quot; (lispy-eval input))
  (repl))
</pre>
<pre class="brush: plain; title: ; notranslate">
(repl)
(define a 5)
;===&gt; #&lt;unspecified&gt;
a
;===&gt; 5
(if 1 2 3)
;===&gt; 2
(hello)
;===&gt; Not implemented
</pre>
<p>With that addition we are finished with the first level of the eval function.  An expression can only be one of three things: self-evaluating, a symbol or an application (either syntax or procedure which we&#8217;ll cover later).</p>
<p>How does it work?  global-syntax-definitions is used to store anonymous procedures that each take a single argument (the rest of the expression after the name).  If a given symbol matches a key in global-syntax-definitions the value of that key is called with the unevaluated list of arguments as the only argument.</p>
<p>In other words, when lispy-eval comes across a primitive syntax definition it transfers control to a Scheme procedure located in the global-syntax-definitions table.  That Scheme procedure is responsible for evaluating the arguments and returning a Lispy value.</p>
<p>Now that we have a data structure to hold our global-syntax-definitions it would be a good idea to supply an easy mechanism to set a new syntax definition.  For this purpose we&#8217;ll design a macro in Lispy that will set a new syntax definition called scheme-syntax.</p>
<pre class="brush: plain; highlight: [27,28,29]; title: ; wrap-lines: false; notranslate">
(use srfi-69)

(define global-syntax-definitions (make-hash-table))
(define frame (make-hash-table))

(define (set-symbol! symbol value)
  (hash-table-set! frame symbol value))

(set-symbol! 'test &quot;Value retrieved successfully&quot;)

(define (lookup-variable-value symbol)
  (if (hash-table-exists? frame symbol)
      (hash-table-ref frame symbol)
      &quot;Error: Unbound variable&quot;))

(define (self-evaluating? expr)
  (or (number? expr) (string? expr) (char? expr) (boolean? expr)))

(define (lispy-eval expr)
  (cond ((self-evaluating? expr) expr)
        ((symbol? expr) (lookup-variable-value expr))
        (else
          (if (hash-table-exists? global-syntax-definitions (car expr))
              ((hash-table-ref global-syntax-definitions (car expr)) (cdr expr))
              &quot;Not implemented&quot;))))

(hash-table-set! global-syntax-definitions 'scheme-syntax
  (lambda (expr)
    (hash-table-set! global-syntax-definitions (car expr) (eval (cadr expr)))))

(hash-table-set! global-syntax-definitions 'define
  (lambda (expr)
    (set-symbol! (car expr) (lispy-eval (cadr expr)))))

(hash-table-set! global-syntax-definitions 'if
  (lambda (expr)
    (if (lispy-eval (car expr))
        (lispy-eval (cadr expr))
        (lispy-eval (caddr expr)))))

(define (repl)
  (define input (read))
  (print &quot;;===&gt;&quot; (lispy-eval input))
  (repl))
</pre>
<pre class="brush: plain; title: ; notranslate">
(repl)
(scheme-syntax quote (lambda (expr) (car expr)))
;===&gt; #&lt;unspecified&gt;
(quote (1 2 3))
;===&gt; (1 2 3)
(1 2 3)
;===&gt; Not implemented
</pre>
<p>With the addition of scheme-syntax it is now possible to write Scheme directly in Lispy.  Because of this we can now implement all of the primitive syntax forms in Lispy.  Some might consider this cheating, but eventually we&#8217;re going to want a way to interface with Chicken.  Why not implement it right away, use it, test it and make it solid by implementing everything else in it?  We&#8217;ll still have to make some modifications to the core interpreter to implement procedures and a load form later.</p>
<p>We haven&#8217;t even gotten to the mutually recursive yin-yang that is the eval/apply cycle yet.  However, thanks to piggy-backing on Chicken, we already have a somewhat useful language.  A language without procedures is a pretty bad one, so we&#8217;ll keep pressing on, but check out some of the things that are possible already&#8230;</p>
<pre class="brush: plain; title: ; notranslate">
(repl)
(scheme-syntax print
  (lambda (expr)
    (print (car expr))))
;===&gt; #&lt;unspecified&gt;
(scheme-syntax loop
  (lambda (expr)
    (let loop ((n (car expr)))
      (begin
        (lispy-eval (cadr expr))
        (if (&gt; n 0)
            (loop (- n 1)))))))
;===&gt; #&lt;unspecified&gt;
(loop 2 (print &quot;Hi&quot;))
;===&gt; Hi
;===&gt; Hi
;===&gt; Hi
;===&gt; #&lt;unspecified&gt;
</pre>
<p>In the next article we&#8217;ll do  a little refactoring, remove define and if from the core of the interpreter and implement a load function so we can remove our syntax definitions out of the main interpreter file.</p>
<p><a title="Lispy in Scheme | Refactor and load" href="http://nickzarr.com/blog4/2011/02/26/lispy-in-scheme-refactor-and-load/">GOTO Part 4 | Refactor and load</a></p>
<p><a title="Lispy in Chicken" href="http://nickzarr.com/blog4/lispy-in-scheme/">GOTO Table of Contents</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/02/scheme-syntax/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Lispy in Scheme &#124; Assignment and define</title>
		<link>http://nickzarr.com/blog4/2011/02/assignment-and-define/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=assignment-and-define</link>
		<comments>http://nickzarr.com/blog4/2011/02/assignment-and-define/#comments</comments>
		<pubDate>Fri, 25 Feb 2011 08:59:37 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Lispy]]></category>
		<category><![CDATA[Chicken]]></category>
		<category><![CDATA[chicken scheme]]></category>
		<category><![CDATA[interpreter]]></category>
		<category><![CDATA[Language Design]]></category>
		<category><![CDATA[lispy in scheme]]></category>
		<category><![CDATA[meta-circular evaluator]]></category>
		<category><![CDATA[metacircular]]></category>
		<category><![CDATA[metacircular evaluator]]></category>
		<category><![CDATA[Scheme]]></category>
		<category><![CDATA[sicp]]></category>
		<category><![CDATA[structure and interpretation of computer programs]]></category>
		<category><![CDATA[write an interpreter]]></category>
		<category><![CDATA[writing a programming language]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=301</guid>
		<description><![CDATA[Our goal in this part is to implement assignment via the form (define symbol value). There are three challenges to this goal. First we need to come up with a system to store symbol names and their values. Then we need to display those values when the symbol is eval&#8217;d. Finally we need to recognize [...]]]></description>
			<content:encoded><![CDATA[<p>Our goal in this part is to implement assignment via the form (define symbol value).  There are three challenges to this goal.  First we need to come up with a system to store symbol names and their values.  Then we need to display those values when the symbol is eval&#8217;d.  Finally we need to recognize the define form and set the value of its symbol.</p>
<p>&nbsp;</p>
<h2>Starting with a Stub</h2>
<p>To start with we need to modify our eval procedure to recognize symbols.  We&#8217;ll call a procedure lookup-variable-value that will eventually give the value of the symbol.  Right now we&#8217;ll just have it return a string stating our intentions.</p>
<pre class="brush: plain; highlight: [1,2,9]; title: ; notranslate">
(define (lookup-variable-value expr)
  &quot;Here's where we lookup the value of the symbol.&quot;)

(define (self-evaluating? expr)
  (or (number? expr) (string? expr) (char? expr) (boolean? expr)))

(define (lispy-eval expr)
  (cond ((self-evaluating? expr) expr)
        ((symbol? expr) (lookup-variable-value expr))
        (else &quot;Not implemented&quot;)))

(define (repl)
  (define input (read))
  (print &quot;;===&gt;&quot; (lispy-eval input))
  (repl))
</pre>
<pre class="brush: plain; title: ; notranslate">
(repl)
&quot;hello&quot;
;===&gt; hello
hi
;===&gt; Here's where we lookup the value of the symbol.
</pre>
<p>&nbsp;</p>
<h2>The Global Frame</h2>
<p>To set the value of a symbol we need to have somewhere to set it.  That somewhere is going to be a <a href="http://nickzarr.com/blog4/2011/02/20/what-in-the-hell-are-hash-tables/">hash table</a>.  The hash table that stores a set of names and their associated values is referred to as a frame.</p>
<p>For now we&#8217;ll define our frame as a global variable and also define a procedure set-variable! to set the value of a symbol.  Since we don&#8217;t have any method of assigning values to symbols yet, we define a symbol &#8220;test&#8221; when we make the frame so we can see if it works.</p>
<pre class="brush: plain; highlight: [1,3,5,6,8,11,12,13]; title: ; notranslate">
(use srfi-69)

(define frame (make-hash-table))

(define (set-symbol! symbol value)
  (hash-table-set! frame symbol value))

(set-symbol! 'test &quot;Value retrieved successfully&quot;)

(define (lookup-variable-value symbol)
  (if (hash-table-exists? frame symbol)
      (hash-table-ref frame symbol)
      &quot;Error: Unbound variable&quot;))

(define (self-evaluating? expr)
  (or (number? expr) (string? expr) (char? expr) (boolean? expr)))

(define (lispy-eval expr)
  (cond ((self-evaluating? expr) expr)
        ((symbol? expr) (lookup-variable-value expr))
        (else &quot;Not implemented&quot;)))

(define (repl)
  (define input (read))
  (print &quot;;===&gt;&quot; (lispy-eval input))
  (repl))
</pre>
<pre class="brush: plain; title: ; notranslate">
(repl)
test
;===&gt; Value retrieved successfully
hello
;===&gt; Error: Unbound variable
</pre>
<p>&nbsp;</p>
<h2>(define symbol value)</h2>
<p>Now that we can store and retrieve the value of a symbol, we need a way to do it from within Lispy.  Lispy uses the form (define symbol value) to define a new symbol or set the value of an existing symbol.</p>
<p>The form (define symbol value) is a pair (also a list, but all lists are also pairs) so the first step to detecting its usage is to look for pairs.  The next step is to check the symbol in the car of that pair (or the first item of the list), if that symbol is &#8220;define&#8221; we run the code to define a symbol.  For now we&#8217;ll just return a string stating our intentions.</p>
<pre class="brush: plain; highlight: [21,22,23,24]; title: ; notranslate">
(use srfi-69)

(define frame (make-hash-table))

(define (set-symbol! symbol value)
  (hash-table-set! frame symbol value))

(set-symbol! 'test &quot;Value retrieved successfully&quot;)

(define (lookup-variable-value symbol)
  (if (hash-table-exists? frame symbol)
      (hash-table-ref frame symbol)
      &quot;Error: Unbound variable&quot;))

(define (self-evaluating? expr)
  (or (number? expr) (string? expr) (char? expr) (boolean? expr)))

(define (lispy-eval expr)
  (cond ((self-evaluating? expr) expr)
        ((symbol? expr) (lookup-variable-value expr))
        ((pair? expr)
          (if (equal? (car expr) 'define)
              &quot;Set the value of the symbol.&quot;
              &quot;Not implemented&quot;))
        (else &quot;Not implemented&quot;)))

(define (repl)
  (define input (read))
  (print &quot;;===&gt;&quot; (lispy-eval input))
  (repl))
</pre>
<pre class="brush: plain; title: ; notranslate">
(repl)
test
;===&gt; Value retrieved successfully
(define a 1)
;===&gt; Set the value of the symbol.
(set a 1)
;===&gt; Not implemented
</pre>
<p>&nbsp;</p>
<h2>Setting the Value of Symbols</h2>
<p>To actually set the value of the symbol we need to get the arguments to define.  Getting the symbol argument is straightforward, however we need to eval the value argument as it might not be self-evaluating.</p>
<pre class="brush: plain; highlight: [23]; title: ; notranslate">
(use srfi-69)

(define frame (make-hash-table))

(define (set-symbol! symbol value)
  (hash-table-set! frame symbol value))

(set-symbol! 'test &quot;Value retrieved successfully&quot;)

(define (lookup-variable-value symbol)
  (if (hash-table-exists? frame symbol)
      (hash-table-ref frame symbol)
      &quot;Error: Unbound variable&quot;))

(define (self-evaluating? expr)
  (or (number? expr) (string? expr) (char? expr) (boolean? expr)))

(define (lispy-eval expr)
  (cond ((self-evaluating? expr) expr)
        ((symbol? expr) (lookup-variable-value expr))
        ((pair? expr)
          (if (equal? (car expr) 'define)
              (set-symbol! (cadr expr) (lispy-eval (caddr expr)))
              &quot;Not implemented&quot;))
        (else &quot;Not implemented&quot;)))

(define (repl)
  (define input (read))
  (print &quot;;===&gt;&quot; (lispy-eval input))
  (repl))
</pre>
<pre class="brush: plain; title: ; notranslate">
(repl)
(define a 5)
;===&gt; #&lt;unspecified&gt;
a
;===&gt; 5
</pre>
<p>In addition to being able to set symbols, we now have a glimpse into how basic forms (like define) are handled.  It really is no more complicated than checking the procedure name, evaluating the arguments that need to be, then passing the arguments to a Scheme procedure.</p>
<p>* To any Schemers that may be reading this:  I avoided implementing environments here for two reasons.  I wanted to show the simplest implementation possible and in an upcoming post we will transform our global frame into a lookup table for primitive syntax.</p>
<p><a title="Lispy in Chicken | scheme-syntax macro" href="http://nickzarr.com/blog4/2011/02/25/scheme-syntax/">GOTO Part 3 | scheme-syntax macro</a></p>
<p><a title="Lispy in Chicken" href="http://nickzarr.com/blog4/lispy-in-scheme/">GOTO Table of Contents</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/02/assignment-and-define/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lispy in Chicken &#124; Self-Evaluating Values</title>
		<link>http://nickzarr.com/blog4/2011/02/lispy-in-chicken-self-evaluating-values/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=lispy-in-chicken-self-evaluating-values</link>
		<comments>http://nickzarr.com/blog4/2011/02/lispy-in-chicken-self-evaluating-values/#comments</comments>
		<pubDate>Thu, 24 Feb 2011 05:29:20 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Lispy]]></category>
		<category><![CDATA[Chicken]]></category>
		<category><![CDATA[chicken scheme]]></category>
		<category><![CDATA[interpreter]]></category>
		<category><![CDATA[Language Design]]></category>
		<category><![CDATA[lispy in scheme]]></category>
		<category><![CDATA[meta-circular evaluator]]></category>
		<category><![CDATA[metacircular]]></category>
		<category><![CDATA[metacircular evaluator]]></category>
		<category><![CDATA[Scheme]]></category>
		<category><![CDATA[sicp]]></category>
		<category><![CDATA[structure and interpretation of computer programs]]></category>
		<category><![CDATA[write an interpreter]]></category>
		<category><![CDATA[writing a programming language]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=207</guid>
		<description><![CDATA[Lispy is a language that was invented to answer one question. How do I write my own programming language? My journey to the solution started with the meta-circular interpreter in SICP. I played with it and tweaked it a bit, but it seemed to me too much like cheating. I searched the internet and read [...]]]></description>
			<content:encoded><![CDATA[<p><a href="https://github.com/jacktrades/Lispy">Lispy</a> is a language that was invented to answer one question.  How do I write my own programming language?  My journey to the solution started with the meta-circular interpreter in SICP.  I played with it and tweaked it a bit, but it seemed to me too much like cheating.  I searched the internet and read everything I could find (most of it I didn&#8217;t understand at the time).  Finally I found a series called <a href="http://michaux.ca/articles/scheme-from-scratch-introduction">Scheme from Scratch</a> which details writing a Scheme interpreter in C.  Scheme from Scratch is written in the style of <a href="http://scheme2006.cs.uchicago.edu/11-ghuloum.pdf">An Incremental Approach to Compiler Construction</a>, where you have a working interpreter at each stage.</p>
<p>To force myself to come up with my own implementations, instead of just blindly reading through the series, I decided to write a version of Scheme that has some Python influences.  I wrote generic functions and list/vector/string comprehensions and I hooked up the Hans Boehm garbage collector to stop it from crashing all the time.</p>
<p>Writing Lispy in C was a fun, challenging and rewarding experience.  However as I began to answer my questions about how basic language features could be implemented, I began to have new questions.  I started wondering about sequence abstractions, parallel execution, optimization and code generation.  As my questions got more in depth I began to realize that C was not the easiest language for me to solve them in.</p>
<p>That leads us to Chicken.  Since Lispy is a language that is based on Scheme, why not write it in Scheme?  The advantages are obvious, we get a full blown reader (that we now only have to modify), compilation to C and tons of other features like macros.  Most of Lispy is simply syntax or functional extensions of Scheme and map directly into Scheme code.</p>
<p>This series will build Lispy incrementally.  Each stage of this process will generate a fully working, if not featureful, language.  Each stage we implement will be the simplest code possible to implement a feature.  Error handling or efficiency will not be a concern (though may be taken into account if absolutely necessary).  The interpreter that we will build borrows a lot from the meta-circular evaluator in <a href="http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-26.html#%_sec_4.1">The Structure and Interpretation of Computer Programs</a>.</p>
<p>You will need to install Chicken to follow along (this may work on other Schemes but that is not an objective for this series), if you&#8217;re running a recent version of Ubuntu you can get a fairly recent version of Chicken with apt-get or you can <a href="http://code.call-cc.org/">download it here</a>.  This series will build an interpreter that is similar to <a href="https://github.com/jacktrades/Scheme-Meta-Circular-Evaluator">this meta-circular evaluator</a> that I previously wrote.</p>
<p>&nbsp;</p>
<h2>A Simple Scheme Meta-Circular Evaluator</h2>
<p>The first thing we&#8217;re going to do is implement a REPL, also called an interpreter.  REPL stands for Read, Eval, Print Loop and that&#8217;s just what it does.  First the repl reads in an expression from stdin, then it evaluates the expression and prints the return value to stdout.  When it is finished with these tasks it loops and does it all again.  To get something up and running so we can play with it, let&#8217;s make a simple Chicken repl.</p>
<p>Most repls will print an indicator before the input line (&gt;&gt;&gt; in Python, #;1&gt; in Chicken).  Lispy will instead print an indicator before the output.  This makes sense for now because it lets us copy and paste interpreter sessions.  This will make our lives easier for now and is trivial to swap later.</p>
<pre class="brush: plain; title: ; notranslate">
(define (repl)
  (define input (read))
  (print &quot;;===&gt;&quot; (eval input))
  (repl))
</pre>
<pre class="brush: plain; title: ; notranslate">
(repl)
42
;===&gt; 42
&quot;hi&quot;
;===&gt; hi
(+ 2 2)
;===&gt; 4
</pre>
<p>Since Lispy is very close to Scheme in syntax we can continue to use the default (read) function for now.  The thing that we&#8217;re most interested in at the moment is the eval function and we need to implement that in order to start implementing everything else.</p>
<p>Our first version of eval will be as simple as possible.  We&#8217;ll simply echo the input back to the screen.  Our simple reader already understands basic Scheme data types such as integers, strings and lists.</p>
<pre class="brush: plain; highlight: [1,2,6]; title: ; notranslate">
(define (lispy-eval expr)
  expr)

(define (repl)
  (define input (read))
  (print &quot;;===&gt;&quot; (lispy-eval input))
  (repl))
</pre>
<pre class="brush: plain; title: ; notranslate">
(repl)
42
;===&gt; 42
&quot;hi&quot;
;===&gt; hi
(+ 2 2)
;===&gt; (+ 2 2)
</pre>
<p>&nbsp;</p>
<h2>A Language of Numbers</h2>
<p>The simplest language is a language of numbers.  Numbers are self-evaluating and we&#8217;re going to use native Chicken data types wherever possible to simplify implementation, so if the expression is a number we&#8217;ll just return it for now.</p>
<pre class="brush: plain; highlight: [2,3]; title: ; notranslate">
(define (lispy-eval expr)
  (cond ((number? expr) expr)
        (else &quot;Not implemented&quot;)))

(define (repl)
  (define input (read))
  (print &quot;;===&gt;&quot; (lispy-eval input))
  (repl))
</pre>
<pre class="brush: plain; title: ; notranslate">
(repl)
42
;===&gt; 42
&quot;hi&quot;
;===&gt; Not implemented
</pre>
<p>&nbsp;</p>
<h2>A Language of Self-Evaluating Values</h2>
<p>Continuing with our language of self-evaluating values is just as simple.  Booleans, strings and characters are also self-evaluating so we&#8217;ll add them now.  More complex data structures like hash tables are also self evaluating, however we&#8217;ll leave them for later.</p>
<p>To get something up and running quickly we&#8217;ll stick with the Scheme versions of these data types.  Eventually we will modify the boolean and string data types and will probably remove the character type completely.</p>
<pre class="brush: plain; highlight: [1,2,5]; title: ; notranslate">
(define (self-evaluating? expr)
  (or (number? expr) (string? expr) (char? expr) (boolean? expr)))

(define (lispy-eval expr)
  (cond ((self-evaluating? expr) expr)
        (else &quot;Not implemented&quot;)))

(define (repl)
  (define input (read))
  (print &quot;;===&gt;&quot; (lispy-eval input))
  (repl))
</pre>
<pre class="brush: plain; title: ; notranslate">
(repl)
42
;===&gt; 42
&quot;hi&quot;
;===&gt; hi
#t
;===&gt; #t
</pre>
<p>The first stage of our language is complete.  We now have a functional language of self-evaluating values.  Though one could argue exactly how functional it really is.  The next step along our path will be to introduce symbols and implement assignment.</p>
<p><a title="Lispy in Chicken | Assignment and define" href="http://nickzarr.com/blog4/2011/02/25/assignment-and-define/">GOTO Part 2 | Assignment and define</a></p>
<p><a title="Lispy in Chicken" href="http://nickzarr.com/blog4/lispy-in-scheme/">GOTO Table of Contents</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/02/lispy-in-chicken-self-evaluating-values/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Future of Lispy</title>
		<link>http://nickzarr.com/blog4/2011/02/the-future-of-lispy/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=the-future-of-lispy</link>
		<comments>http://nickzarr.com/blog4/2011/02/the-future-of-lispy/#comments</comments>
		<pubDate>Sat, 19 Feb 2011 10:05:23 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Lispy]]></category>
		<category><![CDATA[Language Design]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=69</guid>
		<description><![CDATA[Lispy is a Scheme/Python-like language written in C.  Lispy was the first interpreter I wrote in a low-level language and my first program ever written in C.  With this in mind, I consider Lispy to be a very successful project.  I learned a lot along the way, but mostly I learned that writing a language [...]]]></description>
			<content:encoded><![CDATA[<p><a href="https://github.com/jacktrades/Lispy">Lispy</a> is a Scheme/Python-like language written in C.  Lispy was the first interpreter I wrote in a low-level language and my first program ever written in C.  With this in mind, I consider Lispy to be a very successful project.  I learned a lot along the way, but mostly I learned that writing a language is a lot of work.</p>
<p>My general idea for Lispy was to have a system that behaved like Scheme, but looked and felt more like Python.  Most of the core functions in Lispy are generic and comprehensions play a large role in looping, though tail-recursion is still available in the general case.</p>
<p>However I&#8217;ve always wanted more from Lispy.  I really like the sequence abstractions and immutable data structures of Clojure.  I want to play around with lazy, concurrent and parallel evaluation.  However the idea of implementing all that in C is daunting to me.*</p>
<p>The solution is obvious.  Since Lispy is to be a Scheme-like language, and Scheme is a language that is designed for writing programming languages, the next version of Lispy will be written in Chicken Scheme.  It was a natural choice, and would have been my first, had I not done the original implementation for academic purposes.</p>
<p>The switch to Chicken should make it easier to scratch another itch of mine, compiling.  I can envision a number of paths to the compilation of Lispy, from macro compiling to Chicken all the way down to generating assembly.  I haven&#8217;t started laying out a plan for compilation yet, but my bet would be that Lispy will become a thin language layer on top of Chicken.</p>
<p>This new version will focus on extending the sequence/constructor concept to support lazy sequences, hash-tables and generic operations for all sequences.</p>
<p>There are three excerpts that I think succinctly describe the motivations behind Lispy.</p>
<blockquote><p>Programming languages should be designed not by piling feature on top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary.</p>
<p>- <a href="http://people.csail.mit.edu/jaffer/r4rs_2.html#SEC2">R4RS</a></p></blockquote>
<blockquote><p>Most data structures exist because of speed.  For example, many languages today have both strings and lists.  Semantically, strings are more or less a subset of lists in which the elements are characters.  So why do you need a separate data type? You don&#8217;t, really.  Strings only exist for efficiency.  But it&#8217;s lame to clutter up the semantics of the language with hacks to make programs run faster. Having strings in a language seems to be a case of premature optimization.</p>
<p>- <a href="http://www.paulgraham.com/hundred.html">Paul Graham &#8220;The Hundred-Year Language&#8221;</a></p></blockquote>
<blockquote><p>Thus, programs must be written for people to read, and only incidentally for machines to execute.</p>
<p>- <a href="http://mitpress.mit.edu/sicp/full-text/sicp/book/node3.html">SICP</a></p></blockquote>
<p>Lispy&#8217;s main goal is to make a language that is &#8220;shockingly inefficient&#8221; but also a joy to program in.  Lispy is at least a 10 year language.  Lispy is designed to be simple at the expense of efficiency.  Lispy is research, mainly research into the type of programming language that I want to use (as I haven&#8217;t quite figured that out yet).</p>
<p>Note that this post is to help encourage me to start developing this version.  I haven&#8217;t written any code yet.</p>
<p>* It may be that I&#8217;m just inexperienced with the language, but I prefer coding in Scheme.</p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/02/the-future-of-lispy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

