Feature Requests item #3001956, was opened at 2010-05-14 22:32
Message generated for change (Comment added) made by sds
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=351355&aid=3001956&group_id=1355
Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: Extend ANSI CL
Group: None
Status: Closed
>Resolution: Accepted
Priority: 5
Private: No
Submitted By: Krzysztof Drewniak (krzysz00)
>Assigned to: Sam Steingold (sds)
Summary: Make closures/functions printable
Initial Comment:
This would be a great feature. Basically make it so that given
(setf foo #'(lambda (x) x))
(setf bar (read-from-string (format nil "~s" foo)))
then (= (funcall foo 3) (cuncall bar 3)) would be true.
This would be great and let you do many good things.
----------------------------------------------------------------------
Comment By: Sam Steingold (sds)
Date: 2010-05-21 13:52
Message:
Thanks for the suggestion - it has been just implemented and
checked into the CVS repository, and will be available in the next
release.
If you cannot wait for the next release, you can get the latest
development sources from the CVS and compile them yourself.
Please be aware that the development sources are not stable and
might not even compile on your machine.
You should report any problems you encounter with the CVS sources
to the <clisp-devel> mailing list, not to the <clisp-list>.
If you use the CVS sources, you should read <clisp-devel>
since the CVS log goes there.
----------------------------------------------------------------------
Comment By: Bruno Haible (haible)
Date: 2010-05-16 05:23
Message:
1) Why is it bad to have features that work for some functions (namely,
functions that don't
refer to closed-up variables, functions, tags, blocks) and don't work
for functions that do
refer to closed-up variables, functions, tags, blocks?
Because the very concept of "function" is that one function is
substitutable for another function,
provided it has the same argument list and the same semantics. The way the
function is
implemented - with references to special variables or with references to
lexical variables -
MUST not have any effect on what you can do with the function.
2) The fact that (with-standard-io-syntax (prin1-to-string func)) allows a
compiled function
to be printed readably is a misfeature, because it violates principle 1):
It offers some feature
that does not work reliably for functions that refer to closed-over
lexical variables. It would be
good to introduce a new, undocumented special variable
SYSTEM::*PRINT-CLOSURE-READABLY*
that triggers the readable printout of closures in clisp. This variable
should be bound to NIL by
WITH-STANDARD-IO-SYNTAX.
3) Why are interpreted functions not printed readably when
*print-readably* is true?
Because they refer to the global environment.
> (setf foo #'(lambda (x) x))
> (sys::%record-ref foo 8)
((DECLARATION OPTIMIZE DECLARATION))
This is necessary and even desired: A interpreted function may not have
processed all
its source code after it is created (this is what distinguishes it from a
compiled function).
Therefore it needs to refer to the global environment.
And even if there was not the reference to the declaration environment, it
is not
desirable to print them readably because it would violate principle 1).
4) Requests like this are understandable from the point of new Lisp
users.
But these users have to learn that there are different programming styles
possible withing CL: The function and closed-up-variable oriented style,
where your data resides in closed-up variables. The function and
structure
style, where your data resides in objects of DEFSTRUCT type. The
CLOS style, where your data resides in objects of DEFCLASS type and
your code is in methods of generic functions. You can use all three
styles
on Common Lisp, but you have to be aware of the limitations. One of
these limitations is that you get the best support for *PRINT-READABLY*
by using the third style.
----------------------------------------------------------------------
Comment By: Sam Steingold (sds)
Date: 2010-05-16 00:16
Message:
compiler closures already can be printed readably:
[4]> (setf foo #'(lambda (x) (declare (compile)) x))
#<COMPILED-FUNCTION :LAMBDA>
[5]> (setf bar (read-from-string (with-standard-io-syntax (prin1-to-string
foo))))
#<COMPILED-FUNCTION :LAMBDA>
[6]> (= (funcall foo 1) (funcall bar 1))
T
we do not print interpreted closures readably for historical reasons.
I see no reason not to print them readably as lambda expressions (when the
original lambda is still available).
Of course, when the lambda is closed over a variable, you will not get
what you expect:
(let (a) (setq f1 (lambda (x) (push x a)) f2 (lambda () (pop a))))
F1 and F2 modify the same variable A.
now, if you do
(setq g1 (read-from-string (with-standard-io-syntax (prin1-to-string
f1))))
(setq g2 (read-from-string (with-standard-io-syntax (prin1-to-string
f2))))
there is no way to make g1 and g2 modify the same variable.
(this argument did not prevent us from printing compiled closured
readably, even though it applies equally there too).
So, Bruno, why can't we print interpreted closured "readably" as lambda
expressions?
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=351355&aid=3001956&group_id=1355

Community

Help

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

I agree to receive quotes, newsletters and other information from sourceforge.net and its partners regarding IT services and products. I understand that I can withdraw my consent at any time. Please refer to our Privacy Policy or Contact Us for more details