From: William James Date: 2006-07-25T05:20:11+09:00 Subject: Re: RLisp - Lisp naturally embedded in Ruby Tomasz Wegrzanowski wrote: > Hello :-) > > Maybe some of you guys will be interested. > I wrote a small Lisp interpretter embedded in Ruby. > The emdedding is very tight - Lisp macros are Ruby Proc objects > and Lisp lists are Ruby Arrays (so actually cdr/cons copy). > It is somewhat more Scheme-ish (or even Goo-ish) than Common Lisp-ish, > but the macro system is more like Common Lisp's. > [obj method args] is a reader macro for (send obj 'method args), > which expands to obj.send(:method, *args). > Very interesting. > Here are some examples: > > ; Fib function > (defun fib (n) > (if (<= n 1) > 1 > (+ (fib (- n 1)) (fib (- n 2))) > ) > ) > (print (map fib '(1 2 3 4 5))) > > ; A small HTTP server > (ruby-eval "require 'webrick'") ; import module > (let HTTPServer (ruby-eval "WEBrick::HTTPServer")) ; bind class name > > ; Configure the server > (let config [Hash new]) Please don't use "let" for this. "setq" or "define" would be much better. >From Structure and Interpretation of Computer Programs: The first part of the let expression is a list of name-expression pairs. When the let is evaluated, each name is associated with the value of the corresponding expression. The body of the let is evaluated in a local environment that includes these names a local variables. .... No new mechanism is required in the interpreter in order to provide local variables. Let is simply syntactic sugar for the underlying lamda. >From the newLisp manual: syntax: (let ((sym1 exp-init1) [ (sym2 exp-init2) ...] ) body) syntax: (let (sym1 exp-init1 [sym2 exp-init2 ... ] ) body) .... One or more expressions in body are evaluated using the local definitions of sym1, sym2 etc. let is useful for breaking up complex expressions by defining local variables close to the place where they are used. .... The let form is just an optimized version and syntactic convenience for writing: ((lambda (sym1 [sym2 ...]) body ) exp-init1 [ exp-init2 ]) >From comp.lang.lisp: (defun look-for-element () (format t "~%this is the list we will work on: ~A~%" *list*) (let ((element (prompt-read-element))) (if (member element *list*) (give-position element *list*) (format nil "element not found")))) Emacs elisp: (let VARLIST BODY...): bind variables according to VARLIST then eval BODY. The value of the last form in BODY is returned. Each element of VARLIST is a symbol (which is bound to nil) or a list (SYMBOL VALUEFORM) (which binds SYMBOL to the value of VALUEFORM). All the VALUEFORMs are evalled before any symbols are bound.