From: Kyle Brooks Date: 2008-03-02T06:00:05+09:00 Subject: Re: a practical Lisp in Ruby This is a VERY interesting idea, but why do you want to do this? - Kyle On Mar 1, 11:59 am, Elliott Hird wrote: > 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: >     >> foo = 3 >     => 3 >     >> def foo; 4 end >     => nil >     >> foo >     => 3 >     >> method(:foo).call >     => 4 >   since this thing will emulate a Lisp-1 (basically), how should this be >   handled? maybe in the same way. > > - 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 >     >> (def foo 3) >     => 3 >     >> (def (foo) 4) >     => # >     >> foo >     => 3 or #?! >     >> (foo) >     => "you can't call a Fixnum!" or 4? > > 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." (engine downcase) ".com"))) > > -ehird