On 17 Dec 2004 12:29:27 +0100, Luke Gorrie luke@synap.se wrote:
Chris Capel pdf23ds@gmail.com writes:
Shouldn't &rest be treated like &body as far as macroindentation is concerned?
No. IIUC the only difference between &rest and &body is that tools are supposed to indent &body specially but not &rest. (I believe this is discussed in the hyperspec.)
I phrased that badly. I should have said "Isn't this indentation wrong?" and "Shouldn't it be indented similarly to if it used &body instead of &rest?" In fact, I think &rest *ought* to be treated specially, no matter how &body is treated, and no matter how the two treatements correlate, even if the treatements end up being identical in some, or all, cases.
However, the indentation you're seeing in that example isn't determined by slime but by Emacs itself. Emacs has builtin rules for how to indent def* and with-* macros and by default SLIME won't override them.
If you want SLIME to learn indentation for def* and with-* then you can set `slime-conservative-indentation' to nil.
Actually, I have that set to nil already. This is still the behavior I see. And this is the reason: swank:macro-indentation returns nil for all macros with &rest args, so the indentation used is the default for cl-indent, which for def* forms, is to indent the first two forms by 4, and the rest by 2. (I think that was a fairly poor decision, but hey.)
Chris Capel pdf23ds@gmail.com writes:
(defmacro deffoo (name bar baz &rest options) ...)
With this definition (or any definition using rest, really), this is the indentation you get:
(deffoo foo bar baz opt1 opt2)
Look at that again. The third argument is being indented as if it were a &rest or a &body. But it should have the same indentation as "bar". One way to accomplish this is to treat &rest and &body the same for macro-indentation purposes. Another way might be to indent &rest args even further than the preceeding args. But in any case, the current behavior is broken.
Another example:
(defmacro testtest (foo bar baz &rest options) nil)
is indented
(testtest foo bar baz opt1 opt2)
This is less annoying, as it's at least consistent, but still not optimal, in my opinion, as the &rest arguments should be distinguished somehow by indentation. You can get the same behavior from def* forms by disabling lisp-prefix-match-indentation, but I don't think that's a good solution.
To see the intended behaviour take for example the indentation arglist (mapcar f list &rest lists) vs. (with-foo foo &body body):
(mapcar #'the-function-i-want-to-map my-first-list my-second-list)
(with-foo my-foo (frob1) (frob2))
I think mapcar is a bad example, because it takes one list argument and one &rest lists argument. To be consistent, the lambda-list should be simply (function &rest lists). If that were the case, I would be perfectly happy with a call indented like
(mapcar #'identity list1 list2)
Besides, mapcar doesn't really affect anything in this discussion, as swank doesn't return indentations for common lisp symbols, and it's special-cased in cl-indent anyway.
Chris Capel