From: SourceForge.net <no...@so...> - 2010-05-16 09:23:05
|
Feature Requests item #3001956, was opened at 2010-05-15 04:32 Message generated for change (Comment added) made by haible 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: Rejected Priority: 5 Private: No Submitted By: Krzysztof Drewniak (krzysz00) Assigned to: Bruno Haible (haible) 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: Bruno Haible (haible) Date: 2010-05-16 11: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 06: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 |