# A practical Lisp in Ruby

**URL:** <https://www.ruby-forum.com/t/a-practical-lisp-in-ruby/130674>\
**Category:** Ruby\
**Created:** [March 1, 2008, 6:00pm UTC](https://www.ruby-forum.com/t/a-practical-lisp-in-ruby/130674 "2008-03-01T18:00:55Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![ehird](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/43a26b/32.png) [@ehird](https://www.ruby-forum.com/u/ehird)\
**Post date:** [March 1, 2008, 6:00pm UTC](https://www.ruby-forum.com/t/a-practical-lisp-in-ruby/130674/1 "2008-03-01T18:00:55Z")

</div>

Hi! I’ve been working on a Lisp interpreter in Ruby that is fully  
integrated (I mean – fully. The aim is to have basically nothing  
specific to the interpreter and use Ruby for everything. Basic rule of  
thumb: you should be able to use it to write a Rails app with no extra  
pain than in Ruby.)

Some examples:

'(1 2 3) =\> (1 2 3)  
[1 2 3] =\> [1 2 3]  
([] empty?) =\> true  
(puts (if ([] empty?) “hello world” “oh no”)) =\> hello world

Now, I hope to have some code released Real Soon Now (it really isn’t  
usable enough yet; needs some reworking). But I’d like the Ruby  
community’s opinion on some few things, to try and make it as Ruby-ish  
as possible. So, dump of things I’ve thought about:

- should # be used as a comment marker (instead of ;)? it might get in  
the way of _something_, lisp dialects tend to use it a lot, but #\c  
will probably be ?c, #t/#f is true/false, and #(…) is […] so I’m  
not sure.

- should 'a be ruby’s :a? that could mess up pretty printing, e.g.:  
'(a b c) =\> (:a :b :c)  
if 'a is something other than :a, what should  
it be? a subclass of Symbol that just overrides pretty-printing, i  
guess. and then :a would be ruby’s :a.

- syntax for dicts? if we take the above idea, I think something like:  
{:a 2 :b 3} =\> {:a =\> 2, :b =\> 3}  
would be nice, but again there’s the problem that pretty-printing  
loses out.  
however I don’t think that Ruby’s syntax should be re-used directly,  
because  
it’s not lisp-like.

- how to call out to ruby. what happens if you pass a list to a ruby  
function?  
I could recursively translate them to arrays, but that’s expensive and  
if you’re calling out to something that wants to directly use the  
object  
or is one of the functions that doesn’t care what type its object is,  
it might not even be expected behaviour. also, should i translate a\_b  
to a-b?  
vise-versa?

- on a similar note, what class is (lambda (x) x)? if a Proc I have to  
have a trampoline in the Proc, which isn’t nice. a subclass of Proc?

- how to handle blocks. some ideas:  
([1 2 3] map (lambda (x) (+ x 1)))  
that means I have to do arity stuff, and presents a problem – what if  
‘map’ there was variadic? are we passing a function, or a block?  
([1 2 3] map (do (x) (+ x 1)))  
here ‘do’ creates something internally treated as a block. again the  
variadic problem, relating to my “what if the func/method doesn’t care  
about the type it gets”?  
([1 2 3] map do (x) (+ x 1))  
this is a little bit hard to read, but unambigious. of course, now you  
can’t use “do” in most places. a multiline example of this:  
([0 1 2 3 4 5] map do (x)  
(if (= (% x 2) 0)  
(+ x 5)  
(- x 4)))  
this is my preferred syntax at the moment, actually. maybe i could  
hijack  
{…} somehow (don’t really like that idea).

- (def (func …) …) or (def func (…) …)? the former seems more  
rubyish  
to me, i guess. (def (foo) …) instead of (def foo () …).

- this thing:

- and closely linked to that: since a 0-arg function is used often in  
Ruby  
in place of a variable (but – mostly in a method, where this would be  
(obj foo) so it wouldn’t be a problem). you’d have to do (foo)  
currently,  
which would differenciate it from foo.

- also related: watch this imaginary session in the Lisp REPL

this clashes with Lisp-1-ness, certainly.

Anyway, that’s the end of this long post for now. Feel free to ignore  
my ramblings, but to leave, here’s a few code examples that don’t  
actually work  
right now and may look completely different when they do 🙂

;; Output “I love Ruby”  
(def say “I love Ruby”)  
(puts say)

;; Output “I _LOVE_ RUBY”  
(set! (say “love”) “_love_”) ;; set! name?  
(puts (say upcase))

;; Output “I _love_ Ruby” five times  
(5 times do (puts say))

and the second:

(class Numeric  
(def (plus x)  
(self + x)  
;; or (the same, but variadic)  
(+ self x)))

Well, OK. Have a third.

(def search-engines  
(%w[Google Yahoo MSN] map do (engine)  
(+ “[http://www](http://www).” (engine downcase) “.com”)))

-ehird

---

<div class="post-metadata">

**Author:** ![ehird](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/43a26b/32.png) [@ehird](https://www.ruby-forum.com/u/ehird)\
**Post date:** [March 1, 2008, 10:02pm UTC](https://www.ruby-forum.com/t/a-practical-lisp-in-ruby/130674/2 "2008-03-01T22:02:05Z")

</div>

This is a VERY interesting idea, but why do you want to do this?

- Kyle

On Mar 1, 11:59 am, Elliott H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![ehird](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/43a26b/32.png) [@ehird](https://www.ruby-forum.com/u/ehird)\
**Post date:** [March 1, 2008, 10:05pm UTC](https://www.ruby-forum.com/t/a-practical-lisp-in-ruby/130674/3 "2008-03-01T22:05:41Z")

</div>

On 01/03/2008, Kyle B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> This is a VERY interesting idea, but why do you want to do this?
> 
> - Kyle

For a start - because it can be done ;-).

For another - because I want to see what happens when you combine Lisp  
awesomeness like macros & such with Ruby’s elegance and libraries. I  
am expecting an explosion of some sort.

Who knows? Maybe it’ll target YARV one day, and be a first-class  
citizen, just like Ruby itself.

-ehird

---

<div class="post-metadata">

**Author:** ![ehird](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/43a26b/32.png) [@ehird](https://www.ruby-forum.com/u/ehird)\
**Post date:** [March 1, 2008, 11:23pm UTC](https://www.ruby-forum.com/t/a-practical-lisp-in-ruby/130674/4 "2008-03-01T23:23:37Z")

</div>

On 01/03/2008, James B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Perhaps combined with Rubinious you really could have Lisp-like macros.

You mean, in Ruby itself? That would be crazy awesome. 🙂

But they will probably be ugly. Ruby parse trees aren’t as nice as Lisp  
ones 😉

---

<div class="post-metadata">

**Author:** ![ehird](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/43a26b/32.png) [@ehird](https://www.ruby-forum.com/u/ehird)\
**Post date:** [March 1, 2008, 11:28pm UTC](https://www.ruby-forum.com/t/a-practical-lisp-in-ruby/130674/5 "2008-03-01T23:28:54Z")

</div>

On Mar 1, 2008, at 1:04 PM, Elliott H. wrote:

> Who knows? Maybe it’ll target YARV one day, and be a first-class  
> citizen, just like Ruby itself.
> 
> -ehird

Elliot-

You may want to look at these two projects:

[http://chaosforge.org/taw/rlisp/](http://chaosforge.org/taw/rlisp/)

[http://bus-scheme.rubyforge.org/](http://bus-scheme.rubyforge.org/)

rlisp is a lisp to ruby compiler with nice lisp → ruby integration  
that solves most of the problems you are asking about. Bus Scheme is  
a scheme written in ruby with ruby integration.

Rlisp is more complete but I prefer scheme to lisp myself so bus  
scheme is pretty interesting, bus scheme already runs on rubinius too 😉

Cheers-

- Ezra Z.  
– Founder & Software Architect  
– removed\_email\_address@domain.invalid  
– [EngineYard.com](http://EngineYard.com)

---

<div class="post-metadata">

**Author:** ![ehird](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/43a26b/32.png) [@ehird](https://www.ruby-forum.com/u/ehird)\
**Post date:** [March 1, 2008, 11:10pm UTC](https://www.ruby-forum.com/t/a-practical-lisp-in-ruby/130674/6 "2008-03-01T23:10:06Z")

</div>

Elliott H. wrote:  
ome sort.

> Who knows? Maybe it’ll target YARV one day, and be a first-class  
> citizen, just like Ruby itself.

Perhaps combined with Rubinious you really could have Lisp-like macros.

–  
James B.

“Discover the recipes you are using and abandon them.”

- Brian Eno and Peter Schmidt, Oblique Strategies

---

<div class="post-metadata">

**Author:** ![ehird](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/43a26b/32.png) [@ehird](https://www.ruby-forum.com/u/ehird)\
**Post date:** [March 2, 2008, 12:25am UTC](https://www.ruby-forum.com/t/a-practical-lisp-in-ruby/130674/7 "2008-03-02T00:25:56Z")

</div>

On 01/03/2008, Ezra Z. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Elliot  
> t 🙂  
> a scheme written in ruby with ruby integration.
> 
> ```
> Rlisp is more complete but I prefer scheme to lisp myself so bus
> 
> ```
> 
> scheme is pretty interesting, bus scheme already runs on rubinius too 😉

I’ve seen rlisp briefly and Bus Scheme too. Bus Scheme isn’t really  
that integrated; more Scheme than Ruby, IMO. RLisp is quite nice but  
not quite perfect, IMO – the philosophy’s quite different.

My idea is a Ruby Lisp, really, not a Lisp integrated with Ruby. 🙂

-ehird

---

<div class="post-metadata">

**Author:** ![ehird](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/43a26b/32.png) [@ehird](https://www.ruby-forum.com/u/ehird)\
**Post date:** [March 2, 2008, 5:30am UTC](https://www.ruby-forum.com/t/a-practical-lisp-in-ruby/130674/8 "2008-03-02T05:30:49Z")

</div>

On Mar 1, 5:28 pm, Ezra Z. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> Rlisp is more complete but I prefer scheme to lisp myself so bus
> 
> ```
> 
> scheme is pretty interesting, bus scheme already runs on rubinius too 😉

Bummer. I work from my home typically, so I don’t think I can  
contribute to Bus Scheme 😉
