Hi Jeff,
The hyperspec doesn't intend to mean "execute in parallel". It just means
that the values for the bindings in a let are computed independently of one
another, but that the bindings for the let* are computed sequentially.
Take the following example, which I have not submitted to Lisp and will
give you warnings about unused variables.
(defun foo-let (x)
(let ((x 3)
(x (* x x)))
x)
(foo 2) --> 4
(defun foo-let-star (x)
(let* ((x 4)
(x (* x x)))
x)
(foo-let-star 12313212) --> 16
There are various Lisp libraries that provide the functionality you're
looking for. For example, Vladamir Sedach provides an eager futures
library [ http://common-lisp.net/project/eager-future/ ]. Also, I provide
a "plet" primitive (and others, like "spec-mv-let") for ACL2, which is
built on top of CL [
http://www.cs.utexas.edu/users/moore/acl2/current/PLET.html ]. If you'd
like more information about the latter, feel free to inquire (probably off
the list-serve).
David
On Tue, Nov 27, 2012 at 11:50 AM, Jeff Cunningham <jeffrey@...>
wrote:
> According to the Hyperspec:
>
> "let and let* create new variable bindings and execute a series of forms
> that use these bindings. let performs the bindings in parallel and let*
does
> them sequentially. "
>
> I thought I knew what that meant until I tried to demonstrate it to
myself.
> I wrote a simple function that eats cpu cycles for a visible period of
time.
> Then I set up a let expression which I thought would evaluate these forms
in
> parallel:
>
> (defun waste-time (n)
> (let ((a 0))
> (dotimes (i n a)
> (incf a (- (random 1.0) 0.5)))))
>
> (let ((n 100000000))
> (let ((n1 (waste-time n))
> (n2 (waste-time n)))
> (print n1)
> (print n2)))
>
> I have a quad-core i7 running Linux 3.2.0-33-generic #52-Ubuntu SMP Thu
Oct
> 18 16:29:15 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux.
>
> I built a fresh copy of SBCL with --fancy (which includes threading I
> believe) which I cloned via git this morning.
>
> What I expected to see was two cpu cores busy for a few seconds when I run
> this. But what I in fact see is a single thread running. This indicates it
> is evaluating the let bindings serially, not in parallel.
>
> If I wrap the code with (time ) I get this for the parallel let:
>
> 362.691
> 1979.4808
> Evaluation took:
> 3.815 seconds of real time
> 3.816238 seconds of total run time (3.816238 user, 0.000000 system)
> 100.03% CPU
> 8,753,527,227 processor cycles
> 30,000 bytes consed
>
> And I get this for the serial let*:
>
> -2341.4565
> 436.2103
> Evaluation took:
> 3.783 seconds of real time
> 3.780236 seconds of total run time (3.780236 user, 0.000000 system)
> 99.92% CPU
> 8,680,021,725 processor cycles
> 33,168 bytes consed
>
>
>
> So I don't understand what the difference is, other than the compiler not
> being willing to recognize sequential bindings in the case of let vs let*.
>
> Regards,
> Jeff
>
>
------------------------------------------------------------------------------
> Monitor your physical, virtual and cloud infrastructure from a single
> web console. Get in-depth insight into apps, servers, databases, vmware,
> SAP, cloud infrastructure, etc. Download 30-day Free Trial.
> Pricing starts from $795 for 25 servers or applications!
> http://p.sf.net/sfu/zoho_dev2dev_nov
> _______________________________________________
> Sbcl-help mailing list
> Sbcl-help@...
> https://lists.sourceforge.net/lists/listinfo/sbcl-help
>
|