emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Always-true predicate?


From: Stefan Monnier
Subject: Re: Always-true predicate?
Date: Fri, 19 Feb 2021 15:11:53 -0500
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

>> > (f a b c &rest d)
>> > rather than
>> > (apply #'f a b c d)
>> I don't think it's sufficiently nicer to justify making such a change,
>
> I think "usage mimics declaration" is a very important concept,

I generally agree and the above syntax is indeed satisfactory from that
point of view (and funnily enough Scheme's neat (lambda (x . y) body)
syntax (which is arguably inspired by a similar desire) does not enjoy
such a nice equivalent at call sites since (f x . (append a b)) can't
be distinguished from (f x append a . b)).

> but if we're making sunk-cost arguments, one could argue against
> fairly much any change...

One can argue against any change, indeed (as demonstrated daily on this
list ;-), so in the end it's always a judgment call on the
overall tradeoff.

>> OTOH, the nice thing about `apply` is that it's just a function: no
>> special treatment, no new syntax, nothing.  Try `grep apply
>> lisp/emacs-lisp/bytecomp.el` and see how it really needs no
>> special treatment.
> ...but it gets that special treatment, which is why (apply #'or) is
> mis-compiled.

Actually, it's not the compiler, it's the optimizer.
[ Yes, it's a nitpick, but nevertheless...
  Also, I'm not completely sure in which sense it "miscompiles" it,
  since it can't be compiled correctly, AFAIK.  ]

>> I'd rather reduce the use of `&rest` and `apply` than try to make it
>> more sexy, since it's fundamentally quite inefficient
> I think the inefficiency is fundamental to "apply", not to "&rest".
> When you call a known procedure all the packing and unpacking of
> arguments can be inlined...

IMO it's more fundamental to `&rest` because the callee can rely on the
`&rest` list being a fresh new list (it can safely perform destructive
update on it).

> I think we're back to a fundamental question here: if I understand
> correctly, to you, an ELisp function is fundamentally of the "take a
> list, return a Lisp object or throw" type, as though it were defined
> like this:
>
> (defan f args (if (/= (length args) 2) (throw
> 'wrong-number-of-arguments)) (+ (car args) (cadr args)))

Indeed.

> In your world, (lambda (&rest args) (apply #'f args)) is the same as
> f. In my world, we have "func-arity", to which it isn't.

In my view, a function value of the form (closure ...) or (lambda ...)
or #[...] has arity, but a function value represented by a SYMBOL does
not because it can change at any time.


        Stefan




reply via email to

[Prev in Thread] Current Thread [Next in Thread]