From: Ola Bini Date: 2006-07-27T22:01:20+09:00 Subject: Re: RLisp - Lisp naturally embedded in Ruby Tomasz Wegrzanowski wrote: > On 7/27/06, Christian Neukirchen wrote: >> > Yeah, but setf changes variables in outside scope. >> > (setf a 2) >> > (defun foo () >> > (setf a 3) >> > a >> > ) >> > (foo) ; -> 3 >> > a ; -> 3 >> >> No, that's just because a is global here. Shadow it by a local variable: >> >> (defun foo () >> (let (a) >> (setf a 3) >> a)) >> >> a ; => 2 >> (foo) ; => 3 >> a ; => 2 >> >> > I think it would be a huge win if variables were local to >> > the nearest lambda (or equivalent) by default, just like in Ruby. >> >> That's why one uses LET for local variables. ;-) > > Can we macro around it or something, so that > (set-local-variable variable value) introduces a function-local variable > without increasing indentation level each time it's being done? > > I think it's reasonable to write something like that (whatever the names > of set-local-variable operator is): > > (defun veclen (x y) > (set-local-variable x2 (* x x)) > (set-local-variable y2 (* y y)) > (set-local-variable z2 (+ x2 y2)) > (sqrt z2) > ) > > Such a macro would be a strange beast indeed. The problem is that indentation level actually reflects lexical scope, which means that set-local-variable would have to find the environment for the function veclen and change this after it was defined. What you _could_ do if the nesting is bad for you is to introduce CL's aux variables: (defun veclen (x y &aux (x2 (* x x)) (y2 (* y y)) (z2 (+ x2 y2))) (sqrt z2)) This is of course just syntactic sugar, but it works and is standardized. I recommend you do this, keep setf/setq for changing the variables, but leave let alone. -- Ola Bini (http://ola-bini.blogspot.com) JvYAML, RbYAML, JRuby and Jatha contributor System Developer, Karolinska Institutet (http://www.ki.se) OLogix Consulting (http://www.ologix.com) "Yields falsehood when quined" yields falsehood when quined.