From: <as...@ma...> - 2003-12-10 15:31:41
|
It'd be nice to have arglists not just for functions, but for macros and special forms, too. So, how about something like the following: - move arglist and setArglist up from Function to Functional - put macroObject.setArglist(lambdaList); in DEFMACRO - extend ARGLIST to deal with MacroObject, or change it to deal with any Functional Is this a sound plan? Andras |
From: Peter G. <pe...@ar...> - 2003-12-10 16:13:52
|
On Wed, 10 Dec 2003 at 17:30:26 +0100, Andr=E1s_Simon wrote: > It'd be nice to have arglists not just for functions, but for macros > and special forms, too. So, how about something like the following: > > - move arglist and setArglist up from Function to Functional > - put macroObject.setArglist(lambdaList); in DEFMACRO > - extend ARGLIST to deal with MacroObject, or change it to deal with > any Functional > > Is this a sound plan? I think so. Two points: - If we want ARGLIST to support special operators as well as macros, don't we have to extend it to deal with any Functional, and not just a MacroObject? - DEFMACRO is initially defined (for bootstrapping purposes) as a special operator in Primitives.java, and then later redefined as a macro in precompiler.lisp, so you'd need to add a call to %SET- ARGLIST to its definition in precompiler.lisp too. A bit of further explanation of the second point: ABL, like ACL and CLISP, provides permanent implementations of certain macros (DO, DO*, DOTIMES, and DOLIST, among others) as special operators, in addition to their implementations as macros per se. The special operator implementations are used in interpreted code, even after the macro versions have been defined, since they tend to run considerably faster than the macro expansions (when the macro expansions aren't JVM-compiled). The choice of which implementation to use is made by the precompiler, depending on whether the precompiler was invoked by the JVM compiler or not. DEFMACRO, on the other hand, is initially implemented as a special operator just to bootstrap the system. The early version only supports the simplest macros (in particular, there's no destructuring). When DEFMACRO is re-implemented as a macro at the end of precompiler.lisp, its early implementation as a special operator is overwritten by the additional FSET call ("Make an exception just this one time...") at the bottom of precompiler.lisp, so DEFMACRO ends up being just a macro. -Peter |
From: <as...@ma...> - 2003-12-10 21:47:14
|
Thanks for the explanation! I committed the necessary changes, and ARGLIST now works for user-defined macros, though not (yet) for primitives (which probably shows that I haven't completely understood your explanation). But I thought I can deal with that later. Andras ps. I love it when -: (MINUEND &REST SUBTRAHENDS) appears in the echo area. Allegro's -: (NUMBER &REST MORE-NUMBERS) is just plain boring, compared to that :-) |
From: Slava P. <sl...@je...> - 2003-12-10 21:54:37
|
On Wed, 2003-12-10 at 17:46, Andr=E1s Simon wrote: > ps. I love it when >=20 > -: (MINUEND &REST SUBTRAHENDS) >=20 > appears in the echo area. Allegro's What is a MINUEND, and what is a SUBTRAHEND? :-) --=20 Slava Pestov |
From: <as...@ma...> - 2003-12-10 22:12:20
|
On Wed, 10 Dec 2003, Slava Pestov wrote: > On Wed, 2003-12-10 at 17:46, Andr=E1s Simon wrote: > > ps. I love it when > > > > -: (MINUEND &REST SUBTRAHENDS) > > > > appears in the echo area. Allegro's > > What is a MINUEND, and what is a SUBTRAHEND? :-) According to m-w.com, MINUEND is `a number from which the subtrahend is to be subtracted' I think this explains SUBTRAHEND reasonably well, too. :-) Andras |
From: <as...@ma...> - 2003-12-11 16:42:21
|
On Wed, 10 Dec 2003, Peter Graves wrote: > ABL, like ACL and CLISP, provides permanent implementations of > certain macros (DO, DO*, DOTIMES, and DOLIST, among others) as > special operators, in addition to their implementations as macros per > se. There's a small issue with macros defined as special operators, namely that ilisp doesn't attempt to look up their arglists. If it did, then given a symbol, it could check whether (get symbol 'system::macroexpand-macro) returned a non-nil value, and if so, could feed that to ARGLIST. Or ARGLIST could do the same, that is, given a symbol that names a special operator, check whether is has arglist info, and if not, apply the Java equivalent of (get symbol 'system::macroexpand-macro) to see if there's a macro of the same name. What I don't like about it is that then ARGLIST could, in principle, be lying (in the unlikely case that the macro has a different arglist then the special operator). It's clear that ilisp should be patched to not ignore special-operators in ABL. The question is whether ARGLIST should be doing the extra calculations or ilisp should feed it the right argument. The latter is certainly easier. What do you think? Andras |
From: Peter G. <pe...@ar...> - 2003-12-11 18:44:57
|
On Thu, 11 Dec 2003 at 18:41:08 +0100, Andr=E1s_Simon wrote: > There's a small issue with macros defined as special operators, > namely that ilisp doesn't attempt to look up their arglists. This clearly seems like a limitation in ilisp. ACL's ARGLIST function, for example, returns useful information about special operators too, and it seems silly not to pass that information along. > If it did, then given a symbol, it could check whether (get symbol > 'system::macroexpand-macro) returned a non-nil value, and if so, > could feed that to ARGLIST. Or ARGLIST could do the same, that is, > given a symbol that names a special operator, check whether is has > arglist info, and if not, apply the Java equivalent of (get symbol > 'system::macroexpand-macro) to see if there's a macro of the same > name. What I don't like about it is that then ARGLIST could, in > principle, be lying (in the unlikely case that the macro has a > different arglist then the special operator). I think it would be fine for ARGLIST to do this small amount of extra work. That would make it more useful in the case where you're not using it under ilisp. If the macro has a different arglist than the special operator, that's a separate bug in ABL that should be fixed in the place where it's actually broken (i.e. by fixing the arglist that's incorrect). > It's clear that ilisp should be patched to not ignore special- > operators in ABL. The question is whether ARGLIST should be doing the > extra calculations or ilisp should feed it the right argument. The > latter is certainly easier. Well, it can't be too much easier, since fixing ARGLIST to do the work should only take a few lines of code. > What do you think? What I really think is that the way forward is slime. But whether it's for slime, or for ilisp, or for j, or for running in a bare xterm, clearly ABL's ARGLIST should do the best job it possibly can. -Peter |
From: <as...@ma...> - 2003-12-12 00:05:18
|
On Thu, 11 Dec 2003, Peter Graves wrote: > On Thu, 11 Dec 2003 at 18:41:08 +0100, Andr=E1s_Simon wrote: > > There's a small issue with macros defined as special operators, > > namely that ilisp doesn't attempt to look up their arglists. > > This clearly seems like a limitation in ilisp. But it's among the minor ones. And maybe it's there because of the limitations of the CL's it's used with, I don't know. > > ACL's ARGLIST function, for example, returns useful information about > special operators too, and it seems silly not to pass that information > along. Agreed. > I think it would be fine for ARGLIST to do this small amount of extra > work. That would make it more useful in the case where you're not using > it under ilisp. > > If the macro has a different arglist than the special operator, that's > a separate bug in ABL that should be fixed in the place where it's > actually broken (i.e. by fixing the arglist that's incorrect). I'm convinced. > > > It's clear that ilisp should be patched to not ignore special- > > operators in ABL. The question is whether ARGLIST should be doing the > > extra calculations or ilisp should feed it the right argument. The > > latter is certainly easier. > > Well, it can't be too much easier, since fixing ARGLIST to do the work > should only take a few lines of code. > > > What do you think? > > What I really think is that the way forward is slime. Yes, but it's a very long way. I'm a slime fan myself, but I'm happy that after weeks of dreaming about slime it dawned on me that ilisp may be a more feasible target, and would make life much easier (for me anyway). After all, I've been using ilisp for years with CMUCL, and though I love to hate it, after some customization (a painful process) it works well enough that I don't go mad when switching from eli to ilisp and back again. I don't know how people use ABL (and actually I'm quite curious); I used to start it in an emacs shell, and compared to that, ilisp is wonderful :-) Andras |
From: Doug M. <do...@mc...> - 2003-12-12 02:55:28
|
András Simon <as...@ma...> writes: > anyway). After all, I've been using ilisp for years with CMUCL, and > though I love to hate it, after some customization (a painful process) > it works well enough that I don't go mad when switching from eli to > ilisp and back again. I don't know how people use ABL (and actually > I'm quite curious); I used to start it in an emacs shell, and compared > to that, ilisp is wonderful :-) I use ABL inside J, and it works pretty well for me, even though I'm a huge Emacs-addict otherwise. -Doug |
From: <as...@ma...> - 2003-12-14 19:30:04
|
On Thu, 11 Dec 2003, Doug McNaught wrote: > I use ABL inside J, and it works pretty well for me, even though I'm a > huge Emacs-addict otherwise. Do symbol completion, arglist lookup, evaluating definitions, and macroexpansion work in source file buffers in j? (These are the main reasons I'm so happy with ilisp now.) What other features are there that make (interactive) Lisp programming easy in j? Just curious... Andras |
From: Doug M. <do...@mc...> - 2003-12-14 20:37:34
|
András Simon <as...@ma...> writes: > On Thu, 11 Dec 2003, Doug McNaught wrote: > >> I use ABL inside J, and it works pretty well for me, even though I'm a >> huge Emacs-addict otherwise. > > Do symbol completion, arglist lookup, evaluating definitions, and > macroexpansion work in source file buffers in j? (These are the main > reasons I'm so happy with ilisp now.) What other features are there > that make (interactive) Lisp programming easy in j? Just curious... Arglist lookup isn't there and I do miss it. Evaluating definitions works fine (bound by default to Ctrl-Alt-E). Symbol completion and macroexpansion aren't there, but I haven't yet come to rely on them in other environments. So you would probably like J less than I do. None of its deficiencies are insurmountable, of course, given a bit of hacking time... -Doug |
From: <as...@ma...> - 2003-12-14 23:17:49
|
On Sun, 14 Dec 2003, Doug McNaught wrote: > Arglist lookup isn't there and I do miss it. Evaluating definitions > works fine (bound by default to Ctrl-Alt-E). Symbol completion and > macroexpansion aren't there, but I haven't yet come to rely on them in > other environments. I see. For me, symbol completion is perhaps the single most important feature (besides, of course, eval-defun and automatic indentation - which J probably does better than ilisp, by the way). I'm just unable to write DECODE-UNIVESRAL-TIME without some external help :-) > > So you would probably like J less than I do. None of its deficiencies > are insurmountable, of course, given a bit of hacking time... > The hacking time shortage isn't insurmountable either, given enough J using Lisp hackers... Especially that it has a quite nice scripting language. But seriously, I don't know how much of the editor functionality is accessible from Lisp, but I wouldn't be surprised if J could be turned into a better Lisp environment than emacs+slime is with not much more work than ABL needs to become slime-capable. Andras |
From: Peter G. <pe...@ar...> - 2003-12-15 00:21:54
|
On Mon, 15 Dec 2003 at 01:16:37 +0100, Andr=E1s_Simon wrote: > On Sun, 14 Dec 2003, Doug McNaught wrote: > > > Arglist lookup isn't there and I do miss it. Evaluating definitions > > works fine (bound by default to Ctrl-Alt-E). Symbol completion and > > macroexpansion aren't there, but I haven't yet come to rely on them i= n > > other environments. > > I see. For me, symbol completion is perhaps the single most important > feature (besides, of course, eval-defun and automatic indentation - > which J probably does better than ilisp, by the way). I'm just unable > to write DECODE-UNIVESRAL-TIME without some external help :-) > > > > > So you would probably like J less than I do. None of its deficiencie= s > > are insurmountable, of course, given a bit of hacking time... > > > > The hacking time shortage isn't insurmountable either, given enough J > using Lisp hackers... Especially that it has a quite nice scripting > language. But seriously, I don't know how much of the editor > functionality is accessible from Lisp, but I wouldn't be surprised if > J could be turned into a better Lisp environment than emacs+slime is > with not much more work than ABL needs to become slime-capable. In principle, all of the editor functionality is accessible from Lisp. (After all, you can write a whole Swing app in Lisp, right?) In practice, I need to implement quite a few more editor-related primitives in LispAPI.java. That effort got slow downed a bit by the distraction of doing an ANSI-compliant Common Lisp. But making j a really good Lisp environment requires making ABL slime- capable in any case, and that has been on my list for a while. The things holding it up are (1) clarifying the implementation of streams a bit, (2) writing READ-SEQUENCE and WRITE-SEQUENCE, and (3) settling upon a proper socket API (which I'm thinking should be kinda like Allegro's). Once those things are done, it should be possible to write swank-armedbear.lisp. Once swank is in place, ABL should work with emacs/slime, and j can start implementing its own version of slime. In the end, j's version of slime should work with all the slime-capable Lisps, not just ABL. Another thing that's on my list is rewriting j's Lisp mode in Lisp, which should help fill in those missing functions in LispAPI.java, as well as making j more accessible to Lisp hackers. But there are only so many hours in the day, so it may be a while before all of this gets done. -Peter |
From: <as...@ma...> - 2003-12-15 01:05:19
|
On Sun, 14 Dec 2003, Peter Graves wrote: > > But making j a really good Lisp environment requires making ABL slime- > capable in any case, and that has been on my list for a while. The Doesn't this depend on whether you want j to be a good Lisp environment for all CL implementations or just ABL? E.g., for ABL only, sockets and Gray streams are probably not needed. I'm really just curious, because I have to use Emacs anyway for various reasons (I'm too much used to its key bindings, need to use it sometimes in a console, etc.) Andras |
From: Peter G. <pe...@ar...> - 2003-12-15 01:35:46
|
On Mon, 15 Dec 2003 at 03:04:06 +0100, Andr=E1s_Simon wrote: > On Sun, 14 Dec 2003, Peter Graves wrote: > > But making j a really good Lisp environment requires making ABL slime= - > > capable in any case, and that has been on my list for a while. The > > Doesn't this depend on whether you want j to be a good Lisp > environment for all CL implementations or just ABL? E.g., for ABL > only, sockets and Gray streams are probably not needed. I'm really > just curious, because I have to use Emacs anyway for various reasons > (I'm too much used to its key bindings, need to use it sometimes in a > console, etc.) Well, j still needs some way to talk to ABL in the situation where ABL is running in a separate process, which is the way I normally run it. And "some way" is either sockets, etc., or it's the abuse of *standard- input*/*standard-output* that ilisp does, which tends to be much less robust. If you use the "jlisp" command in j (rather than "lisp") and run ABL in j's process, you risk bringing the editor down if you screw things up in the Lisp environment, so I only do that when I really do want to interact with the instance of ABL that's running inside j (or at least that's running inside j the way I run j; if you don't have ~/.j/init.lisp, j doesn't start Lisp at all, and there's no ABL running inside j, unless you run "jlisp"). If you run ABL as a separate process, it's really no different from running sbcl or cmucl or Allegro within j (which I do all the time too). So ABL is not as much of a special case as you might think. -Peter |
From: <as...@ma...> - 2003-12-14 19:21:51
|
Macros (not macro versions of special operators) defined with the Java-version of DEFMACRO in boot.lisp seem to "lose their identity" somewhere. For example, in one run, when IN-PACKAGE is defined, it's #<MACRO-OBJECT @ #x7b6889> but by the time the prompt appears, CL-USER(12): (symbol-function 'in-package) #<MACRO-OBJECT @ #xa4e743> I'd like to know what exactly happens, because the new MacroObject knows nothing about the arglist stored in the original. Andras |
From: Peter G. <pe...@ar...> - 2003-12-14 20:05:41
|
On Sun, 14 Dec 2003 at 21:20:33 +0100, Andr=E1s_Simon wrote: > Macros (not macro versions of special operators) defined with the > Java-version of DEFMACRO in boot.lisp seem to "lose their identity" > somewhere. For example, in one run, when IN-PACKAGE is defined, it's > > #<MACRO-OBJECT @ #x7b6889> > > but by the time the prompt appears, > > CL-USER(12): (symbol-function 'in-package) > #<MACRO-OBJECT @ #xa4e743> > > I'd like to know what exactly happens, because the new MacroObject > knows nothing about the arglist stored in the original. The original definitions of early macros are later replaced by PRECOMPILE-PACKAGE (boot.lisp, line 105): (sys::precompile-package "COMMON-LISP") This explains why the object loses its identity (although in the case of IN-PACKAGE, I suspect the precompiler doesn't really change the code.) = But I'm not sure why the arglist is being lost, since PRECOMPILE does call %SET-ARGLIST (precompiler.lisp, line 531): (when (and name (functionp result)) (%set-lambda-name result name) (%set-call-count result (%call-count definition)) (%set-arglist result (arglist definition)) (if (and (symbolp name) (macro-function name)) (setf (fdefinition name) (make-macro result)) (setf (fdefinition name) result))) I don't have time to track this down any further right now, but maybe this information is a starting point. -Peter |
From: <as...@ma...> - 2003-12-14 20:12:10
|
On Sun, 14 Dec 2003, Peter Graves wrote: > I don't have time to track this down any further right now, but maybe > this information is a starting point. Very much so! Thanks, Andras |
From: <as...@ma...> - 2003-12-14 22:51:20
|
On Sun, 14 Dec 2003, Peter Graves wrote: > > But I'm not sure why the arglist is being lost, since PRECOMPILE does > call %SET-ARGLIST (precompiler.lisp, line 531): > > (when (and name (functionp result)) > (%set-lambda-name result name) > (%set-call-count result (%call-count definition)) > (%set-arglist result (arglist definition)) > (if (and (symbolp name) (macro-function name)) > (setf (fdefinition name) (make-macro result)) > (setf (fdefinition name) result))) > In the case of macros, this sets the arglist of the expansion function. So I propose sth like this instead: (when (and name (functionp result)) (%set-lambda-name result name) (%set-call-count result (%call-count definition)) (if (and (symbolp name) (macro-function name)) (let ((mac (make-macro result))) (%set-arglist mac (arglist (symbol-function name))) (setf (fdefinition name) mac)) (progn (setf (fdefinition name) result) (%set-arglist result (arglist definition))))) Does this look OK? Perhaps the other %set-XXX's should be moved inside the IF too. Andras |
From: Peter G. <pe...@ar...> - 2003-12-14 23:57:14
|
On Mon, 15 Dec 2003 at 00:50:06 +0100, Andr=E1s_Simon wrote: > On Sun, 14 Dec 2003, Peter Graves wrote: > > But I'm not sure why the arglist is being lost, since PRECOMPILE does= > > call %SET-ARGLIST (precompiler.lisp, line 531): > > > > (when (and name (functionp result)) > > (%set-lambda-name result name) > > (%set-call-count result (%call-count definition)) > > (%set-arglist result (arglist definition)) > > (if (and (symbolp name) (macro-function name)) > > (setf (fdefinition name) (make-macro result)) > > (setf (fdefinition name) result))) > > > > In the case of macros, this sets the arglist of the expansion > function. So I propose sth like this instead: > > (when (and name (functionp result)) > (%set-lambda-name result name) > (%set-call-count result (%call-count definition)) > (if (and (symbolp name) (macro-function name)) > (let ((mac (make-macro result))) > (%set-arglist mac (arglist (symbol-function name))) > (setf (fdefinition name) mac)) > (progn > (setf (fdefinition name) result) > (%set-arglist result (arglist definition))))) > > Does this look OK? Perhaps the other %set-XXX's should be moved > inside the IF too. I tried this, and it seems to work fine (at least for IN-PACKAGE). We're still not getting arglists for macros that are also defined as special operators (like WHEN and UNLESS, defined as special operators in Primitives.java and as macros right below IN-PACKAGE in boot.lisp). This is probably a separate issue, though. -Peter |
From: <as...@ma...> - 2003-12-15 00:29:29
|
On Sun, 14 Dec 2003, Peter Graves wrote: > We're still not getting arglists for macros that are also defined as > special operators (like WHEN and UNLESS, defined as special operators > in Primitives.java and as macros right below IN-PACKAGE in boot.lisp). > This is probably a separate issue, though. It's because I didn't want to commit the new ARGLIST until it works for everything. I'll test it a bit more, clean it up, and then commit. Andras |