Discussion:
Sub-function free variable binding differences between Scheme and CL
Burton Samograd
2012-03-05 13:05:38 UTC
Permalink
Content preview: Hello, I am curently translating the logic circuit simulator
code from SICP into Common Lisp and have run into a snag that I would like
to ask about. The Scheme code is as follows from section 3.3.4 (page 223
of my hardcover edition): [...]

Content analysis details: (-0.7 points, 5.0 required)

pts rule name description
---- ---------------------- --------------------------------------------------
-0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low
trust
[209.85.210.179 listed in list.dnswl.org]
0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider
(burton.samograd[at]gmail.com)
-0.0 SPF_PASS SPF: sender matches SPF record
0.0 T_DKIM_INVALID DKIM-Signature header exists but is not valid
Archived-At: <http://permalink.gmane.org/gmane.lisp.cl-pro/614>

Hello,

I am curently translating the logic circuit simulator code from SICP
into Common Lisp and have run into a snag that I would like to ask
about.

The Scheme code is as follows from section 3.3.4 (page 223 of my
hardcover edition):

(define (and-gate a1 a2 output)
(define (and-action-procedure)
(let ((new-value
(locical-and (get-signal a1) (get-signal a2))))
(after-delay and-gat-delay
(lambda ()
(set-signal! output new-value)))))
(add-action! a1 and-action-procedure)
(add-action! a2 and-action-procedure))

The code basically binds the local function and-action-procedure into
a list of functions in a1 and a2 which are then called by another
routine later to perform the action when a value is set on the wire.

My translated Common Lisp code is:

(defun make-and-gate (a1 a2 output)
(flet ((logical-and (a b)
(if (= a 1) b a))
(and-action-proc ()
(let ((new-value (logical-and (get-signal a1) (get-signal a2))))
(set-signal output new-value))))
(add-action a1 #'and-action-proc)
(add-action a2 #'and-action-proc)))

The problem is that the bindings of a1 and a2 in and-action-proc are
not being bound to the values of the calling function in the Common
Lisp version. This causes the calling of and-action-proc to fail
because a1 and a2 are not bound and I am assuming being treated as
dynamic (special) variables. I have also tried to define
and-action-proc using labels with no difference in results.

Is this a total schemantic difference between CL and Scheme? Is every
function in Scheme a closure where free variables of sub-functions
bound to the calling functions environment? If so, is there a way to
emulate this in Common Lisp?

I would also like to note that I am currently trying out writing this
code using LispWorks Personal Edition, rather than my usual SBCL
environment, if that would make any difference.

--
Burton Samograd
Stas Boukarev
2012-03-05 13:23:20 UTC
Permalink
Content preview: Burton Samograd writes: > Hello, > > I am curently translating
the logic circuit simulator code from SICP > into Common Lisp and have run
into a snag that I would like to ask > about. > > The Scheme code is as follows
from section 3.3.4 (page 223 of my > hardcover edition): > > (define (and-gate
a1 a2 output) > (define (and-action-procedure) > (let ((new-value > (locical-and
(get-signal a1) (get-signal a2)))) > (after-delay and-gat-delay > (lambda
() > (set-signal! output new-value))))) > (add-action! a1 and-action-procedure)
(add-action! a2 and-action-procedure)) > > The code basically binds the
local function and-action-procedure into > a list of functions in a1 and
a2 which are then called by another > routine later to perform the action
when a value is set on the wire. > > My translated Common Lisp code is: >
(defun make-and-gate (a1 a2 output) > (flet ((logical-and (a b) > (if (=
a 1) b a)) > (and-action-proc () > (let ((new-value (logical-and (get-signal
a1) (get-signal a2)))) > (set-signal output new-value)))) > (add-action a1
#'and-action-proc) > (add-action a2 #'and-action-proc))) You should use LABELS
instead of FLET, FLET doesn't make its definitions available inside definitions
so the call logical-and in and-action-proc can't find logical-and. [...]

Content analysis details: (-100.7 points, 5.0 required)

pts rule name description
---- ---------------------- --------------------------------------------------
-0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low
trust
[209.85.214.51 listed in list.dnswl.org]
-100 USER_IN_WHITELIST From: address is in the user's white-list
0.0 SINGLE_HEADER_2K A single header contains 2K-3K characters
0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider
(stassats[at]gmail.com)
-0.0 SPF_PASS SPF: sender matches SPF record
0.0 T_DKIM_INVALID DKIM-Signature header exists but is not valid
Archived-At: <http://permalink.gmane.org/gmane.lisp.cl-pro/615>
Hello,
I am curently translating the logic circuit simulator code from SICP
into Common Lisp and have run into a snag that I would like to ask
about.
The Scheme code is as follows from section 3.3.4 (page 223 of my
(define (and-gate a1 a2 output)
(define (and-action-procedure)
(let ((new-value
(locical-and (get-signal a1) (get-signal a2))))
(after-delay and-gat-delay
(lambda ()
(set-signal! output new-value)))))
(add-action! a1 and-action-procedure)
(add-action! a2 and-action-procedure))
The code basically binds the local function and-action-procedure into
a list of functions in a1 and a2 which are then called by another
routine later to perform the action when a value is set on the wire.
(defun make-and-gate (a1 a2 output)
(flet ((logical-and (a b)
(if (= a 1) b a))
(and-action-proc ()
(let ((new-value (logical-and (get-signal a1) (get-signal a2))))
(set-signal output new-value))))
(add-action a1 #'and-action-proc)
(add-action a2 #'and-action-proc)))
You should use LABELS instead of FLET, FLET doesn't make its definitions
available inside definitions so the call logical-and in and-action-proc
can't find logical-and.

And seriously, writing to the _pro_ mailing list to ask trivial questions?
--
With best regards, Stas.
Burton Samograd
2012-03-05 13:54:30 UTC
Permalink
Content preview: I apologize, my original code was using labels but I copied
the one using flet for this question. Please assume that I am using labels;
the variable binding question still stands. I am asking this on the Pro list
because it seems that everyone is on the same lists anyways and I get the
best answers from the list. I can send it somewhere else if you have a suggestion
where I would get the same quality of answer as here. [...]

Content analysis details: (0.5 points, 5.0 required)

pts rule name description
---- ---------------------- --------------------------------------------------
-0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low
trust
[209.85.210.179 listed in list.dnswl.org]
0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider
(burton.samograd[at]gmail.com)
-0.0 SPF_PASS SPF: sender matches SPF record
1.2 MISSING_HEADERS Missing To: header
0.0 T_DKIM_INVALID DKIM-Signature header exists but is not valid
Archived-At: <http://permalink.gmane.org/gmane.lisp.cl-pro/616>

I apologize, my original code was using labels but I copied the one
using flet for this question. Please assume that I am using labels;
the variable binding question still stands.

I am asking this on the Pro list because it seems that everyone is on
the same lists anyways and I get the best answers from the list. I
can send it somewhere else if you have a suggestion where I would get
the same quality of answer as here.

--
Burton Samograd
Post by Stas Boukarev
Post by Burton Samograd
Hello,
I am curently translating the logic circuit simulator code from SICP
into Common Lisp and have run into a snag that I would like to ask
about.
The Scheme code is as follows from section 3.3.4 (page 223 of my
(define (and-gate a1 a2 output)
    (define (and-action-procedure)
        (let ((new-value
               (locical-and (get-signal a1) (get-signal a2))))
         (after-delay and-gat-delay
                      (lambda ()
                              (set-signal! output new-value)))))
     (add-action! a1 and-action-procedure)
     (add-action! a2 and-action-procedure))
The code basically binds the local function and-action-procedure into
a list of functions in a1 and a2 which are then called by another
routine later to perform the action when a value is set on the wire.
(defun make-and-gate (a1 a2 output)
  (flet ((logical-and (a b)
           (if (= a 1) b a))
         (and-action-proc ()
           (let ((new-value (logical-and (get-signal a1) (get-signal a2))))
             (set-signal output new-value))))
    (add-action a1 #'and-action-proc)
    (add-action a2 #'and-action-proc)))
You should use LABELS instead of FLET, FLET doesn't make its definitions
available inside definitions so the call logical-and in and-action-proc
can't find logical-and.
And seriously, writing to the _pro_ mailing list to ask trivial questions?
--
With best regards, Stas.
Stas Boukarev
2012-03-05 14:02:25 UTC
Permalink
Content preview: Burton Samograd writes: > I apologize, my original code was
using labels but I copied the one > using flet for this question. Please
assume that I am using labels; > the variable binding question still stands.
With labels, the code is right, that means either you're not telling something
else again, or the problem is in another place in the code. [...]

Content analysis details: (-100.7 points, 5.0 required)

pts rule name description
---- ---------------------- --------------------------------------------------
-0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low
trust
[209.85.214.51 listed in list.dnswl.org]
-100 USER_IN_WHITELIST From: address is in the user's white-list
0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider
(stassats[at]gmail.com)
-0.0 SPF_PASS SPF: sender matches SPF record
0.0 T_DKIM_INVALID DKIM-Signature header exists but is not valid
Archived-At: <http://permalink.gmane.org/gmane.lisp.cl-pro/617>
I apologize, my original code was using labels but I copied the one
using flet for this question. Please assume that I am using labels;
the variable binding question still stands.
With labels, the code is right, that means either you're not telling
something else again, or the problem is in another place in the code.
--
With best regards, Stas.
Loading...