Angel \”Java\” Lopez on Blog

June 5, 2012

May 20, 2012

April 10, 2012

Lisp: Links, News And Resources (2)

Filed under: AjLisp, Functional Programming, Links, Lisp, Programming Languages — ajlopez @ 1:23 pm

Previous Post

More links and resource about one my favorites programming languages:

My implementations
http://ajlopez.wordpress.com/category/ajlisp/
http://code.google.com/p/ajlisp/ in C#, three flavors (classic, scheme-like, clojure-like (WIP))
https://github.com/ajlopez/AjLispRb in Ruby
https://github.com/ajlopez/AjLispJs in JavaScript
https://github.com/ajlopez/AjLispJv in Java

Ruby talks to AutoLISP · davidbl/acadhelper Wiki
https://github.com/davidbl/acadhelper/wiki/Ruby-talks-to-AutoLISP

The Emacs Problem | Irreal
http://irreal.org/blog/?p=384

How Emacs changed my life
http://www.slideshare.net/yukihiro_matz/how-emacs-changed-my-life
By Yukihiro "Matz", Ruby creator

cl-dcf – Common Lisp DSL Compiler Framework – Google Project Hosting
http://code.google.com/p/cl-dcf/

Clojure inventor Hickey now aims for Android
http://www.techworld.com.au/article/419328/clojure_inventor_hickey_now_aims_android/?fp=16&fpid=1 In an interview, Clojure founder Rich Hickey discusses future of the functional JVM language, including his mobile aspirations

BiwaScheme Blackboard
http://blackboard.biwascheme.org/
BiwaScheme Blackboard is a sandbox for BiwaScheme, a R6RS Scheme interpreter written in JavaScript.
You can edit, run and save Scheme code in your browser.

Can Your Programming Language Do This? – Joel on Software
http://www.joelonsoftware.com/items/2006/08/01.html
…Without understanding functional programming, you can’t invent MapReduce, the algorithm that makes Google so massively scalable. The terms Map and Reduce come from Lisp and functional programming. …

mtravers / heroku-cl-example
https://github.com/mtravers/heroku-cl-example
Example use of Heroku Common Lisp Buildpack

AI Algorithms, Data Structures, and Idioms in Prolog, Lisp, and Java
http://www.amazon.com/dp/0136070477

Calico Scheme – IPRE Wiki
http://calicoproject.org/Calico_Scheme
Calico Scheme is a new implementation of a Scheme-based language for Calico. It implements many core Scheme functions, but also adds some functionality to bring it into line with the other modern languages like Python and Ruby.

Multics Emacs History/Design/Implementation
http://www.multicians.org/mepap.html

Lisp REPL in Vendetta Online
http://www.a1k0n.net/2005/11/04/lisp-repl-vendetta-online.html
Vendetta Online has a Lisp environment (using SBCL) which controls much of its NPC behavior and will soon be in charge of generating player and NPC missions. Partly in order to get around some thread-safety issues, and partly for convenience we built an REPL into a secret chat channel. (it only responds to developer accounts)
See http://www.vendetta-online.com/
http://www.vendetta-online.com/h/help.html
Vendetta Online is a MMORPG (massively multiplayer online role-playing game) from Guild Software Inc

European Lisp Symposium
http://european-lisp-symposium.org/

IT Software Community – John W. Verity – LISP Is Back, and It’s Baaaaad!
http://www.itsoftwarecommunity.com/author.asp?doc_id=238067&section_id=1624

Why I love Common Lisp and hate Java « Piece of mine
http://kuomarc.wordpress.com/2012/01/27/why-i-love-common-lisp-and-hate-java/

Why I love Ruby (Part 1)
http://duckpunching.github.com/2011/02/26/why-i-love-ruby-part-1.html
Ruby was also developed slowly, and thoughtfully, from the ground up, using the best-of-the-best from multiple programming paradigms, and from the best-of-breed languages from each of those paradigms … (Smalltalk, Lisp, Perl)

What I want from my Common Lisp vendor and the Common Lisp community
http://groups.google.com/group/comp.lang.lisp/msg/4563e504dba92253?pli=1

fogus: Lisp in 32 lines of Ruby
http://blog.fogus.me/2012/01/25/lisp-in-40-lines-of-ruby/

ahefner: Fun with Lisp: Just Intonation and Microtonality
http://ahefner.livejournal.com/19604.html

ahefner: Lispm archaeology: Compiler Protocols
http://ahefner.livejournal.com/19280.html

Web, games, languages ~ jlongster.com
http://jlongster.com/2012/01/16/outlet-gets-a-personality.html

luciolang/lucio – GitHub
https://github.com/luciolang/lucio
Lucio is a Lisp-like language running on Ruby
for those of you younger readers or find lisp exotic and never know anything about it, you might try
https://plus.google.com/113859563190964307534/posts/Xw8M6WMeaDn

Emacs Lisp Basics
http://xahlee.org/emacs/elisp_basics.html
A guide to the CHICKEN compilation process – The Chicken Scheme wiki

http://wiki.call-cc.org/chicken-compilation-process
Homoiconic and “unrestricted” self modifying code + Is lisp really self modifying?

http://stackoverflow.com/questions/8490616/homoiconic-and-unrestricted-self-modifying-code-is-lisp-really-self-modifyin
Readable s-expressions and sweet-expressions home page: Infix and fewer parentheses in Lisp-like languages

http://www.dwheeler.com/readable/index.html
Many people find Lisp s-expressions hard to read as a programming notation. I’ve developed Lisp programs for decades, and though I can read s-expressions well, I remain dissatisfied with their syntactic limitations.

Eleven Theses on Clojure
http://www.tbray.org/ongoing/When/200x/2009/12/01/Clojure-Theses

M-expression – Wikipedia, the free encyclopedia
http://en.wikipedia.org/wiki/M-expression
In computer programming, M-expressions (or meta-expressions) were intended to be the expressions used to write functions in the Lisp programming language. Data to be manipulated using M-expressions was to be written using S-expressions. M-expressions were used for the original theoretical language in early papers about Lisp, but the first working implementation of Lisp interpreted encodings of M-expressions as S-expressions, and M-expressions were never actually implemented.

My Links
http://delicious.com/ajlopez/lisp

Keep tuned!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

December 15, 2011

AjLisp in Ruby (2) Context with Name and Values

Previous Post

One of the first classes I implemented in AjLispRb is the environment. This time I called it a context: a dictionary where to save name/values, to store the atom values. The code:

module AjLisp
class Context
    def initialize(parent = nil)
        @parent = parent
        @values = Hash.new
    end
    
    def getValue(name)
        if @values.has_key?(name)
            return @values[name]
        end
        
        if @parent != nil
            return @parent.getValue(name)
        end
        
        return nil
    end
    
    def setValue(name, value)
        @values[name] = value
    end
end
end

The class was coded using TDD, the first tests at test/test_context.rb. Some tests:

def test_not_defined_is_nil
    context = AjLisp::Context.new
    assert_nil(context.getValue(:foo))
end
def test_set_and_get_value
    context = AjLisp::Context.new
    context.setValue(:foo, "bar")
    assert_equal("bar", context.getValue(:foo))
end
def test_get_value_from_parent
    parent = AjLisp::Context.new
    parent.setValue(:foo, "bar")
    context = AjLisp::Context.new(parent)
    assert_equal("bar", context.getValue(:foo))
end

Initially, I used strings for names, but now I'm using Ruby symbols like :foo. I have a test that ensures the independence of parent and child context values:

def test_override_value_from_parent
    parent = AjLisp::Context.new
    parent.setValue(:foo, "bar")
    context = AjLisp::Context.new(parent)
    context.setValue(:foo, "bar2")
    assert_equal("bar2", context.getValue(:foo))
    assert_equal("bar", parent.getValue(:foo))
end

Each context can have a parent. There is a top context, defined in lib/ajlisp.rb:

module AjLisp
@context = Context.new
@context.setValue :quote, FPrimitiveQuote.instance
@context.setValue :first, PrimitiveFirst.instance
@context.setValue :rest, PrimitiveRest.instance
@context.setValue :cons, PrimitiveCons.instance
@context.setValue :list, PrimitiveList.instance
@context.setValue :lambda, FPrimitiveLambda.instance
@context.setValue :flambda, FPrimitiveFLambda.instance
@context.setValue :mlambda, FPrimitiveMLambda.instance
@context.setValue :let, FPrimitiveLet.instance
@context.setValue :define, FPrimitiveDefine.instance
@context.setValue :do, FPrimitiveDo.instance
@context.setValue :if, FPrimitiveIf.instance
@context.setValue :definef, FPrimitiveDefinef.instance
@context.setValue :definem, FPrimitiveDefinem.instance
@context.setValue :+, PrimitiveAdd.instance
@context.setValue :-, PrimitiveSubtract.instance
@context.setValue :*, PrimitiveMultiply.instance
@context.setValue :/, PrimitiveDivide.instance
def self.context
    return @context
end
# ...
end

New context are created in many primitives. At the begin, there is a top context like:

If you have a defined form that returns the second element of a list:

(define second (a) (first (rest a)))

now you have a top context with the new slot:

The top context has a new slot named second with a lambda value (lambda (a) (first (rest a))

When you invoke:

(second (quote (one two three)))

during the invocation a new context is created, its parent set to the top context, and having a new name/value pair:

That context is discarded after second evaluation (unless the context were referenced by recently created closure, details in upcoming post). When you define a simple value:

(define one 1)

the top context is modified, to have a new name/value pair:

Next topics: primitives and special form primitives, their invocation, closures, macros, native methods invocation.

Keep tuned!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

December 2, 2011

AjLisp in Ruby (1) Structure, Classes and Tests

Filed under: AjLisp, Lisp, Programming Languages, Ruby, Test-Driven Development — ajlopez @ 10:57 am

Next Post

I’m learning and practicing Ruby writing my AjLisp interpreter, as usual (early this year, I ported it to Javascript). TDD is my friend: write a test, run in red, code, run in green, refactor, and so on. My code, work in progress, is at:

https://github.com/ajlopez/AjLispRb

Initially, I wrote a single file, following the great and simple example:

http://kanemar.com/2006/03/04/screencast-of-test-driven-development-with-ruby-part-1-a-simple-example/

Notice that Ruby has a ‘test/unit’ package, already in place, ready to use, after installation. After some research, I spitted the file in production code, and test code. I want to build a gem (Ruby package), so I studied the tutorial:

http://guides.rubygems.org/

I have pending readings:

http://speakerdeck.com/u/pat/p/cut-polish-a-guide-to-crafting-gems
http://blog.thepete.net/2010/11/creating-and-publishing-your-first-ruby.html

My code is not a gem, yet. But it have some gem structure:

The lib contains a single file:

require 'ajlisp/list.rb'
require 'ajlisp/named_atom.rb'
require 'ajlisp/context.rb'
require 'ajlisp/string_source.rb'
require 'ajlisp/token.rb'
require 'ajlisp/lexer.rb'
require 'ajlisp/parser.rb'
require 'ajlisp/primitive.rb'
require 'ajlisp/primitive_first.rb'
require 'ajlisp/primitive_rest.rb'
require 'ajlisp/primitive_cons.rb'
require 'ajlisp/primitive_list.rb'
require 'ajlisp/primitive_closure.rb'
require 'ajlisp/fprimitive.rb'
require 'ajlisp/fprimitive_quote.rb'
require 'ajlisp/fprimitive_lambda.rb'
require 'ajlisp/fprimitive_flambda.rb'
require 'ajlisp/fprimitive_let.rb'
require 'ajlisp/fprimitive_closure.rb'
require 'ajlisp/fprimitive_define.rb'
require 'ajlisp/primitive_add.rb'
module AjLisp
@context = Context.new
@context.setValue "quote", FPrimitiveQuote.instance
@context.setValue "first", PrimitiveFirst.instance
@context.setValue "rest", PrimitiveRest.instance
@context.setValue "cons", PrimitiveCons.instance
@context.setValue "list", PrimitiveList.instance
@context.setValue "lambda", FPrimitiveLambda.instance
@context.setValue "flambda", FPrimitiveFLambda.instance
@context.setValue "let", FPrimitiveLet.instance
@context.setValue "define", FPrimitiveDefine.instance
@context.setValue "+", PrimitiveAdd.instance
def self.context
    return @context
end
def self.evaluate(context, item)
    if item.is_a? List or item.is_a? NamedAtom
        return item.evaluate(context)
    end

    return item
end
end

I wrote some primitives (normal forms, and special forms: the latter don’t evaluate their parameters before apply, like quote or define). Notice that the additional files are in a subfolder ajlisp inside lib, why? Because when this code is installed as a gem, all lib file code could be include with require(‘thenameofrubyfile’). If I put other files than ajlisp.rb, i.e. list.rb or atom.rb, those file names could be required, and maybe a name collision with other gems could occur. Then, the recommended practice (see other gem code in your Ruby installation folder) is to put additional files below lib folder.

In the test folder there is a top test.rb file that includes other test files:

require 'ajlisp'
require 'test/unit'
require "test_list.rb"
require "test_named_atom.rb"
require "test_context.rb"
require "test_string_source.rb"
require "test_token.rb"
require "test_lexer.rb"
require "test_parser.rb"
require "test_primitive_first.rb"
require "test_primitive_rest.rb"
require "test_primitive_cons.rb"
require "test_primitive_list.rb"
require "test_primitive_closure.rb"
require "test_primitive_add.rb"
require "test_fprimitive_quote.rb"
require "test_fprimitive_lambda.rb"
require "test_fprimitive_let.rb"
require "test_fprimitive_closure.rb"
require "test_fprimitive_flambda.rb"
require "test_fprimitive_define.rb"
require "test_evaluate"

so you can run the tests from command line:

ruby –Ilib;test test\test.rb

If you have Windows, the runtest.cmd file contains this line.

Some test code:

require 'ajlisp'
require 'test/unit'
class TestList < Test::Unit::TestCase
#... 
    def test_create_with_first
        list = AjLisp::List.new("foo")
        assert_equal("foo", list.first)
        assert_nil(list.rest)
    end

    def test_create_with_first_and_rest
        rest = AjLisp::List.new("bar")
        list = AjLisp::List.new("foo", rest)
        assert_equal("foo", list.first)
        assert_not_nil(list.rest)
        assert_equal("bar", list.rest.first)
        assert_nil(list.rest.rest)
    end

    def test_create_from_array
        list = AjLisp::List.make [1, "a", "foo"]
        assert_not_nil list
        assert_equal 1, list.first
        assert_equal "a", list.rest.first
        assert_equal "foo", list.rest.rest.first
        assert_nil list.rest.rest.rest
    end
#..
end

Every list is an object of this class, list.rb:

module AjLisp
class List
    attr_reader :first
    attr_reader :rest

    def initialize(first=nil, rest=nil)
        @first = first
        @rest = rest
    end

    def evaluate(context)
        form = AjLisp::evaluate(context, @first)
        form.evaluate(context, self)
    end

    def self.make(array)
        if array and array.length > 0
            first = array.shift

            if first.is_a? Array
                first = make(first)
            elsif first.is_a? Symbol
                first = NamedAtom.new first.to_s
            end

            return List.new first, make(array)
        end 

        return nil
    end
end
end

The accessors first and rest are read-only. Thanks to the untyped nature of Ruby (like in Javascript) the implementation of this interpreter is straightforward, or without much code ceremony, at least.

In my new tests, I included the code into the AjLisp module, so I don’t need to write AjLisp:: prefix before referencing a class:

require 'ajlisp'
require 'test/unit'
module AjLisp
class TestLexer < Test::Unit::TestCase
    def test_get_atom_token
        source = StringSource.new "atom"
        lexer = Lexer.new source
        token = lexer.nextToken

        assert_not_nil token
        assert_equal "atom", token.value
        assert_equal TokenType::ATOM, token.type
        assert_nil lexer.nextToken
    end
    def test_get_atom_token_with_spaces
        source = StringSource.new " atom "
        lexer = Lexer.new source
        token = lexer.nextToken

        assert_not_nil token
        assert_equal "atom", token.value
        assert_equal TokenType::ATOM, token.type
        assert_nil lexer.nextToken
    end
#...
end

Next topics: some implementation details, primitives vs fprimitives, context (nested environments with name/values), lambda and closures, lexer and parser.

Next steps: complete primitives (let, letrec, definef, do, if…), macro (mlambda, definem, macro expansion…)

Keep tuned!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

September 5, 2011

AjLisp in Javascript (Part 3) Define, Lambda and Closures

Previous Post

Lets review the new forms definition in AjLisp, my Lisp interpreter written in Javascript (github repository). A key special form in AjLispJs, is define form:

var defineForm = new SpecialForm();
defineForm.eval = function eval(list, env)
{
	var name = list.first().name();
	var value = list.rest().first();
	var body = list.rest().rest();
		
	if (isNil(body)) {
		value = evaluate(value, env);
	}
	else {
		value = new Closure(value, env, body);
	}		
		
	environment[name] = value;
	return value;
}

You can use to define simple global data. My initial tests:

test("Evaluate Simple Expression with Atoms", function() {
	eval("(define one 1)");
	eval("(define two 2)");
	eval("(define three 3)");
	equal(eval("one"), 1);
	equal(eval("(quote one)").asString(), "one");
	equal(eval("(list one two three)").asString(), "(1 2 3)");
	equal(eval("(first (list one two three))"), 1);
	equal(eval("(rest (list one two three))").asString(), "(2 3)");
	equal(eval("(cons one (list two three))").asString(), "(1 2 3)");
});
		

But define is prepared to accept three parameters:

(define mapfirst (fn lst)
  (if (nilp lst)
    nil
    (cons
      (fn (first lst))
      (mapfirst fn (rest lst))
    )
  )
)

The first parameter is the name of the global environment property. The second is a list of parameters. The third is the form to apply. Define is used to define new functions. It’s equivalent to

(define mapfirst (lambda (fn lst)
    (if (nilp lst)
      nil
      (cons
        (fn (first lst))
        (mapfirst fn (rest lst))
      )
    )
  )
)

Note the lambda. It is an special form:

var lambdaForm = new SpecialForm();
lambdaForm.eval = function eval(list, env)
{
    var argnames = list.first();
    var body = list.rest();
    return new Closure(argnames, env, body);
}

Both define (with three parameters) and lambda create a Closure. The closure receives a list of argument names, a closure environment and a body. Then, when a closure is evaluated:

function Closure(argnames, closureenv, body) {
	body = new List(doForm, body);
	
	this.eval = function(args, environment) {
		var newenv = makeEnvironment(argnames, args, closureenv);
		return evaluate(body, newenv);
	};
}
	
Closure.prototype.evaluate = Form.prototype.evaluate;
Closure.prototype.apply = Form.prototype.apply;

The key part is the .eval: closure evaluation employs a new environment, based not in the current environment, but in the closureenv, the environment received in the constructor when the closure was created. This is a typical implementation in Lisp interpreter.

Next topics to discuss in upcoming posts: flambda, mlambda, macro evaluation, parser.

Keep tuned!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

August 30, 2011

AjLisp in Javascript (Part 2) List Evaluation, Forms and Special Forms

Filed under: AjLisp, JavaScript, Lisp, Open Source Projects, Programming Languages — ajlopez @ 10:16 am

Previous Post
Next Post

In the previous post I presented the structure and creation of atoms and list. But, how a list is evaluated in AjLisp? As in other lisp implementation, the head of the list points to something (form or special form) to apply to the rest of the elements. This is the initial code in list evaluation:

List.prototype.evaluate = function(environment) 
{
    var form = this.first().evaluate(environment);		
    return form.apply(this, environment);
}	

The head should be an element with .apply as method. There are two kinds of form: normal form and special forms. The form implementation:

function Form() {
}
Form.prototype.evaluate = function(environment) { return this; }
Form.prototype.apply = function(list, environment) 
{ 
    if (isNil(list)) return this.eval(list, environment);
    var rest = list.rest();
    if (rest != null)
        rest = rest.evaluateList(environment);
    return this.eval(rest, environment); 
}

The special form implementation:

function SpecialForm() {
}
SpecialForm.prototype.evaluate = function(environment) { return this; }
SpecialForm.prototype.apply = function(list, environment) 
{ 
    if (isNil(list)) return this.eval(list, environment);
    return this.eval(list.rest(), environment);
}

The difference? The elements of the rest of the list ARE EVALUATED in a normal form. An special form doesn't evaluate them. Why? Because the special form are “primitives” like (if <cond> <then> <else>…) where the <then> <else>… parts should be evaluated under control of the special form. See:

Special Forms in Lisp

Special forms are those expressions in the Lisp language which do not follow normal rules for evaluation. Some such forms are necessary as primitives of the language, while others may be desirable in order to improve readability, control the evaluation environment, implement abstraction and modularity, affect the flow of control, allow extended scoping mechanisms, define functions which accept a variable number of arguments, or achieve greater efficiency. There exist several long-standing mechanisms for specifying the definition of special forms: FEXPR's, NLAMBDA's, and MACRO's.

Form examples? I wrote new forms using instances, overriding their eval method:

var listForm = new Form();
listForm.eval = function eval(list) 
{
	return list;
}
var nilpForm = new Form();
nilpForm.eval = function eval(list) 
{
	if (isNil(list))
		return true;
		
	return isNil(list.first());
}
var listpForm = new Form();
listpForm.eval = function eval(list) 
{
	if (isNil(list))
		return true;
		
	return isList(list.first());
}

An special form example, the ‘if’:

var ifForm = new SpecialForm();
ifForm.eval = function eval(list, env)
{
	var cond = evaluate(list.first(), env);
	var then = list.rest().first();
	var elsebody = list.rest().rest();
	
	if (!isNil(cond) && cond != false)
		return evaluate(then, env);
	while (!isNil(elsebody)) 
	{
		result = evaluate(elsebody.first(), env);
		elsebody = elsebody.rest();
	}
	
	return result;			
}

They are exposed in the global environment:

// Environment
var environment = new Environment();
environment.list = listForm;
environment.first = firstForm;
environment.rest = restForm;
environment.cons = consForm;
environment['do'] = doForm;
environment['if'] = ifForm;
// more settings in environment

Topics for upcoming posts: environments, closures, lambdas, macros.

Keep tuned!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

August 19, 2011

AjLisp in Javascript (Part 1) Atoms, Lists and TDD

Filed under: AjLisp, JavaScript, Lisp, QUnit, Test-Driven Development — ajlopez @ 10:59 am

Next Post

I’m rewriting my AjLisp interpreter using Javascript. I think that a Lisp interpreter is a good project to learn a language: simple, bounded but not trivial. I would never have begun this project without TDD (Test-Driven Development): Javascript is so dynamic and the tools I’m using (the browser, plain text editors) are so limited, that this project have been hard without the help of TDD. The practice of TDD gives me fun, doing baby steps and it helps me to explore good design.

The code (with parser, many primitive forms, some macro procession, work in progress) is at GitHub:

https://github.com/ajlopez/AjLispJs

The code is in one file: https://github.com/ajlopez/AjLispJs/blob/master/src/ajlisp.js

I’m using QUnit for tests:

The implementation uses the namespace pattern:

AjLisp = function() {
// ...
}();

The namespace is the result of evaluate a function. This function returns an object with the public members of the namespace:

return {
	// Classes
	List: List,
	Environment: Environment,
	Atom: Atom,
	Closure: Closure,
	Lexer: Lexer,
	TokenType: TokenType,
	Parser: Parser,
	
	// Functions
	makeList: makeList,
	isAtom: isAtom,
	isList: isList,
	isNil: isNil,
	asString: asString,
	evaluate: evaluate,
	
	// Top Environment
	environment: environment
}

As usual, a Lisp interpreter should support lists and atoms. Partial code:

function List(first, rest) {
	function getFirst() {
		return first;
	}
	
	function getRest() {
		return rest;
	}
	
	this.first = getFirst;
	this.rest = getRest;
}
List.prototype.isAtom = function() { return false; }
List.prototype.isList = function() { return true; }
List.prototype.evaluate = function(environment) 
{
	var form = this.first().evaluate(environment);		
	return form.apply(this, environment);
}	
// ...

Note that the first and rest part of a list are encapsulated in the constructor closure. They are inmutable, and can be accesed by functions aList.first(), aList.rest(). I should evaluate the impact of all those closure at list construction. But they are relative light.

Atom implementation is simple:

function Atom(name) {
	this.evaluate = function(environment) {
		return environment.getValue(name);
	};
	
	this.name = function() { return name; };
}
Atom.prototype.isAtom = function() { return true; }
Atom.prototype.isList = function() { return false; }
Atom.prototype.asString = function() { return this.name(); }
Atom.prototype.equals = function(atom)
{
	if (isNil(atom) || !isAtom(atom))
		return false;
		
	return this.name() == atom.name();
}

The atom evaluation is based in an enviroment (association of names to values) and the atom name. Numbers, strings are direct Javascript objects and they don't need to be implemented as atoms. In a “classical” Lisp implementation, all elements are SExpressions (symbolic expressions) capable of being evaluated. Now, I have AjLisp.evaluate that accepts any Javascript object and detect if it can be evaluated in an environment:

function evaluate(x, environment)
{
	if (x === null || x === undefined)
		return x;
		
	if (x.evaluate != undefined && typeof(x.evaluate) == "function")
		return x.evaluate(environment);
		
	return x;
}

Atom tests:

test("Atom", function() {
	var environment = new AjLisp.Environment();
	environment.setValue("one", 1);
	var one = new AjLisp.Atom("one");
	equal(one.evaluate(environment), 1);
	ok(one.isAtom());
	equal(one.isList(), false);
	ok(AjLisp.isAtom(one));
	equal(AjLisp.isList(one), false);
	equal(one.asString(), "one");
	equal(one.equals(one), true);
	var one2 = new AjLisp.Atom("one");
	equal(one.equals(one2), true);
});

Test exercising list behavior:

test("List", function() {
	var list = new AjLisp.List(1,2);
	equals(list.first(), 1);
	equals(list.rest(), 2);
	equal(list.isAtom(),false);
	equal(list.isList(),true);
	equal(AjLisp.isAtom(list), false);
	equal(AjLisp.isList(list), true);
	equal(list.asString(), "(1.2)");
	equal(list.equals(list), true);
	var list2 = new AjLisp.List(1,2);
	equal(list.equals(list2), true);
	equal(list2.equals(list), true);
	var list3 = AjLisp.makeList(1,2,3);
	equal(list.equals(list3), false);
	equal(list3.equals(list), false);
	list = AjLisp.makeList(null, null);
	ok(list.first() === null);
	ok(list.rest().first() === null);
});

Pending topics: environment implementation, list evaluation, forms and special forms, parser, lambda, mlambda, flambda. Lot of fun! ;-)

Keep tuned!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

May 3, 2010

AjCoreLisp and MinimaLisp, a minimal Lisp interpreter implementation

As I mentioned in:

AjLisp family: Implementing Lisp Interpreters in C#

I was working written two Lisp interpreters: AjLisp and AjSharpure (a clojure-like interpreter). But I wanted to explore what is the core of the language, the minimal part that should be implemented, in order to have a Lisp interpreter.

Then, I wrote AjCoreLisp. You can download from my Google project

http://code.google.com/p/ajlisp/source/browse/#svn/trunk/AjCoreLisp

It is implemented in C#. The solution:

has five projects:

AjCoreLisp: core class library, implementing the language base, but without parser and lexer, only execution runtime.

AjCoreLisp.Tests: as usual, I developed the library using TDD approach. This is the tests project of the core library.

MinimaLisp: A proof-of-concept lexer, parser, and minimal machine, to show how to use the core library to build a minimal Lisp interpreter.

MiminaLisp.Console: the interactive console interpreter.

MiminaLisp.Test: TDD tests written during the development of MinimaLisp.

The root interface is IExpression:

    public interface IExpression
    {
        object Evaluate(IEnvironment environment);
    }

Any Lisp has list support. The IList interface is:

 

    public interface IList : IExpression
    {
        object First { get; }
        object Rest { get; }
        IList Next { get; }
    }

No update of the list are supported. If you want to add such list, you should derive from this interface, and put the implementation in your extending project, as MinimaLisp. Note that I borrowed from Clojure, the idea of having Rest and Next: the former return an object, the latter presumes the rest of the list is a list itselft.

Every form implements the interface IForm:

    public interface IForm
    {
        object Apply(IEnvironment environment, IList arguments);
    }

Then, the Form class implements IForm and IExpression:

    public class Form : IForm, IExpression
    {
        private IList parameters;
        private IIdentifier parameter;
        private IList body;
        private IEnvironment environment;
        public Form(IList parameters, IList body, IEnvironment environment)
        {
            this.parameters = parameters;
            this.body = body;
            this.environment = environment;
        }
        public Form(IIdentifier parameter, IList body, IEnvironment environment)
        {
            this.parameter = parameter;
            this.body = body;
            this.environment = environment;
        }
// ....
        public object Evaluate(IEnvironment environment)
        {
            return this;
        }
        public virtual object Apply(IEnvironment environment, IList arguments)
        {
            IEnvironment newenv;
            
            if (this.parameter != null)
                newenv = this.MakeNewEnvironmentList(arguments);
            else
                newenv = this.MakeNewEnvironment(arguments);
            return Machine.EvaluateBody(this.body, newenv);
        }
// ....
    }

Note that Form does not evaluate its arguments. That is the job of derived Function class:

    public class Function : Form, IExpression
    {
        public Function(IList parameters, IList body, IEnvironment environment)
            : base(parameters, body, environment)
        {
        }
        public Function(IIdentifier parameter, IList body, IEnvironment environment)
            : base(parameter, body, environment)
        {
        }
        public override object Apply(IEnvironment environment, IList arguments)
        {
            return base.Apply(environment, BaseForm.EvaluateList(arguments, environment));
        }
    }

As usual, macros have a twists: they evaluate its body, and then, evaluates the returned value:

    public class Macro : Form, IExpression
    {
// ...
        public override object Apply(IEnvironment environment, IList arguments)
        {
            object value = base.Apply(environment, arguments);
            value = Machine.Resolve(value, environment);
            return Machine.Evaluate(value, environment);
        }
    }

Ok, enough source code. Look the complete code, for more details. The main point is that AjCoreLisp implements few primitives:

The binding to this primitives is the job of MinimaLisp Machine:

        public MinimalMachine()
        {
            this.Environment.SetValue("first", new First());
            this.Environment.SetValue("rest", new Rest());
            this.Environment.SetValue("cons", new Cons());
            this.Environment.SetValue("quote", new Quote());
            this.Environment.SetValue("define", new Define());
            this.Environment.SetValue("lambda", new Lambda());
            this.Environment.SetValue("flambda", new FormLambda());
            this.Environment.SetValue("mlambda", new MacroLambda());
            this.Environment.SetValue("let", new Let());
            this.Environment.SetValue("letrec", new RecursiveLet());
            this.Environment.SetValue("eval", new Evaluate());
            this.Environment.SetValue("if", new If());
            this.Environment.SetValue("do", new Do());
            this.Environment.SetValue("nil?", new IsNil());
            this.Environment.SetValue("list?", new IsList());
            this.Environment.SetValue("equal?", new IsEqual());
        }

Based on that set, I could write a set of core functions:

(define list x x)
(define definem 
  (mlambda x 
    (list 
      'define 
      (first x)
      (cons 'mlambda (rest x))
    )
  )
)
(define mapfirst (fn lst)
  (if (nil? lst)
    nil
    (cons 
      (fn (first lst)) 
      (mapfirst fn (rest lst))
    )
  )
)
    
(define mapcond (fn lst)
  (if (nil? lst)
    nil
    (if (fn (first lst))
      (cons 
        (first lst) 
        (mapcond fn (rest lst))
      )
      (mapcond fn (rest lst))
    )
  )
)
(define append (x y) (if (nil? x) y (cons (first x) (append (rest x) y))))
  
(definem cond lst
  (if (nil? lst)
    nil 
    (list 
      'if 
      (first (first lst)) 
      (cons 'do (rest (first lst))) 
      (cons 'cond (rest lst))
    )
  )
)
(define atom? (x)
  (cond 
    ((nil? x) t)
    ((list? x) nil)
    (t t)
  )
)
(definem and lst
  (if (nil? lst)
    t
    (list 
      'if 
      (first lst)
      (cons 'and (rest lst))
      nil
    )
  )
)
(definem or lst
  (if (nil? lst)
    nil
    (list 
      'if 
      (first lst)
      t
      (cons 'or (rest lst))
    )
  )
)
(define not (x)
  (if x
    nil
    t
  )
)
(definem backquote (lst) 
  (cond 
      ((nil? lst) nil)
        ((atom? lst) (list 'quote lst))
        ((equal? (first lst) 'unquote) (first (rest lst)))
        ((and (list? (first lst)) (equal? (first (first lst)) 'unquote-slice)) (list 'append (first (rest (first lst))) (list 'backquote (rest lst))))
        (t (list 'cons (list 'backquote (first lst)) (list 'backquote (rest lst))))
  )
)
(definem while lst
  (list 'if (list 'not (first lst)) nil (cons 'do (rest lst)) (cons 'while lst))
)

I'm very proud of my implementation of backquote (macro expansion). That is, these tests are green (note the use of unquote and unquote-slice):

this.EvaluateAndCompare("(backquote (a b c))", "(a b c)");
this.EvaluateAndCompare("(backquote (a (b c) d))", "(a (b c) d)");
this.Evaluate("(define x '(b b))");
this.EvaluateAndCompare("(backquote (a (unquote x) c))", "(a (b b) c)");
this.EvaluateAndCompare("(backquote (a ((unquote x)) c))", "(a ((b b)) c)");
this.EvaluateAndCompare("(backquote (a (unquote-slice x) c))", "(a b b c)");
this.EvaluateAndCompare("(backquote (a ((unquote-slice x)) c))", "(a (b b) c)");
this.EvaluateAndCompare("(backquote (a (unquote-slice x) (unquote-slice x) c))", "(a b b b b c)");

There is no numeric support, then, I wrote numbers using Peano-like ideas, only for tests:

(define succ (x)
  (cons x nil))
  
(define pred (x)
  (first x))
(define add (x y)
  (if (nil? x)
    y
    (add (pred x) (succ y))
  )
)

I didn’t improve the code for a while, but my next step could be refactor AjLisp to be based on this core interpreter. Now, I have a more clear idea of what is needed and what is accesory in a Lisp interpreter.

And, as usual, I had fun written all this code! ;-)

Keep tuned!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

January 9, 2010

Refactoring AjLisp: a lisp interpreter written in C#

Filed under: AjLisp, C Sharp, Open Source Projects — ajlopez @ 11:47 am

These days I was working on reimplementing the core of my open source AjLisp lisp interpreter. I wrote about the previous version in my 2008 post:

AjLisp: a Lisp interpreter in .NET

The work is in progress. You can download the current code from:

http://code.google.com/p/ajlisp/source/browse/#svn/trunk/AjLisp

(there are two other implementations in that repository, work in progress: AjScheme, an Scheme-like lisp, and AjSharpure, following Clojure ideas). I should write more about these implementations. This post is the initial one in a series about this new AjLisp. It’s a short introduction to the current status of the project.

The main change in the new version: the interpreter can manage native objects and values. The alternative was to point to such objects using a wrapper, a class that implements SymbolicExpression or something similar. But I choose to point and manage direct native object and values. So, I changed the primitives and related classes to receive objects instead of IExpression. Now, there is an interface IExpression, that is defined:

    public interface IExpression
    {
        object Evaluate(ValueEnvironment environment);
    }

The ValueEnvironment (I'm planning to rename it to BindingEnvironment, and to derive from it an interface IBindingEnvironment) keeps nested association of names to values:

There is an interface IFunction:

    public interface IFunction
    {
        object Apply(List arguments, ValueEnvironment environment);
    }

that it should be implemented by any form expression (the head of a list to evaluate).

There are two main classes that represent the core types in AjLisp: identifiers and lists:

All the project was built using Test-Driven Development, so I could change the previous versions with courage: I had my battery of tests ready to help me in the refactoring process. This is the current status:

I should write about:

- ValueEnvironment implementation

- Native objects and values management

- List type and evaluation

- Identifier evaluation

- Implemented primitives

- Lexer and Parser

- Numeric operations

- Rational numbers (AjLisp can manage integral numerator/denominator pairs)

Currently, after the wisdom gained developing these projects (AjLisp, AjScheme, AjSharpure), I’m writing a minimal core AjCoreLisp, to show what are the minimal primivites we need to create a Lisp interpreter. Armed with such implementation, I would like to explore compilation alternatives (Dynamic Language Runtime is my first candidate). It could be overwhelming to me do such exploration based on a “bigger” interpreter like AjLisp. First, I’ll try to compile an interpreter with few primitives.

Keep tuned!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

Older Posts »

Theme: Shocking Blue Green. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 28 other followers