[slime-devel] Re: macro indentation

Chris Capel pdf23ds at gmail.com
Fri Dec 17 17:06:55 UTC 2004


On 17 Dec 2004 12:29:27 +0100, Luke Gorrie <luke at synap.se> wrote:
> Chris Capel <pdf23ds at 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 at 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
-- 
"What is it like to be a bat? What is it like to bat a bee? What is it
like to be a bee being batted? What is it like to be a batted bee?"
-- The Mind's I (Hofstadter, Dennet)



More information about the slime-devel mailing list