Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Message from discussion Binding in defparameter versus let

Received: by 10.180.88.195 with SMTP id bi3mr836819wib.3.1347645093569;
        Fri, 14 Sep 2012 10:51:33 -0700 (PDT)
Path: ed8ni64951265wib.0!nntp.google.com!volia.net!news2.volia.net!feed-A.news.volia.net!npeer.de.kpn-eurorings.net!npeer-ng0.de.kpn-eurorings.net!xlned.com!feeder1.xlned.com!border2.nntp.ams.giganews.com!border3.nntp.ams.giganews.com!border1.nntp.ams.giganews.com!nntp.giganews.com!news.panservice.it!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail
From: Pascal Costanza <p...@p-cos.net>
Newsgroups: comp.lang.lisp
Subject: Re: Binding in defparameter versus let
Date: Mon, 10 Sep 2012 00:08:58 +0200
Lines: 69
Message-ID: <ab4ibqFdumnU1@mid.individual.net>
References: <10e817c1-f4f5-4033-a617-1707a2bc366a@googlegroups.com> <barmar-0B446B.17301409092012@news.eternal-september.org>
Mime-Version: 1.0
X-Trace: individual.net E8wS1cXF8rkSiSwTqihYKwL+k7FNxxQ2EpyyOzewYf+S0XqBj1nADWBKq+cWp9YhD5
Cancel-Lock: sha1:Rbl33seOXZswRbWIUd2hCGFXpvw=
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:15.0) Gecko/20120824 Thunderbird/15.0
In-Reply-To: <barmar-0B446B.17301409092012@news.eternal-september.org>
Bytes: 3212
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

On 09/09/2012 23:30, Barry Margolin wrote:
> In article <10e817c1-f4f5-4033-a617-1707a2bc366a@googlegroups.com>,
>   parisni...@gmail.com wrote:
>
>> Today I was cleaning up some code and made a mistake.
>>
>> The code was originally like this
>> (defparameter *baz* (list 'a #'(lambda()(third *baz*)) 'c))
>>
>> Now *baz* is bound early enough that the lambda works properly.
>
> The issue isn't when it's bound, it's that it's bound in the same scope
> that the variable is looked up in -- they're both in the global scope.
>
>>
>> It failed when I moved it into a function:
>>
>> (defun foo ()
>>    (let ((bar (list 'a #'(lambda()(third bar)) 'c)))
>>      (print bar)))
>>
>> The binding for let doesn't occur until running, so (third bar) is unbound.
>
> No, the issue is that the scope of the binding is the LET body, which
> doesn't include the initial value expression.
>
>>
>> This can be easily remedied with:
>> (defun foo ()
>>    (let ((bar))
>>      (setf bar (list 'a #'(lambda()(third bar)) 'c))
>>      (print bar)))
>>
>> Are there neater ways to do the same thing?
>
> (defun foo ()
>    (locally (declare (special bar))
>      (let ((bar (list 'a #'(lambda () (third bar)) 'c)))
>        (print bar))))
>
> In Scheme you could do what you want using LETREC, but Common Lisp
> doesn't have this.  Since it's usually used for defining local
> functions, and Common Lisp doesn't use LET for defining local functions
> (because of the separate function and value namespaces), we achieve this
> using FLET and LABELS -- the latter allows for recursion. But we don't
> have a LABELS-equivalent for LET.

It doesn't take a lot to have letrec in Common Lisp:

(defmacro letrec ((&rest bindings) &body body)
   `(let ,(mapcar #'first bindings)
      (setq ,@(apply #'append bindings))
      ,@body))

 > (letrec ((bar (list 'a (lambda () (third bar)) 'c)))
     (print bar)
     (print (funcall (second bar))))

(A #<anonymous interpreted function 200C56CA> C)
C


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
The views expressed are my own, and not those of my employer.