Attach please find a patch that allows SLIME HEAD to work with ABCL.
This patch
o does not attempt to automatically compile the files in the SLIME 'contrib' directory, as ABCL never returns when asked to compile 'contrib/swank-arglists.lisp'
o allows the use of slime-compile-and-load-file (C-c C-k) by patching the definition of COMPILER-CONDITION with explicit NILs, and does a load time creation of a COMPILER-CONDITION to get the MOP discriminating functions initialized correctly
Both these patches should really be addressed within the ABCL itself, but I haven't had the time to figure out these problems to the depth needed for understanding how to fix them. Patching SLIME to get around these problems at the present moment would at least stop people from complaining "SLIME is broken for ABCL", but I leave that decision up to the ruling SLIME-heads. . .
Mark Evenson mark.evenson@gmx.at writes:
o does not attempt to automatically compile the files in the SLIME contrib' directory, as ABCL never returns when asked to compile contrib/swank-arglists.lisp'
Just a guess, but what I could imagine that `parse-first-valid-form-spec' in swank-arglist.lisp could possibly be the culprit, as it uses the "mapping on several lists, one being circular" trick:
(mapcar #'+ '(1 2 3 4) '#1=(10 . #1#))
I'd expect this one to return (11 12 13 14), but closely rereading the CLHS entry for the mapping functions, reveals that those are actually only defined for /proper lists/.
Is this something one could (and should?) reasonably expect to be de facto portable behaviour? IOW, am I to blame, or is ABCL?
I figure that at least LOOP's for-as-in-list clause could be meaningfully used in the above manner. So rewriting the code in question is no problem. Still, it's something I'd like to find out what's the commonly shared opinion about this.
-T.
Tobias C. Rittweiler wrote:
Just a guess, but what I could imagine that `parse-first-valid-form-spec' in swank-arglist.lisp could possibly be the culprit, as it uses the "mapping on several lists, one being circular" trick:
(mapcar #'+ '(1 2 3 4) '#1=(10 . #1#))
I'd expect this one to return (11 12 13 14), but closely rereading the CLHS entry for the mapping functions, reveals that those are actually only defined for /proper lists/.
Actually, ABCL seems to handle this form ok, returning the expected (11 12 13 14). And ABCL can compile PARSE-FIRST-VALID-FORM-SPEC from swank-arglist.lisp.
The problem ABCL seems to be once again [1] in its MOP when it attempts to compile the DEFMETHODs for EXTRA-KEYWORDS with the first argument specialized on (EQL 'MAKE-INSTANCE).
The following blows ABCL up with an unprintable (by SLIME) backtrace:
;;; From SLIME 'contrib/extra-keywords.lisp' r1.5
(defgeneric extra-keywords (operator &rest args) (:documentation "Return a list of extra keywords of OPERATOR (a symbol) when applied to the (unevaluated) ARGS. As a secondary value, return whether other keys are allowed. As a tertiary value, return the initial sublist of ARGS that was needed to determine the extra keywords."))
(defmethod extra-keywords ((operator (eql 'make-instance)) &rest args) (multiple-value-or (apply #'extra-keywords/make-instance operator args) (call-next-method)))
Is this something one could (and should?) reasonably expect to be de facto portable behaviour? IOW, am I to blame, or is ABCL?
I don't really feel qualified to answer about portability: all I can offer is that ABCL seems to understand the idiom correctly, but I haven't looked at the relevant code in the reader.
[1]: See the discussion around http://thread.gmane.org/gmane.editors.j.devel/1397 for context.
"Tobias C. Rittweiler" tcr@freebits.de writes:
(mapcar #'+ '(1 2 3 4) '#1=(10 . #1#))
I figure that at least LOOP's for-as-in-list clause could be meaningfully used in the above manner. So rewriting the code in question is no problem. Still, it's something I'd like to find out what's the commonly shared opinion about this.
I do not like it, because it uses a tricky construct to achieve something simple. I would use something like
(mapcar (curry #'+ 10) list)
instead, where
(defun curry (func &rest args) "Supplies @arg{args} to @arg{func} from the left." #'(lambda (&rest after-args) (apply func (append args after-args))))
is a utility function.
Nicolas
Nicolas Neuss neuss@math.uni-karlsruhe.de writes:
I do not like it, because it uses a tricky construct to achieve something simple. I would use something like
(mapcar (curry #'+ 10) list)
(Notice that this is not currying, but partial application; hence the util is probably better named `papply' or similiarly.)
"Tobias C. Rittweiler" tcr@freebits.de writes:
Nicolas Neuss neuss@math.uni-karlsruhe.de writes:
I do not like it, because it uses a tricky construct to achieve something simple. I would use something like
(mapcar (curry #'+ 10) list)
(Notice that this is not currying, but partial application; hence the util is probably better named `papply' or similiarly.)
Hm, I think that I am at least in agreement with Graham's AnsiCL book where he calls such functions 'curry' (supplying arguments from the left) and 'rcurry' (supplying arguments from the right).
Nicolas
* Tobias C. Rittweiler [2007-09-03 19:32+0200] writes:
Just a guess, but what I could imagine that `parse-first-valid-form-spec' in swank-arglist.lisp could possibly be the culprit, as it uses the "mapping on several lists, one being circular" trick:
[...]
Without parse-first-valid-form-spec, ABCL can compile the file.
(mapcar #'+ '(1 2 3 4) '#1=(10 . #1#))
I'd expect this one to return (11 12 13 14), but closely rereading the CLHS entry for the mapping functions, reveals that those are actually only defined for /proper lists/.
Never heard of this trick.
Is this something one could (and should?) reasonably expect to be de facto portable behaviour? IOW, am I to blame, or is ABCL?
Don't know, but parse-first-valid-form-spec gets my vote for most obfuscated function of the month.
Helmut.
On Sep 4, 2007, at 5:17 AM, Helmut Eller wrote:
- Tobias C. Rittweiler [2007-09-03 19:32+0200] writes:
Just a guess, but what I could imagine that `parse-first-valid-form-spec' in swank-arglist.lisp could possibly be the culprit, as it uses the "mapping on several lists, one being circular" trick:
(mapcar #'+ '(1 2 3 4) '#1=(10 . #1#))
I'd expect this one to return (11 12 13 14), but closely rereading the CLHS entry for the mapping functions, reveals that those are actually only defined for /proper lists/.
Never heard of this trick.
I think it's fair to consider it archaic, but it was once well known in Maclisp and early Lisp Machine Lisp. IIRC, the latter even had a builtin function `circular-list' to simplify the construction of such lists.
-- Scott
* Mark Evenson [2007-09-03 11:21+0200] writes:
o allows the use of slime-compile-and-load-file (C-c C-k) by patching the definition of COMPILER-CONDITION with explicit NILs, and does a load time creation of a COMPILER-CONDITION to get the MOP discriminating functions initialized correctly
I didn't see any difference for C-c C-k with and without the patch. Can you explain what it is?
I'd like to keep the definition of COMPILER-CONDITION as it is. Would it be enough to supply explicit nils in the load time form? Like so:
(let ((c (make-condition 'compiler-condition :original-condition nil :severity ':note :message "" :location nil)) (slots `(severity message short-message references location))) (dolist (slot slots) (funcall slot c)))
Helmut.
Helmut Eller wrote:
- Mark Evenson [2007-09-03 11:21+0200] writes:
o allows the use of slime-compile-and-load-file (C-c C-k) by patching the definition of COMPILER-CONDITION with explicit NILs, and does a load time creation of a COMPILER-CONDITION to get the MOP discriminating functions initialized correctly
I didn't see any difference for C-c C-k with and without the patch. Can you explain what it is?
On any version subsequent to (and inclusive of) ABCL-0.0.10 that I have compiled without this patch to SLIME, slime-compile-and-load-file doesn't work, producing a backtrace akin to something like [1]. I received exactly one (1) report of another user for whom this patch solved a similar problem, so I had some confidence that it would help some of the users of SLIME/ABCL. But I suspect that the the SLIME + ABCL community is fairly small, and it may be that for some unknown reason the bug only manifests itself for some versions of the JavaVM that hosts ABCL.
The patch was derived from a trial and error approach from the SLIME side of things, as opposed to ABCL internals (which I am only starting to understand). Essentially, without this patch the first time SLIME tries to create a SWANK-BACKEND::COMPILER-CONDITION with sufficiently complicated arguments (/me waves hands), I would get the backtrace. But if I:
1) gave the definition of COMPILER-CONDITION explicit nil :INITFORMs
2) created an empty COMPILER-CONDITION at load-time that calls each of the readers
then the bug doesn't occur.
Out of curiosity, which version of ABCL on which JVM on which OS where you testing on?
I'd like to keep the definition of COMPILER-CONDITION as it is. Would it be enough to supply explicit nils in the load time form? Like so:
(let ((c (make-condition 'compiler-condition :original-condition nil :severity ':note :message "" :location nil)) (slots `(severity message short-message references location))) (dolist (slot slots) (funcall slot c)))
Using this supplied form in 'swank-abcl.lisp' doesn't help. It seems that one needs the explicit :INITFORM nil for all the COMPILER-CONDITION slots.
Thanks for looking at the patch. Even if you decide not to accept it, at least this thread can give future SLIME/ABCL hackers (including me when I have the time) a place to start looking at this issue.
[1]: http://article.gmane.org/gmane.editors.j.devel/1397
* Mark Evenson [2007-09-04 14:52+0200] writes:
Out of curiosity, which version of ABCL on which JVM on which OS where you testing on?
ABCL 0.0.10 (the version from the web page) Sun's JVM 1.6.0/Linux-2.6/x86
(let ((c (make-condition 'compiler-condition :original-condition nil :severity ':note :message "" :location nil)) (slots `(severity message short-message references location))) (dolist (slot slots) (funcall slot c)))
Using this supplied form in 'swank-abcl.lisp' doesn't help. It seems that one needs the explicit :INITFORM nil for all the COMPILER-CONDITION slots.
It seems to help here, at least a bit. I used this file for testing:
(defun fib (number) (let ((x 1)) (if (= number 0) 1 (+ number (fib (1- number))))))
(defun foo () (bar))
#-abcl (defun baz () (if))
The warning in fib is reported as it should; the warning about the undefined function bar is only printed in the console; and I had to disable baz, because otherwise ABCL jumps to the debugger.
Thanks for looking at the patch. Even if you decide not to accept it, at least this thread can give future SLIME/ABCL hackers (including me when I have the time) a place to start looking at this issue.
I only committed my version.
Helmut.