* Declaring Lisp function types
@ 2024-02-23 16:02 Andrea Corallo
2024-02-23 23:35 ` Adam Porter
` (4 more replies)
0 siblings, 5 replies; 72+ messages in thread
From: Andrea Corallo @ 2024-02-23 16:02 UTC (permalink / raw)
To: emacs-devel
Hi all,
I'm looking into moving out the function type declarations in
'comp-known-type-specifiers' in order to move them to where the function
are actually defined. This to easy maintenance (ATM they get out of
sync) and to allow the user for (indeed optionally) declaring function
types.
In principle I believe we are interested in expressing the the argument
types and (maybe optionally) the return type.
Some ways CL does this:
;;1
(declaim (ftype (function (integer integer) integer) sum))
;; ^^inputs ^^output [optional]
(defun sum (a b)
(declare (integer a b))
(+ a b))
;;2
(defun sum (a b)
(declare (integer a b))
(+ a b))
;;3 through 'defstar' (a CL library not in the standard)
(defun* sum ((a integer) (b integer))
(+ a b))
;;4 again through 'defstar'
(defun* (sum -> integer) ((a integer) (b integer))
(+ a b))
I find 1 a bit too verbose and I think most of times we want a way to do
the declaration inside the function definition.
I think 2 would be not trivial to implement with our current declare
mechanism (as it conflicts) and does *not* allow for declaring the
return type.
3 and 4 are I guess are okay assuming we would fine with extending the
defun syntax.
I initially thought also about adding an ftype declaration like:
(defun sum (a b)
(declare (ftype (function (integer integer) integer)))
(+ a b))
But looked a bit too verbose to me.
Finally on top of 'scratch/func-type-decls' (where I there was already a
similar work for primitives) I pushed some commits that allows for the
following style:
(defun sum (a b)
(declare (function (integer integer) integer))
(+ a b))
I moved all function declaration out of 'comp-known-type-specifiers' and
everything looks functional now.
Before writing a ton of changelogs I thought was good to get some
feedback anyway. WDYT?
Thanks!
Andrea
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-02-23 16:02 Declaring Lisp function types Andrea Corallo
@ 2024-02-23 23:35 ` Adam Porter
2024-02-24 7:10 ` Eli Zaretskii
2024-02-24 9:21 ` Andrea Corallo
2024-02-25 17:04 ` Alan Mackenzie
` (3 subsequent siblings)
4 siblings, 2 replies; 72+ messages in thread
From: Adam Porter @ 2024-02-23 23:35 UTC (permalink / raw)
To: acorallo; +Cc: emacs-devel
Hi Andrea,
> Finally on top of 'scratch/func-type-decls' (where I there was already a
> similar work for primitives) I pushed some commits that allows for the
> following style:
>
> (defun sum (a b)
> (declare (function (integer integer) integer))
> (+ a b))
>
> I moved all function declaration out of 'comp-known-type-specifiers' and
> everything looks functional now.
>
> Before writing a ton of changelogs I thought was good to get some
> feedback anyway. WDYT?
That looks nice to me. My only suggestion would be to change the symbol
`function` to `type`, i.e.
(defun sum (a b)
(declare (type (integer integer) integer))
(+ a b))
Because it would be more concise and descriptive.
Thanks for your work on these features!
--Adam
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-02-23 23:35 ` Adam Porter
@ 2024-02-24 7:10 ` Eli Zaretskii
2024-02-24 8:53 ` Tomas Hlavaty
2024-02-24 8:56 ` Adam Porter
2024-02-24 9:21 ` Andrea Corallo
1 sibling, 2 replies; 72+ messages in thread
From: Eli Zaretskii @ 2024-02-24 7:10 UTC (permalink / raw)
To: Adam Porter; +Cc: acorallo, emacs-devel
> Date: Fri, 23 Feb 2024 17:35:12 -0600
> Cc: emacs-devel@gnu.org
> From: Adam Porter <adam@alphapapa.net>
>
> That looks nice to me. My only suggestion would be to change the symbol
> `function` to `type`, i.e.
>
> (defun sum (a b)
> (declare (type (integer integer) integer))
> (+ a b))
>
> Because it would be more concise and descriptive.
FWIW, Andrea's proposal looks more descriptive to me. "Type" is too
general, whereas "function" is more specific.
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-02-24 7:10 ` Eli Zaretskii
@ 2024-02-24 8:53 ` Tomas Hlavaty
2024-02-24 9:08 ` Adam Porter
2024-02-24 8:56 ` Adam Porter
1 sibling, 1 reply; 72+ messages in thread
From: Tomas Hlavaty @ 2024-02-24 8:53 UTC (permalink / raw)
To: Eli Zaretskii, Adam Porter; +Cc: acorallo, emacs-devel
On Sat 24 Feb 2024 at 09:10, Eli Zaretskii <eliz@gnu.org> wrote:
>> (declare (type (integer integer) integer))
> FWIW, Andrea's proposal looks more descriptive to me. "Type" is too
> general, whereas "function" is more specific.
both are hard to grep for which is inconvenient
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-02-24 8:53 ` Tomas Hlavaty
@ 2024-02-24 9:08 ` Adam Porter
2024-02-24 9:24 ` Andrea Corallo
0 siblings, 1 reply; 72+ messages in thread
From: Adam Porter @ 2024-02-24 9:08 UTC (permalink / raw)
To: Tomas Hlavaty, Eli Zaretskii; +Cc: acorallo, emacs-devel
On 2/24/24 02:53, Tomas Hlavaty wrote:
> On Sat 24 Feb 2024 at 09:10, Eli Zaretskii <eliz@gnu.org> wrote:
>>> (declare (type (integer integer) integer))
>> FWIW, Andrea's proposal looks more descriptive to me. "Type" is too
>> general, whereas "function" is more specific.
>
> both are hard to grep for which is inconvenient
"(declare (type" would be hard to grep for? Wouldn't that be a unique
string in Elisp code? I can't find any matches for that in master.
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-02-24 9:08 ` Adam Porter
@ 2024-02-24 9:24 ` Andrea Corallo
2024-02-24 15:13 ` Tomas Hlavaty
0 siblings, 1 reply; 72+ messages in thread
From: Andrea Corallo @ 2024-02-24 9:24 UTC (permalink / raw)
To: Adam Porter; +Cc: Tomas Hlavaty, Eli Zaretskii, emacs-devel
Adam Porter <adam@alphapapa.net> writes:
> On 2/24/24 02:53, Tomas Hlavaty wrote:
>> On Sat 24 Feb 2024 at 09:10, Eli Zaretskii <eliz@gnu.org> wrote:
>>>> (declare (type (integer integer) integer))
>>> FWIW, Andrea's proposal looks more descriptive to me. "Type" is too
>>> general, whereas "function" is more specific.
>> both are hard to grep for which is inconvenient
>
> "(declare (type" would be hard to grep for? Wouldn't that be a unique
> string in Elisp code? I can't find any matches for that in master.
Can't either for "(declare (function" :)
Andrea
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-02-24 9:24 ` Andrea Corallo
@ 2024-02-24 15:13 ` Tomas Hlavaty
2024-02-24 15:21 ` Tomas Hlavaty
0 siblings, 1 reply; 72+ messages in thread
From: Tomas Hlavaty @ 2024-02-24 15:13 UTC (permalink / raw)
To: Andrea Corallo, Adam Porter; +Cc: Eli Zaretskii, emacs-devel
On Sat 24 Feb 2024 at 04:24, Andrea Corallo <acorallo@gnu.org> wrote:
>>> both are hard to grep for which is inconvenient
>>
>> "(declare (type" would be hard to grep for? Wouldn't that be a unique
>> string in Elisp code? I can't find any matches for that in master.
>
> Can't either for "(declare (function" :)
there is no requirement that the space in between is what you both say
it is
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-02-24 15:13 ` Tomas Hlavaty
@ 2024-02-24 15:21 ` Tomas Hlavaty
2024-02-24 15:24 ` Tomas Hlavaty
0 siblings, 1 reply; 72+ messages in thread
From: Tomas Hlavaty @ 2024-02-24 15:21 UTC (permalink / raw)
To: Andrea Corallo, Adam Porter; +Cc: Eli Zaretskii, emacs-devel
On Sat 24 Feb 2024 at 16:13, Tomas Hlavaty <tom@logand.com> wrote:
> On Sat 24 Feb 2024 at 04:24, Andrea Corallo <acorallo@gnu.org> wrote:
>>>> both are hard to grep for which is inconvenient
>>>
>>> "(declare (type" would be hard to grep for? Wouldn't that be a unique
>>> string in Elisp code? I can't find any matches for that in master.
>>
>> Can't either for "(declare (function" :)
>
> there is no requirement that the space in between is what you both say
> it is
examples:
(declare (debug t) (indent 1) (function ...))
(declare (debug t)
(indent 1)
(function ...))
your aproach will miss cases
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-02-24 7:10 ` Eli Zaretskii
2024-02-24 8:53 ` Tomas Hlavaty
@ 2024-02-24 8:56 ` Adam Porter
2024-02-24 10:03 ` Eli Zaretskii
1 sibling, 1 reply; 72+ messages in thread
From: Adam Porter @ 2024-02-24 8:56 UTC (permalink / raw)
To: eliz; +Cc: acorallo, adam, emacs-devel
>> That looks nice to me. My only suggestion would be to change the symbol
>> `function` to `type`, i.e.
>>
>> (defun sum (a b)
>> (declare (type (integer integer) integer))
>> (+ a b))
>>
>> Because it would be more concise and descriptive.
>
> FWIW, Andrea's proposal looks more descriptive to me. "Type" is too
> general, whereas "function" is more specific.
I don't understand what you mean. ISTM that "type" is exactly what's
being declared; "function" would seem redundant, because it's already
within a defun form, and less accurate, because it's not declaring the
function itself but its types.
Another consideration is that using `(declare (function ...))` would
preclude allowing `declare-function` forms to be moved into the
`declare` form.
In fact, in Ement.el, I've already implemented this, please see:
https://github.com/alphapapa/ement.el/blob/2b9725accdaed1913b83b2495d3f901ee3aba892/ement-lib.el#L67-L89
Which is used like:
https://github.com/alphapapa/ement.el/blob/2b9725accdaed1913b83b2495d3f901ee3aba892/ement-notifications.el#L55
The advantage of allowing `declare-function` to be done as `(declare
(function ...))` within a defun form is that it keeps the declaration
with the function that makes it necessary, so if the defun is moved to
another location, the declaration goes with it; and that then makes it
easier to remove the declaration later if it becomes unnecessary. (And,
IMHO it looks cleaner than having declare-function forms littering a file.)
As you can see, I have a TODO item to propose this upstream, but I
hadn't gotten around to it yet. After having had it in "production" for
some time without any reported problems, and seeing this thread, now
seems like an appropriate time to propose it. :)
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-02-24 8:56 ` Adam Porter
@ 2024-02-24 10:03 ` Eli Zaretskii
2024-02-25 7:35 ` Adam Porter
0 siblings, 1 reply; 72+ messages in thread
From: Eli Zaretskii @ 2024-02-24 10:03 UTC (permalink / raw)
To: Adam Porter; +Cc: acorallo, adam, emacs-devel
> Date: Sat, 24 Feb 2024 02:56:14 -0600
> Cc: acorallo@gnu.org, adam@alphapapa.net, emacs-devel@gnu.org
> From: Adam Porter <adam@alphapapa.net>
>
> >> That looks nice to me. My only suggestion would be to change the symbol
> >> `function` to `type`, i.e.
> >>
> >> (defun sum (a b)
> >> (declare (type (integer integer) integer))
> >> (+ a b))
> >>
> >> Because it would be more concise and descriptive.
> >
> > FWIW, Andrea's proposal looks more descriptive to me. "Type" is too
> > general, whereas "function" is more specific.
>
> I don't understand what you mean. ISTM that "type" is exactly what's
> being declared
Yes, but type of what? If you were to suggest function-type or
function-signature or something with "function" in its name, I'd like
it better.
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-02-24 10:03 ` Eli Zaretskii
@ 2024-02-25 7:35 ` Adam Porter
0 siblings, 0 replies; 72+ messages in thread
From: Adam Porter @ 2024-02-25 7:35 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: acorallo, emacs-devel
On 2/24/24 04:03, Eli Zaretskii wrote:
>> Date: Sat, 24 Feb 2024 02:56:14 -0600
>> Cc: acorallo@gnu.org, adam@alphapapa.net, emacs-devel@gnu.org
>> From: Adam Porter <adam@alphapapa.net>
>>
>>>> That looks nice to me. My only suggestion would be to change the symbol
>>>> `function` to `type`, i.e.
>>>>
>>>> (defun sum (a b)
>>>> (declare (type (integer integer) integer))
>>>> (+ a b))
>>>>
>>>> Because it would be more concise and descriptive.
>>>
>>> FWIW, Andrea's proposal looks more descriptive to me. "Type" is too
>>> general, whereas "function" is more specific.
>>
>> I don't understand what you mean. ISTM that "type" is exactly what's
>> being declared
>
> Yes, but type of what? If you were to suggest function-type or
> function-signature or something with "function" in its name, I'd like
> it better.
It seemed obvious to me that a `declare' form at the top of a `defun'
pertains to the function. For example `(declare (debug ...))' declares
the function's instrumentation--it's not `(declare (function-debug
...))'. So it seemed to me that `(declare (type ...))' would be
sufficient, rather than `(declare (function ...))' or `(declare
(function-type ...))'.
But I don't have a strong opinion on this, and I won't argue with you if
you disagree. My goals are simply advocating for:
1. Reducing verbosity while maintaining clarity.
2. Allowing for the future possibility of moving `declare-function'
forms into the function body as `(declare (function ...))', which seems
to me like a natural thing to do (see my other message).
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-02-23 23:35 ` Adam Porter
2024-02-24 7:10 ` Eli Zaretskii
@ 2024-02-24 9:21 ` Andrea Corallo
1 sibling, 0 replies; 72+ messages in thread
From: Andrea Corallo @ 2024-02-24 9:21 UTC (permalink / raw)
To: Adam Porter; +Cc: emacs-devel
Adam Porter <adam@alphapapa.net> writes:
> Hi Andrea,
>
>> Finally on top of 'scratch/func-type-decls' (where I there was already a
>> similar work for primitives) I pushed some commits that allows for the
>> following style:
>> (defun sum (a b)
>> (declare (function (integer integer) integer))
>> (+ a b))
>> I moved all function declaration out of 'comp-known-type-specifiers'
>> and
>> everything looks functional now.
>> Before writing a ton of changelogs I thought was good to get some
>> feedback anyway. WDYT?
>
> That looks nice to me. My only suggestion would be to change the
> symbol `function` to `type`, i.e.
>
> (defun sum (a b)
> (declare (type (integer integer) integer))
> (+ a b))
>
> Because it would be more concise and descriptive.
Hi Adam,
I understand your point, probably I had to explain this better in my
original mail.
Fact is, we already use the form (function (ATYPES) RTYPE) as type
specifier for functions. So (ftype (function (ATYPES) RTYPE)) would be
the most correct form semantically, where `ftype` (or `type` or really
what we prefer) would be the declaration which takes the type specifier
as argument.
Having (declare (function (integer integer) integer)) implies that the
type specifier is a valid declaration as well, or IOW that declare
understands as well type specifiers as a declaration, which I believe is
fine.
I personally find `function` more clear than `type`, but more
importantly I think just having `type` instead of `function` would be
harder to justify from a semantic POV.
Thanks!
Andrea
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-02-23 16:02 Declaring Lisp function types Andrea Corallo
2024-02-23 23:35 ` Adam Porter
@ 2024-02-25 17:04 ` Alan Mackenzie
2024-02-25 17:15 ` Eli Zaretskii
` (3 more replies)
2024-02-26 3:38 ` Richard Stallman
` (2 subsequent siblings)
4 siblings, 4 replies; 72+ messages in thread
From: Alan Mackenzie @ 2024-02-25 17:04 UTC (permalink / raw)
To: Andrea Corallo; +Cc: emacs-devel
Hello, Andrea.
On Fri, Feb 23, 2024 at 11:02:52 -0500, Andrea Corallo wrote:
> Hi all,
> I'm looking into moving out the function type declarations in
> 'comp-known-type-specifiers' in order to move them to where the function
> are actually defined. This to easy maintenance (ATM they get out of
> sync) and to allow the user for (indeed optionally) declaring function
> types.
> In principle I believe we are interested in expressing the the argument
> types and (maybe optionally) the return type.
What's missing is the why. Do we actually want to put function type
declarations in Lisp source at all? They will clutter up the code more
than it is cluttered up at the moment.
A ground principle of Lisp is that type checking is done at run time,
not compile time. Your proposal seems to be changing that, although I
don't know what the intention for using the type decorations is.
I worry that these declarations will become frequent, even pervasive,
and then effectively compulsory. Then we won't have Lisp any more,
we'll have something more like C.
I think somebody said somewhere that the declarations will be
"voluntary", but things that start off voluntary have a nasty habit of
first becoming pervasive, then all but universal, and then compulsory.
As I said, I don't know what these declarations are for, but I think
serious thought should be given to not implementing them.
[ .... ]
> Thanks!
> Andrea
--
Alan Mackenzie (Nuremberg, Germany).
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-02-25 17:04 ` Alan Mackenzie
@ 2024-02-25 17:15 ` Eli Zaretskii
2024-02-25 17:16 ` [External] : " Drew Adams
` (2 subsequent siblings)
3 siblings, 0 replies; 72+ messages in thread
From: Eli Zaretskii @ 2024-02-25 17:15 UTC (permalink / raw)
To: Alan Mackenzie; +Cc: acorallo, emacs-devel
> Date: Sun, 25 Feb 2024 17:04:30 +0000
> Cc: emacs-devel@gnu.org
> From: Alan Mackenzie <acm@muc.de>
>
> On Fri, Feb 23, 2024 at 11:02:52 -0500, Andrea Corallo wrote:
> > Hi all,
>
> > I'm looking into moving out the function type declarations in
> > 'comp-known-type-specifiers' in order to move them to where the function
> > are actually defined. This to easy maintenance (ATM they get out of
> > sync) and to allow the user for (indeed optionally) declaring function
> > types.
>
> > In principle I believe we are interested in expressing the the argument
> > types and (maybe optionally) the return type.
>
> What's missing is the why. Do we actually want to put function type
> declarations in Lisp source at all? They will clutter up the code more
> than it is cluttered up at the moment.
My understanding of the rationale is that then we will be able to
maintain the information about each function in one place, instead of
in two. Currently, when the signature changes, someone must remember
to go to that other place and update it.
So I think this change is generally for the better, as it will make
maintenance easier and less error-prone.
^ permalink raw reply [flat|nested] 72+ messages in thread
* RE: [External] : Re: Declaring Lisp function types
2024-02-25 17:04 ` Alan Mackenzie
2024-02-25 17:15 ` Eli Zaretskii
@ 2024-02-25 17:16 ` Drew Adams
2024-02-26 16:25 ` Andrea Corallo
2024-02-29 3:50 ` Richard Stallman
3 siblings, 0 replies; 72+ messages in thread
From: Drew Adams @ 2024-02-25 17:16 UTC (permalink / raw)
To: Alan Mackenzie, Andrea Corallo; +Cc: emacs-devel@gnu.org
> > In principle I believe we are interested in expressing the the
> argument
> > types and (maybe optionally) the return type.
>
> What's missing is the why. Do we actually want to put function type
> declarations in Lisp source at all? They will clutter up the code more
> than it is cluttered up at the moment.
>
> A ground principle of Lisp is that type checking is done at run time,
> not compile time. Your proposal seems to be changing that, although I
> don't know what the intention for using the type decorations is.
>
> I worry that these declarations will become frequent, even pervasive,
> and then effectively compulsory. Then we won't have Lisp any more,
> we'll have something more like C.
>
> I think somebody said somewhere that the declarations will be
> "voluntary", but things that start off voluntary have a nasty habit of
> first becoming pervasive, then all but universal, and then compulsory.
>
> As I said, I don't know what these declarations are for, but I think
> serious thought should be given to not implementing them.
Hi Alan,
This comes from Common Lisp (if not older relatives).
Please see this in general, and in particular about
declarations being voluntary, and their purpose(s):
https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node103.html#SECTION001300000000000000000
In particular, the intro paragraph tells us:
Declarations allow you to specify extra information
about your program to the Lisp system. With one
exception, declarations are completely optional and
correct declarations do not affect the meaning of a
correct program. The exception is that special
declarations do affect the interpretation of variable
bindings and references and so must be specified
where appropriate. All other declarations are of an
advisory nature, and may be used by the Lisp system
to aid the programmer by performing extra error
checking or producing more efficient compiled code.
Declarations are also a good way to add documentation
to a program.
Keep in mind that Common Lisp is not a particular
implementation. It's a spec/standard, which particular
implementations can support/implement in different ways.
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-02-25 17:04 ` Alan Mackenzie
2024-02-25 17:15 ` Eli Zaretskii
2024-02-25 17:16 ` [External] : " Drew Adams
@ 2024-02-26 16:25 ` Andrea Corallo
2024-02-29 3:50 ` Richard Stallman
3 siblings, 0 replies; 72+ messages in thread
From: Andrea Corallo @ 2024-02-26 16:25 UTC (permalink / raw)
To: Alan Mackenzie; +Cc: emacs-devel
Alan Mackenzie <acm@muc.de> writes:
> Hello, Andrea.
>
> On Fri, Feb 23, 2024 at 11:02:52 -0500, Andrea Corallo wrote:
>> Hi all,
>
>> I'm looking into moving out the function type declarations in
>> 'comp-known-type-specifiers' in order to move them to where the function
>> are actually defined. This to easy maintenance (ATM they get out of
>> sync) and to allow the user for (indeed optionally) declaring function
>> types.
>
>> In principle I believe we are interested in expressing the the argument
>> types and (maybe optionally) the return type.
>
> What's missing is the why. Do we actually want to put function type
> declarations in Lisp source at all? They will clutter up the code more
> than it is cluttered up at the moment.
Hi Alan,
just to confirm that I think the explainations you've got form Eli and
Drew are I think a good summary.
Thanks
Andrea
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-02-25 17:04 ` Alan Mackenzie
` (2 preceding siblings ...)
2024-02-26 16:25 ` Andrea Corallo
@ 2024-02-29 3:50 ` Richard Stallman
2024-02-29 6:10 ` Adam Porter
2024-02-29 9:02 ` Andrea Corallo
3 siblings, 2 replies; 72+ messages in thread
From: Richard Stallman @ 2024-02-29 3:50 UTC (permalink / raw)
To: Alan Mackenzie; +Cc: acorallo, emacs-devel
[[[ To any NSA and FBI agents reading my email: please consider ]]]
[[[ whether defending the US Constitution against all enemies, ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]
> I worry that these declarations will become frequent, even pervasive,
> and then effectively compulsory. Then we won't have Lisp any more,
> we'll have something more like C.
> I think somebody said somewhere that the declarations will be
> "voluntary", but things that start off voluntary have a nasty habit of
> first becoming pervasive, then all but universal, and then compulsory.
That is my concern as well. If we let native compilation
lure us down the path of changing the Emacs Lisp language
so as to make native-compiled code faster, there is almost
no limit to how much time we could put into it. There are
always things we could do to keep optimizing some cases.
This will tend to draw effort away from other sorts of improements in
GNU Emacs. We should decline to go down that path.
As long as we avoid that alteration of priorities, and use this
information about function argument types and likely value types only
as a kind of documentation for users, there is no reason not to
improve the way we store it and how users can access it.
--
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-02-29 3:50 ` Richard Stallman
@ 2024-02-29 6:10 ` Adam Porter
2024-02-29 9:02 ` Andrea Corallo
1 sibling, 0 replies; 72+ messages in thread
From: Adam Porter @ 2024-02-29 6:10 UTC (permalink / raw)
To: rms; +Cc: acm, acorallo, emacs-devel
> > I worry that these declarations will become frequent, even pervasive,
> > and then effectively compulsory. Then we won't have Lisp any more,
> > we'll have something more like C.
>
> > I think somebody said somewhere that the declarations will be
> > "voluntary", but things that start off voluntary have a nasty habit of
> > first becoming pervasive, then all but universal, and then compulsory.
I don't think these are fair arguments. They're beyond speculative.
We're here because we want to write this kind of software in Emacs Lisp,
not in C. No one wants mandatory type declarations. And the Common
Lisp model, which Andrea seems to be inspired by and generally
following, does not make such declarations mandatory either.
The same kind of argument could be made about, e.g. Edebug
instrumentation declarations: "If we allow macros to have these, they
could start off voluntary, but then become pervasive, then compulsory.
So we'd better not have them at all, then." Obviously, they have not
turned out that way; they are added where they are useful and needed,
and they are of great benefit. No one has any intention of making them
mandatory; if they are not provided, then the macro is simply not
instrumented as usefully. There is no slippery slope here.
In the same way, if a function has type declarations, and--someday--the
compiler could use them to produce more efficient code, that would be
great. Otherwise, the function will be compiled as it is now.
This is, as far as I can tell, what Andrea has always intended to do,
time permitting, and he has made this clear from all of his writing on
the topic for the past few years. To suggest that he intends otherwise
would seem quite unfair to him.
> That is my concern as well. If we let native compilation
> lure us down the path of changing the Emacs Lisp language
> so as to make native-compiled code faster, there is almost
> no limit to how much time we could put into it. There are
> always things we could do to keep optimizing some cases.
>
> This will tend to draw effort away from other sorts of improements in
> GNU Emacs. We should decline to go down that path.
I don't think that's a reasonable way to view this matter. Emacs is
developed voluntarily. It's a rare occasion that someone comes along
who has the expertise, interest, and time to contribute something as
challenging as compiler optimizations, such as Andrea has graciously
given to us (really, a whole new compiler implementation). When it
happens, who are we to say that they should apply their effort
elsewhere. We should gratefully accept their contributions and
encourage more of them as they are able to provide.
Emacs needs these kinds of significant developments--ones which happen
rarely but provide benefits for many years--to sustain it in the face of
competition that's developed by teams of full-time engineers working at
large companies. Woe unto us if we turn them away by asking them to
volunteer their time on something not according to their interest.
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-02-29 3:50 ` Richard Stallman
2024-02-29 6:10 ` Adam Porter
@ 2024-02-29 9:02 ` Andrea Corallo
1 sibling, 0 replies; 72+ messages in thread
From: Andrea Corallo @ 2024-02-29 9:02 UTC (permalink / raw)
To: Richard Stallman; +Cc: Alan Mackenzie, emacs-devel
Richard Stallman <rms@gnu.org> writes:
> [[[ To any NSA and FBI agents reading my email: please consider ]]]
> [[[ whether defending the US Constitution against all enemies, ]]]
> [[[ foreign or domestic, requires you to follow Snowden's example. ]]]
>
> > I worry that these declarations will become frequent, even pervasive,
> > and then effectively compulsory. Then we won't have Lisp any more,
> > we'll have something more like C.
>
> > I think somebody said somewhere that the declarations will be
> > "voluntary", but things that start off voluntary have a nasty habit of
> > first becoming pervasive, then all but universal, and then compulsory.
>
> That is my concern as well. If we let native compilation
> lure us down the path of changing the Emacs Lisp language
> so as to make native-compiled code faster, there is almost
> no limit to how much time we could put into it. There are
> always things we could do to keep optimizing some cases.
>
> This will tend to draw effort away from other sorts of improements in
> GNU Emacs. We should decline to go down that path.
Hi Richard,
I don't think this is a realistic danger. Over the past years the
contribution to the native compiler by developers other than me proved
to be very sporadic, and even me I progress only when time allows.
OTOH I believe performance is a sensitive subject for many users of the
new generations who often make use of complex and heavy packages. I
believe a faster Emacs would be a better and more future proof platform.
> As long as we avoid that alteration of priorities, and use this
> information about function argument types and likely value types only
> as a kind of documentation for users, there is no reason not to
> improve the way we store it and how users can access it.
I'm pretty sure this will not alter any priority and yes, I think is a
nice addition to the self-documenting capabilities of Emacs.
Thanks
Andrea
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-02-23 16:02 Declaring Lisp function types Andrea Corallo
2024-02-23 23:35 ` Adam Porter
2024-02-25 17:04 ` Alan Mackenzie
@ 2024-02-26 3:38 ` Richard Stallman
2024-02-26 16:38 ` [External] : " Drew Adams
2024-02-26 16:52 ` Andrea Corallo
2024-03-02 21:19 ` Stefan Monnier via Emacs development discussions.
2024-03-15 16:49 ` Andrea Corallo
4 siblings, 2 replies; 72+ messages in thread
From: Richard Stallman @ 2024-02-26 3:38 UTC (permalink / raw)
To: Andrea Corallo; +Cc: emacs-devel
[[[ To any NSA and FBI agents reading my email: please consider ]]]
[[[ whether defending the US Constitution against all enemies, ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]
What is the goal of supporting function type declarations in Emacs
Lisp?
--
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)
^ permalink raw reply [flat|nested] 72+ messages in thread
* RE: [External] : Re: Declaring Lisp function types
2024-02-26 3:38 ` Richard Stallman
@ 2024-02-26 16:38 ` Drew Adams
2024-02-26 16:54 ` Eli Zaretskii
2024-02-26 16:52 ` Andrea Corallo
1 sibling, 1 reply; 72+ messages in thread
From: Drew Adams @ 2024-02-26 16:38 UTC (permalink / raw)
To: rms@gnu.org, Andrea Corallo; +Cc: emacs-devel@gnu.org
> What is the goal of supporting function type
> declarations in Emacs Lisp?
Do you mean the expected types of args?
If so, see the CLTL2 doc I pointed to.
In particular, declaring the type of
an arg can help a compiler produce
more efficient code.
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: [External] : Re: Declaring Lisp function types
2024-02-26 16:38 ` [External] : " Drew Adams
@ 2024-02-26 16:54 ` Eli Zaretskii
2024-02-26 17:44 ` Andrea Corallo
0 siblings, 1 reply; 72+ messages in thread
From: Eli Zaretskii @ 2024-02-26 16:54 UTC (permalink / raw)
To: Drew Adams; +Cc: rms, acorallo, emacs-devel
> From: Drew Adams <drew.adams@oracle.com>
> CC: "emacs-devel@gnu.org" <emacs-devel@gnu.org>
> Date: Mon, 26 Feb 2024 16:38:34 +0000
>
> > What is the goal of supporting function type
> > declarations in Emacs Lisp?
>
> Do you mean the expected types of args?
> If so, see the CLTL2 doc I pointed to.
>
> In particular, declaring the type of
> an arg can help a compiler produce
> more efficient code.
I think in our case it's somewhat different: the native-compiler needs
this information to DTRT with code generation. But I'll let Andrea
explain this.
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: [External] : Re: Declaring Lisp function types
2024-02-26 16:54 ` Eli Zaretskii
@ 2024-02-26 17:44 ` Andrea Corallo
0 siblings, 0 replies; 72+ messages in thread
From: Andrea Corallo @ 2024-02-26 17:44 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: Drew Adams, rms, emacs-devel
Eli Zaretskii <eliz@gnu.org> writes:
>> From: Drew Adams <drew.adams@oracle.com>
>> CC: "emacs-devel@gnu.org" <emacs-devel@gnu.org>
>> Date: Mon, 26 Feb 2024 16:38:34 +0000
>>
>> > What is the goal of supporting function type
>> > declarations in Emacs Lisp?
>>
>> Do you mean the expected types of args?
>> If so, see the CLTL2 doc I pointed to.
>>
>> In particular, declaring the type of
>> an arg can help a compiler produce
>> more efficient code.
>
> I think in our case it's somewhat different: the native-compiler needs
> this information to DTRT with code generation. But I'll let Andrea
> explain this.
Hi Eli,
sorry I was a bit late today on all this thread, I think I aswered this
in my reply to Richard.
Thanks
Andrea
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-02-26 3:38 ` Richard Stallman
2024-02-26 16:38 ` [External] : " Drew Adams
@ 2024-02-26 16:52 ` Andrea Corallo
2024-02-26 18:10 ` Tomas Hlavaty
1 sibling, 1 reply; 72+ messages in thread
From: Andrea Corallo @ 2024-02-26 16:52 UTC (permalink / raw)
To: Richard Stallman; +Cc: emacs-devel
Richard Stallman <rms@gnu.org> writes:
> [[[ To any NSA and FBI agents reading my email: please consider ]]]
> [[[ whether defending the US Constitution against all enemies, ]]]
> [[[ foreign or domestic, requires you to follow Snowden's example. ]]]
>
> What is the goal of supporting function type declarations in Emacs
> Lisp?
Hi Richard,
ATM we have several function type declarations kept in a different file
and naturally they get out of sync over time. So yes one reason is to
move the declarations where functions are actually defined.
These declarations are in use by the native compiler in order to help
generating better code, computing automatically the function signature
of non type declared functions (signatures which we present in C-h f)
and (hope in the close future) aid the programmer by performing extra
error checking at compile time.
Thanks
Andrea
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-02-26 16:52 ` Andrea Corallo
@ 2024-02-26 18:10 ` Tomas Hlavaty
0 siblings, 0 replies; 72+ messages in thread
From: Tomas Hlavaty @ 2024-02-26 18:10 UTC (permalink / raw)
To: Andrea Corallo, Richard Stallman; +Cc: emacs-devel
On Mon 26 Feb 2024 at 11:52, Andrea Corallo <acorallo@gnu.org> wrote:
> ATM we have several function type declarations kept in a different file
> and naturally they get out of sync over time.
What happens when they get out of sync?
> So yes one reason is to move the declarations where functions are
> actually defined.
What happens when they are wrong?
> These declarations are in use by the native compiler in order to help
> generating better code, computing automatically the function signature
> of non type declared functions (signatures which we present in C-h f)
Do you have a specific example?
(describe-function 'car)
and
(describe-function 'sort)
do not show any signature in emacs 28.2
> and (hope in the close future) aid the programmer by performing extra
> error checking at compile time.
How is this different from CL:CHECK-TYPE?
Would CL:CHECK-TYPE be sufficient?
(eww "clhs check-type")
https://www.lispworks.com/documentation/HyperSpec/Body/m_check_.htm
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-02-23 16:02 Declaring Lisp function types Andrea Corallo
` (2 preceding siblings ...)
2024-02-26 3:38 ` Richard Stallman
@ 2024-03-02 21:19 ` Stefan Monnier via Emacs development discussions.
2024-03-03 9:52 ` Andrea Corallo
2024-03-15 16:49 ` Andrea Corallo
4 siblings, 1 reply; 72+ messages in thread
From: Stefan Monnier via Emacs development discussions. @ 2024-03-02 21:19 UTC (permalink / raw)
To: emacs-devel
> (declaim (ftype (function (integer integer) integer) sum))
> ;; ^^inputs ^^output [optional]
> (defun sum (a b)
> (declare (integer a b))
> (+ a b))
Non-starter for me: the separation into two steps makes it unclear what
the declaration applies to (e.g. when re-running the above code, does
the `declaim` apply to the old definition (the one active when the
`declaim` is executed)® the the one that's about to be installed)?
> ;;2
> (defun sum (a b)
> (declare (integer a b))
> (+ a b))
None starter because of how we defined `declare`, where we'd have to
define every existing type as a valid declaration idenitifer.
> ;;3 through 'defstar' (a CL library not in the standard)
> (defun* sum ((a integer) (b integer))
> (+ a b))
> ;;4 again through 'defstar'
> (defun* (sum -> integer) ((a integer) (b integer))
> (+ a b))
Acceptable, with some tweaks to better fit my favorite bikeshed color.
> (defun sum (a b)
> (declare (ftype (function (integer integer) integer)))
> (+ a b))
The `f` of `ftype` is redundant with the following `function`, so we
could shorten that to:
(defun sum (a b)
(declare (ftype (integer integer) integer))
(+ a b))
> (defun sum (a b)
> (declare (function (integer integer) integer))
> (+ a b))
It's cute, I guess. Whether to prefer `function`, `ftype`, or Adam's `type`,
is largely a "bikeshed color" choice. I do prefer the latter two
because we already know that this is a function, whereas we don't know
that this is a *type* (and they're shorter, to boot).
Later you said:
> Fact is, we already use the form (function (ATYPES) RTYPE) as type
> specifier for functions. So (ftype (function (ATYPES) RTYPE)) would be
> the most correct form semantically, where `ftype` (or `type` or really
> what we prefer) would be the declaration which takes the type specifier
> as argument.
Of course (declare (ftype (integer integer) integer))
would still end up generating something like
(foo-declare-type 'sum '(function (integer integer) integer))
so I see no semantic issue with using `ftype` or `type` here, unless
there are functions whose type could take another form than (function
<args> <rettype>)? Are you thinking of types like
(or (function (int) int) (function (float) float))?
More important I think is to document what such annotations mean and
what they should look like (currently, this is not super important,
because the annotations live together with the code that uses them, but
if we move them outside of `comp.el`, the "contract" needs to be made
more explicit).
- How they interact with `&optional` and `&rest` (or even `&key` for
`c-defun`).
- What will/could happen if one of the arguments does not have the
specified type?
- What will/could happen if the result does not have the
specified type?
- Do we have types to say "arg unused" or "no return value"?
- Can we have higher-order function types, like
(function (proc (function (proc string) void)) void)
and if so, again, what does it mean in terms of what can happen if the
runtime values don't actually match the announced types (e.g. what
happens (and when) if we pass a function that has the "wrong type")?
Stefan
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-02 21:19 ` Stefan Monnier via Emacs development discussions.
@ 2024-03-03 9:52 ` Andrea Corallo
2024-03-03 14:52 ` Stefan Monnier
0 siblings, 1 reply; 72+ messages in thread
From: Andrea Corallo @ 2024-03-03 9:52 UTC (permalink / raw)
To: Stefan Monnier via Emacs development discussions.; +Cc: Stefan Monnier
Stefan Monnier via "Emacs development discussions."
<emacs-devel@gnu.org> writes:
>> (declaim (ftype (function (integer integer) integer) sum))
>> ;; ^^inputs ^^output [optional]
>> (defun sum (a b)
>> (declare (integer a b))
>> (+ a b))
>
> Non-starter for me: the separation into two steps makes it unclear what
> the declaration applies to (e.g. when re-running the above code, does
> the `declaim` apply to the old definition (the one active when the
> `declaim` is executed)® the the one that's about to be installed)?
>
>> ;;2
>> (defun sum (a b)
>> (declare (integer a b))
>> (+ a b))
>
> None starter because of how we defined `declare`, where we'd have to
> define every existing type as a valid declaration idenitifer.
>
>> ;;3 through 'defstar' (a CL library not in the standard)
>> (defun* sum ((a integer) (b integer))
>> (+ a b))
>> ;;4 again through 'defstar'
>> (defun* (sum -> integer) ((a integer) (b integer))
>> (+ a b))
>
> Acceptable, with some tweaks to better fit my favorite bikeshed color.
>
>> (defun sum (a b)
>> (declare (ftype (function (integer integer) integer)))
>> (+ a b))
>
> The `f` of `ftype` is redundant with the following `function`, so we
> could shorten that to:
>
> (defun sum (a b)
> (declare (ftype (integer integer) integer))
> (+ a b))
>
>> (defun sum (a b)
>> (declare (function (integer integer) integer))
>> (+ a b))
>
> It's cute, I guess. Whether to prefer `function`, `ftype`, or Adam's `type`,
> is largely a "bikeshed color" choice. I do prefer the latter two
> because we already know that this is a function, whereas we don't know
> that this is a *type* (and they're shorter, to boot).
>
> Later you said:
>> Fact is, we already use the form (function (ATYPES) RTYPE) as type
>> specifier for functions. So (ftype (function (ATYPES) RTYPE)) would be
>> the most correct form semantically, where `ftype` (or `type` or really
>> what we prefer) would be the declaration which takes the type specifier
>> as argument.
>
> Of course (declare (ftype (integer integer) integer))
> would still end up generating something like
>
> (foo-declare-type 'sum '(function (integer integer) integer))
My fear it's this is a bit more convoluted and this extra step makes it
less understandable/justifiable. I like the symmetry of having
'function' both in the input (the declaration) and the output (the final
type itself). Maybe my background as physicist makes symmetry too
central for me? :)
> so I see no semantic issue with using `ftype` or `type` here, unless
> there are functions whose type could take another form than (function
> <args> <rettype>)? Are you thinking of types like
> (or (function (int) int) (function (float) float))?
That's a good example why it would be good to be able to accept the type
specifier as a declaration with no tricks. On the specific case I'm not
sure we want to support this in the inner machinery (at least for now).
> More important I think is to document what such annotations mean and
> what they should look like (currently, this is not super important,
> because the annotations live together with the code that uses them, but
> if we move them outside of `comp.el`, the "contract" needs to be made
> more explicit).
>
> - How they interact with `&optional` and `&rest` (or even `&key` for
> `c-defun`).
ATM we already support in type specifiers `&optional` and `&rest`:
(subr-type (native-compile '(lambda (x &optional y &rest z)))) =>
(function (t &optional t &rest t) null)
Not sure we want to handle &key as well as it looks to me not very
native to the elisp machinery. OTOH cl-defun just expands to the native
elisp call convention.
> - What will/could happen if one of the arguments does not have the
> specified type?
I think if ones does a declaration has to declare the type of all
arguments (rest should be optional).
> - What will/could happen if the result does not have the
> specified type?
I think we want to complete it with the inferred return type if we have
it or t otherwise.
> - Do we have types to say "arg unused" or "no return value"?
We don't have "arg unused" because the function type (or signature) is
like the contract with the outside word, it should not matter how (and
if) and arg is used inside.
OTOH we have "no return value" and it's nil
(subr-type (native-compile '(lambda (x) (error x)))) =>
(function (t) nil)
> - Can we have higher-order function types, like
>
> (function (proc (function (proc string) void)) void)
>
> and if so, again, what does it mean in terms of what can happen if the
> runtime values don't actually match the announced types (e.g. what
> happens (and when) if we pass a function that has the "wrong type")?
I don't kwnow if we want to allow this to be future proof, ATM certanly
the compiler does not use it and I don't think it could help code
generation. OTOH might be nice for documentation?
As a note: AFAIR SBCL doesn't go beyond something like:
(function (integer function) function)
That if arguments/ret values are functions it forgets the inner details
of their type specifier.
Anyway I certanly agree we should better document this once it's shaped,
and I'll try my best.
But generally speaking I've the feeling there might be other cases we
don't see ATM where accepting directly the type specifier as valid
declaration graciously/naturally solves potential issues we could hit
otherwise.
Thanks
Andrea
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-03 9:52 ` Andrea Corallo
@ 2024-03-03 14:52 ` Stefan Monnier
2024-03-03 17:31 ` Andrea Corallo
0 siblings, 1 reply; 72+ messages in thread
From: Stefan Monnier @ 2024-03-03 14:52 UTC (permalink / raw)
To: Andrea Corallo; +Cc: Stefan Monnier via Emacs development discussions.
>> so I see no semantic issue with using `ftype` or `type` here, unless
>> there are functions whose type could take another form than (function
>> <args> <rettype>)? Are you thinking of types like
>> (or (function (int) int) (function (float) float))?
>
> That's a good example why it would be good to be able to accept the type
> specifier as a declaration with no tricks.
Then I'd go with
(declare (type (function ..)))
This may be a bit more verbose, but it's simple and clear. And to the
extent that people are worried that it could become pervasive and even
mandatory, I think verbose is good.
> On the specific case I'm not sure we want to support this in the inner
> machinery (at least for now).
+1
>> More important I think is to document what such annotations mean and
>> what they should look like (currently, this is not super important,
>> because the annotations live together with the code that uses them, but
>> if we move them outside of `comp.el`, the "contract" needs to be made
>> more explicit).
>> - How they interact with `&optional` and `&rest` (or even `&key` for
>> `c-defun`).
> ATM we already support in type specifiers `&optional` and `&rest`:
I know, but it needs to be documented.
> Not sure we want to handle &key as well as it looks to me not very
> native to the elisp machinery. OTOH cl-defun just expands to the
> native elisp call convention.
FWIW, I agree.
>> - What will/could happen if one of the arguments does not have the
>> specified type?
> I think if ones does a declaration has to declare the type of all
> arguments (rest should be optional).
I mean, what happens (both at compile-time and at run-time) when
`my-fun` says (function (number) number) but we call it with a string?
>> - What will/could happen if the result does not have the
>> specified type?
> I think we want to complete it with the inferred return type if we have
> it or t otherwise.
Same here: I meant what happens when `my-fun` actually returns nil
even though its own type declaration claims it returns a number?
Maybe we should also give a hint about the potential benefits (how it
influences the generated code), so coders can have a better idea about
when a type annotation is worthwhile and when it's not.
Stefan
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-03 14:52 ` Stefan Monnier
@ 2024-03-03 17:31 ` Andrea Corallo
2024-03-03 18:13 ` Stefan Monnier
0 siblings, 1 reply; 72+ messages in thread
From: Andrea Corallo @ 2024-03-03 17:31 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Stefan Monnier via Emacs development discussions.
Stefan Monnier <monnier@iro.umontreal.ca> writes:
>>> so I see no semantic issue with using `ftype` or `type` here, unless
>>> there are functions whose type could take another form than (function
>>> <args> <rettype>)? Are you thinking of types like
>>> (or (function (int) int) (function (float) float))?
>>
>> That's a good example why it would be good to be able to accept the type
>> specifier as a declaration with no tricks.
>
> Then I'd go with
>
> (declare (type (function ..)))
>
> This may be a bit more verbose, but it's simple and clear. And to the
> extent that people are worried that it could become pervasive and even
> mandatory, I think verbose is good.
>
>> On the specific case I'm not sure we want to support this in the inner
>> machinery (at least for now).
>
> +1
>
>>> More important I think is to document what such annotations mean and
>>> what they should look like (currently, this is not super important,
>>> because the annotations live together with the code that uses them, but
>>> if we move them outside of `comp.el`, the "contract" needs to be made
>>> more explicit).
>>> - How they interact with `&optional` and `&rest` (or even `&key` for
>>> `c-defun`).
>> ATM we already support in type specifiers `&optional` and `&rest`:
>
> I know, but it needs to be documented.
Agree
>> Not sure we want to handle &key as well as it looks to me not very
>> native to the elisp machinery. OTOH cl-defun just expands to the
>> native elisp call convention.
>
> FWIW, I agree.
>
>>> - What will/could happen if one of the arguments does not have the
>>> specified type?
>> I think if ones does a declaration has to declare the type of all
>> arguments (rest should be optional).
>
> I mean, what happens (both at compile-time and at run-time) when
> `my-fun` says (function (number) number) but we call it with a string?
At the very moment nothing as we use the declaration only for the return
type, in the future I guess we want to have settings of the compiler to:
1- emit runtime type checks for the arguments (maybe introducing
'native-comp-safety'?)
2- Use the arg declaration for code generation optimizations (I guess
connected to 'native-comp-speed')
I've never wanted to enable 1 and 2 as didn't sound correct having an
ad-hoc declaration hidden somewhere in the compiler, but should be
relatively easy as all the infrastructure is in place.
>>> - What will/could happen if the result does not have the
>>> specified type?
>> I think we want to complete it with the inferred return type if we have
>> it or t otherwise.
>
> Same here: I meant what happens when `my-fun` actually returns nil
> even though its own type declaration claims it returns a number?
We might generate wrong code. I *think* this is the same for other kind
of function declarations we already have which are in use by the
byte-compiler.
> Maybe we should also give a hint about the potential benefits (how it
> influences the generated code), so coders can have a better idea about
> when a type annotation is worthwhile and when it's not.
Yep, I don't know where these info should be placed in the manual.
Maybe there should be an area dedicated to the native compiler?
Andrea
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-03 17:31 ` Andrea Corallo
@ 2024-03-03 18:13 ` Stefan Monnier
0 siblings, 0 replies; 72+ messages in thread
From: Stefan Monnier @ 2024-03-03 18:13 UTC (permalink / raw)
To: Andrea Corallo; +Cc: Stefan Monnier via Emacs development discussions.
>>>> - What will/could happen if the result does not have the
>>>> specified type?
>>> I think we want to complete it with the inferred return type if we have
>>> it or t otherwise.
>> Same here: I meant what happens when `my-fun` actually returns nil
>> even though its own type declaration claims it returns a number?
> We might generate wrong code.
That's the point of view of the compiler writer. We need to state it
from the point of view of the user, i.e. describe the potential behavior
of that wrong code we might generate.
Also the description should be clear enough that a user can guess what
happens if the type annotation was correct but the function gets
redefined (e.g. via an advice) which does not obey the same type.
>> Maybe we should also give a hint about the potential benefits (how it
>> influences the generated code), so coders can have a better idea about
>> when a type annotation is worthwhile and when it's not.
> Yep, I don't know where these info should be placed in the manual.
> Maybe there should be an area dedicated to the native compiler?
I'd put it somewhere inside the "@chapter Compilation of Lisp to Native
Code" in `compile.texi`.
Stefan
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-02-23 16:02 Declaring Lisp function types Andrea Corallo
` (3 preceding siblings ...)
2024-03-02 21:19 ` Stefan Monnier via Emacs development discussions.
@ 2024-03-15 16:49 ` Andrea Corallo
2024-03-15 18:19 ` Tomas Hlavaty
` (2 more replies)
4 siblings, 3 replies; 72+ messages in thread
From: Andrea Corallo @ 2024-03-15 16:49 UTC (permalink / raw)
To: emacs-devel; +Cc: Eli Zaretskii, Stefan Kangas
I'd like to progress on this but in order to do that we should pick a
syntax.
Of the three most discussed syntaxes in this thread my order of
preference is (by examples):
1:
(defun sum (a b)
(declare (function (integer integer) integer))
(+ a b))
2:
(defun sum (a b)
(declare (type (function (integer integer) integer)))
(+ a b))
3:
(defun sum (a b)
(declare (type (integer integer) integer))
(+ a b))
For the reasons I've already expressed: 1 I like it, 2 I'm okay with it,
3 I very much dislike it.
Maintainers WDYT?
Thanks
Andrea
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-15 16:49 ` Andrea Corallo
@ 2024-03-15 18:19 ` Tomas Hlavaty
2024-03-15 18:38 ` Eli Zaretskii
2024-03-16 0:01 ` Adam Porter
2024-03-26 10:13 ` Andrea Corallo
2 siblings, 1 reply; 72+ messages in thread
From: Tomas Hlavaty @ 2024-03-15 18:19 UTC (permalink / raw)
To: Andrea Corallo, emacs-devel; +Cc: Eli Zaretskii, Stefan Kangas
On Fri 15 Mar 2024 at 12:49, Andrea Corallo <acorallo@gnu.org> wrote:
> Of the three most discussed syntaxes in this thread my order of
> preference is (by examples):
all cases are grep-unfriendly
would it be possible to choose a grep-friendly symbol name?
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-15 18:19 ` Tomas Hlavaty
@ 2024-03-15 18:38 ` Eli Zaretskii
2024-03-16 13:39 ` Tomas Hlavaty
0 siblings, 1 reply; 72+ messages in thread
From: Eli Zaretskii @ 2024-03-15 18:38 UTC (permalink / raw)
To: Tomas Hlavaty; +Cc: acorallo, emacs-devel, stefankangas
> From: Tomas Hlavaty <tom@logand.com>
> Cc: Eli Zaretskii <eliz@gnu.org>,
> Stefan Kangas <stefankangas@gmail.com>
> Date: Fri, 15 Mar 2024 19:19:02 +0100
>
> On Fri 15 Mar 2024 at 12:49, Andrea Corallo <acorallo@gnu.org> wrote:
> > Of the three most discussed syntaxes in this thread my order of
> > preference is (by examples):
>
> all cases are grep-unfriendly
What do you mean by that? Please tell more: what would you like to
grep for and why?
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-15 18:38 ` Eli Zaretskii
@ 2024-03-16 13:39 ` Tomas Hlavaty
2024-03-16 14:06 ` Eli Zaretskii
0 siblings, 1 reply; 72+ messages in thread
From: Tomas Hlavaty @ 2024-03-16 13:39 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: acorallo, emacs-devel, stefankangas
On Fri 15 Mar 2024 at 20:38, Eli Zaretskii <eliz@gnu.org> wrote:
>> all cases are grep-unfriendly
>
> What do you mean by that?
> Please tell more: what would you like to grep for and why?
Because good names help working with code bases.
(Almost like being given a direct link (like URL) instead of
instructions to go that page, click foo then click bar then search for
baz...)
In the context of "Declaring Lisp function types", grep gives too many
false positives when searching for the symbol 'function' or 'type'.
Some people suggested more complex regexp to match the declare sexp but
that breaks down pretty quickly. A better, more unique symbol name
instead of 'function' or 'type' would be much easier to find.
Looking at
(info "(elisp)Declare Form")
there are examples of good and bad names for declare spec properties.
Good; try searching for these:
(rg "~/mr/emacs" "advertised-calling-convention")
(rg "~/mr/emacs" "side-effect-free")
(rg "~/mr/emacs" "no-font-lock-keyword")
Bad; try searching for these:
(rg "~/mr/emacs" "pure")
(rg "~/mr/emacs" "speed")
Interestingly, the info page above says that the speed property
"specifies the value of native-comp-speed in effect for native
compilation of this function". If the property was called
native-comp-speed, it
- would be more correct,
- it would be easier to search for,
- I could even M-. on the symbol and jump automatically to the
definition and see the documentation with minimal effort and
distraction,
- I would even see helpful text as an eldoc message and see possible
values just by placing cursor on the symbol name.
etc
Try this in elisp-mode:
(defun foo (a b)
(declare (integer a b)
(function a b)
(type a b)
(speed -1)
(native-comp-speed -1)
(advertised-calling-convention)
(side-effect-free)
(no-font-lock-keyword)
)
(+ a b 42))
Place your cursor on integer, function, type, speed, native-comp-speed,
advertised-calling-convention, side-effect-free, no-font-lock-keyword
and watch the difference in eldoc message, try M-. or rgrep emacs
codebase etc.
The symbol "function" already has specific meaning. Using it as a
declare spec property name is just bad. For example, eldoc or M-. shows
something unrelated to "Declaring Lisp function types".
The other symbols do not show or lead to anything, those are dead-ends
magically doing something to the codebase without me being able to use
usual tools to understand and navigate them. This gap could be bridged
by defining dummy function/macro that would show the right arguments and
documentation and also display useful eldoc message. For example like
this:
(defun side-effect-free (val)
"If VAL is non-‘nil’, this function is free of side effects, so
the byte compiler can ignore calls whose value is ignored.
This is the same as the ‘side-effect-free’ property of the
function’s symbol, *note Standard Properties::."
(error "side-effect-free is not meant to be called"))
But maybe it would be possible to structure the code in such a way that
this dummy would not be needed, like the case of the symbol
"native-comp-speed" (if it was called native-comp-speed instead of
speed).
Searching for no-font-lock-keyword does not show any declare definition.
Is it not used for anything?
Elisp has great tools for navigating and understanding code, why work
against them? Lisp symbols are a good concept supported by various
tools; use them, give them good names and all those tools will work as
usual and be very helpful in many contexts.
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-16 13:39 ` Tomas Hlavaty
@ 2024-03-16 14:06 ` Eli Zaretskii
2024-03-16 14:56 ` Tomas Hlavaty
0 siblings, 1 reply; 72+ messages in thread
From: Eli Zaretskii @ 2024-03-16 14:06 UTC (permalink / raw)
To: Tomas Hlavaty; +Cc: acorallo, emacs-devel, stefankangas
> From: Tomas Hlavaty <tom@logand.com>
> Cc: acorallo@gnu.org, emacs-devel@gnu.org, stefankangas@gmail.com
> Date: Sat, 16 Mar 2024 14:39:24 +0100
>
> On Fri 15 Mar 2024 at 20:38, Eli Zaretskii <eliz@gnu.org> wrote:
> >> all cases are grep-unfriendly
> >
> > What do you mean by that?
> > Please tell more: what would you like to grep for and why?
>
> Because good names help working with code bases.
Yes, but who would search for names that are symbols of a programming
language? If you search for "ptrdiff_t" or even "__attribute__", you
get gobs of hits. Same if you search for "defun" or "defmac".
This is simply not a good idea, and the fact that we choose this or
that name for a type declaration will never help you, as long as many
instances use that declaration.
> In the context of "Declaring Lisp function types", grep gives too many
> false positives when searching for the symbol 'function' or 'type'.
It will give too many hits no matter how we call it.
> Looking at
>
> (info "(elisp)Declare Form")
>
> there are examples of good and bad names for declare spec properties.
>
> Good; try searching for these:
>
> (rg "~/mr/emacs" "advertised-calling-convention")
> (rg "~/mr/emacs" "side-effect-free")
> (rg "~/mr/emacs" "no-font-lock-keyword")
That's just sheer luck: not a lot of functions have these properties.
By contrast, _every_ function will have some type and some signature,
so you will have a gazillion of hits if you search for those, no
matter what its name.
> The symbol "function" already has specific meaning. Using it as a
> declare spec property name is just bad. For example, eldoc or M-. shows
> something unrelated to "Declaring Lisp function types".
Some of these are irrelevant to the issue at hand, the others will
have to be adapted to the change, if we care enough.
> The other symbols do not show or lead to anything, those are dead-ends
> magically doing something to the codebase without me being able to use
> usual tools to understand and navigate them. This gap could be bridged
> by defining dummy function/macro that would show the right arguments and
> documentation and also display useful eldoc message. For example like
> this:
>
> (defun side-effect-free (val)
> "If VAL is non-‘nil’, this function is free of side effects, so
> the byte compiler can ignore calls whose value is ignored.
> This is the same as the ‘side-effect-free’ property of the
> function’s symbol, *note Standard Properties::."
> (error "side-effect-free is not meant to be called"))
>
> But maybe it would be possible to structure the code in such a way that
> this dummy would not be needed, like the case of the symbol
> "native-comp-speed" (if it was called native-comp-speed instead of
> speed).
>
> Searching for no-font-lock-keyword does not show any declare definition.
> Is it not used for anything?
Sorry, you lost me here. How is this related to the issue discussed
in this thread?
> Elisp has great tools for navigating and understanding code, why work
> against them?
We don't.
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-16 14:06 ` Eli Zaretskii
@ 2024-03-16 14:56 ` Tomas Hlavaty
2024-03-16 15:43 ` Emanuel Berg
2024-03-16 15:44 ` Eli Zaretskii
0 siblings, 2 replies; 72+ messages in thread
From: Tomas Hlavaty @ 2024-03-16 14:56 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: acorallo, emacs-devel, stefankangas
On Sat 16 Mar 2024 at 16:06, Eli Zaretskii <eliz@gnu.org> wrote:
> Yes, but who would search for names that are symbols
> of a programming language?
I do search for lisp symbols all the time.
Do you not search for lisp symbols?
> If you search for "ptrdiff_t" or even "__attribute__", you get gobs of
> hits.
And?
Those are also reasonably good names.
Now imagine if "ptrdiff_t" was called "function" instead.
> Same if you search for "defun" or "defmac".
defun and defmacro are great symbol names.
Specific, unique and as a bonus short.
> This is simply not a good idea, and the fact that we choose this or
> that name for a type declaration will never help you, as long as many
> instances use that declaration.
The focus is "Declaring Lisp function types". If it had a good symbol
name, I could find relevant places without false positives.
>> In the context of "Declaring Lisp function types", grep gives too many
>> false positives when searching for the symbol 'function' or 'type'.
>
> It will give too many hits no matter how we call it.
The better name, the less false positives.
> That's just sheer luck: not a lot of functions have these properties.
The point is reducing false positives.
> By contrast, _every_ function will have some type and some signature,
> so you will have a gazillion of hits if you search for those, no
> matter what its name.
Every?
What kind of lisp will elisp be?
>> The symbol "function" already has specific meaning. Using it as a
>> declare spec property name is just bad. For example, eldoc or M-. shows
>> something unrelated to "Declaring Lisp function types".
>
> Some of these are irrelevant to the issue at hand, the others will
> have to be adapted to the change, if we care enough.
Why would anything have to be adapted?
Why not simply use a better symbol name?
> Sorry, you lost me here. How is this related to the issue discussed
> in this thread?
It shows how good symbol names help in various ways.
It also shows how bad symbol names do not help.
It shows that using the symbol name 'function' for "Declaring Lisp
function types" is just bad.
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-16 14:56 ` Tomas Hlavaty
@ 2024-03-16 15:43 ` Emanuel Berg
2024-03-16 15:44 ` Eli Zaretskii
1 sibling, 0 replies; 72+ messages in thread
From: Emanuel Berg @ 2024-03-16 15:43 UTC (permalink / raw)
To: emacs-devel
Tomas Hlavaty wrote:
> Why not simply use a better symbol name?
What name would you suggest?
--
underground experts united
https://dataswamp.org/~incal
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-16 14:56 ` Tomas Hlavaty
2024-03-16 15:43 ` Emanuel Berg
@ 2024-03-16 15:44 ` Eli Zaretskii
2024-03-16 15:54 ` Emanuel Berg
2024-03-18 8:55 ` Lele Gaifax
1 sibling, 2 replies; 72+ messages in thread
From: Eli Zaretskii @ 2024-03-16 15:44 UTC (permalink / raw)
To: Tomas Hlavaty; +Cc: acorallo, emacs-devel, stefankangas
> From: Tomas Hlavaty <tom@logand.com>
> Cc: acorallo@gnu.org, emacs-devel@gnu.org, stefankangas@gmail.com
> Date: Sat, 16 Mar 2024 15:56:30 +0100
>
> On Sat 16 Mar 2024 at 16:06, Eli Zaretskii <eliz@gnu.org> wrote:
> > Yes, but who would search for names that are symbols
> > of a programming language?
>
> I do search for lisp symbols all the time.
> Do you not search for lisp symbols?
>
> > If you search for "ptrdiff_t" or even "__attribute__", you get gobs of
> > hits.
>
> And?
Searching for "ptrdiff_t" just in the src directory brings more than
3500 hits. Does it sound like practical to you? Who'd be able to
review such a voluminous output to find what you are after?
> Now imagine if "ptrdiff_t" was called "function" instead.
I don't really see the difference.
Like I said: searching for symbols of a programming language is not a
good idea. It is not efficient, and thus not useful. So this aspect
is simply not relevant to the issue at hand.
> > Same if you search for "defun" or "defmac".
>
> defun and defmacro are great symbol names.
> Specific, unique and as a bonus short.
Maybe if you search the text of a book, or sources of a program
written in a language other than Lisp. Otherwise once again, you get
gobs of hits that are not relevant to what you are looking for.
So the point you are trying to make, namely, that bad names bring too
many hits, is not convincing, because any symbol we choose will have
the same problem.
> > This is simply not a good idea, and the fact that we choose this or
> > that name for a type declaration will never help you, as long as many
> > instances use that declaration.
>
> The focus is "Declaring Lisp function types". If it had a good symbol
> name, I could find relevant places without false positives.
Both 'function' and 'type' (and several similar ones) are good symbol
names for that. And if you disagree, let's agree to disagree, because
it doesn't sound like there's a sign of any agreement or compromise in
sight.
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-16 15:44 ` Eli Zaretskii
@ 2024-03-16 15:54 ` Emanuel Berg
2024-03-18 8:55 ` Lele Gaifax
1 sibling, 0 replies; 72+ messages in thread
From: Emanuel Berg @ 2024-03-16 15:54 UTC (permalink / raw)
To: emacs-devel
Eli Zaretskii wrote:
> Like I said: searching for symbols of a programming language
> is not a good idea. It is not efficient, and thus not
> useful. So this aspect is simply not relevant to the issue
> at hand.
Oh, people do that all the time, from inside and outside of
Emacs. There are many use cases for that, from finding what
caused error messages to simply navigating a buffer, and
many others.
So he has a point, it just that such concerns probably
shouldn't be what determines how the syntax of a language
looks. If "function" is the best way to describe it, it
probably is and that it will be hard(er) to find with certain
methods, well, that can't be helped.
But instead of arguing about people's workflows, let's just
put all suggestions on the table and have a look.
--
underground experts united
https://dataswamp.org/~incal
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-16 15:44 ` Eli Zaretskii
2024-03-16 15:54 ` Emanuel Berg
@ 2024-03-18 8:55 ` Lele Gaifax
1 sibling, 0 replies; 72+ messages in thread
From: Lele Gaifax @ 2024-03-18 8:55 UTC (permalink / raw)
To: emacs-devel
Eli Zaretskii <eliz@gnu.org> writes:
>> Now imagine if "ptrdiff_t" was called "function" instead.
>
> I don't really see the difference.
>
> Like I said: searching for symbols of a programming language is not a
> good idea. It is not efficient, and thus not useful. So this aspect
> is simply not relevant to the issue at hand.
I think Tomas just meant to say that, even if looking for "ptrdiff_t"
brings thousands of hits, you can be pretty confident that almost all of
them are related to a very particular kind of data, the same cannot be
said when looking for a much more generic term such as "function".
Not sure what kind of searches one would do on the keywords/symbols used
in a function declaration (and thus, strictly in this thread's topic),
but surely I find your assertion that
> searching for symbols of a programming language is not a
> good idea. It is not efficient, and thus not useful.
is a bit too broad: it's not that rare (or useless) to search and
replace all "ptrdiff_t" instance with something else.
That said, I think that's not reasonable to always require very specific
terms just to make it simpler to search for them: on one hand, we know
that "naming things" is very difficult, OTOH there a possibly better
approaches to look for terms in a specific context ("syntax aware
grep"[1] comes to mind).
ciao, lele.
[1] https://github.com/osa1/sg
--
nickname: Lele Gaifax | Quando vivrò di quello che ho pensato ieri
real: Emanuele Gaifas | comincerò ad aver paura di chi mi copia.
lele@metapensiero.it | -- Fortunato Depero, 1929.
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-15 16:49 ` Andrea Corallo
2024-03-15 18:19 ` Tomas Hlavaty
@ 2024-03-16 0:01 ` Adam Porter
2024-03-18 9:25 ` Andrea Corallo
2024-03-26 10:13 ` Andrea Corallo
2 siblings, 1 reply; 72+ messages in thread
From: Adam Porter @ 2024-03-16 0:01 UTC (permalink / raw)
To: acorallo; +Cc: eliz, emacs-devel, stefankangas
Hi Andrea, et al,
> I'd like to progress on this but in order to do that we should pick a
> syntax.
>
> Of the three most discussed syntaxes in this thread my order of
> preference is (by examples):
>
> 1:
>
> (defun sum (a b)
> (declare (function (integer integer) integer))
> (+ a b))
Please do not use this syntax. As I've said on the list at
<https://lists.gnu.org/archive/html/emacs-devel/2024-02/msg00790.html>
and
<https://lists.gnu.org/archive/html/emacs-devel/2024-02/msg00815.html>,
and in this bug report
<https://debbugs.gnu.org/cgi/bugreport.cgi?bug=69521>, and again on the
list in this separate thread, as I was instructed
<https://lists.gnu.org/archive/html/emacs-devel/2024-03/msg00118.html>,
that would preclude the possibility of allowing DECLARE-FUNCTION forms
to be placed inside DEFUNs' DECLARE forms as:
(declare (function ...))
For some reason, I can't seem to get a response to that idea, either
affirmative, negative, or neutral. But I would ask that my proposal at
least be considered and addressed before moving forward with that syntax
for this other purpose.
> 2:
>
> (defun sum (a b)
> (declare (type (function (integer integer) integer)))
> (+ a b))
>
> 3:
>
> (defun sum (a b)
> (declare (type (integer integer) integer))
> (+ a b))
>
> For the reasons I've already expressed: 1 I like it, 2 I'm okay with it,
> 3 I very much dislike it.
Forgive me if I've missed it, but why do you dislike #3? It seems
concise and descriptive: it is DECLAREing the DEFUN's TYPEs, just as:
(declare (debug ...))
DECLAREs the DEFUN's DEBUG instrumentation. Whereas including
"function" in the form seems redundant and occupies several extra
characters. The DECLARE form is specifically about the DEFUN, so what
other TYPEs would it be about?
Thanks,
Adam
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-16 0:01 ` Adam Porter
@ 2024-03-18 9:25 ` Andrea Corallo
0 siblings, 0 replies; 72+ messages in thread
From: Andrea Corallo @ 2024-03-18 9:25 UTC (permalink / raw)
To: Adam Porter; +Cc: eliz, emacs-devel, stefankangas
Adam Porter <adam@alphapapa.net> writes:
[...]
>> 2:
>> (defun sum (a b)
>> (declare (type (function (integer integer) integer)))
>> (+ a b))
>> 3:
>> (defun sum (a b)
>> (declare (type (integer integer) integer))
>> (+ a b))
>> For the reasons I've already expressed: 1 I like it, 2 I'm okay with
>> it,
>> 3 I very much dislike it.
>
> Forgive me if I've missed it, but why do you dislike #3?
Hi Adam, you can find my messages in this very thread on this, not sure
I've a better way to explain it.
Thanks
Andrea
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-15 16:49 ` Andrea Corallo
2024-03-15 18:19 ` Tomas Hlavaty
2024-03-16 0:01 ` Adam Porter
@ 2024-03-26 10:13 ` Andrea Corallo
2024-03-26 10:28 ` Christopher Dimech
` (4 more replies)
2 siblings, 5 replies; 72+ messages in thread
From: Andrea Corallo @ 2024-03-26 10:13 UTC (permalink / raw)
To: emacs-devel
Cc: Eli Zaretskii, Stefan Kangas, Adam Porter, Stefan Monnier,
Arthur Miller
Andrea Corallo <acorallo@gnu.org> writes:
> I'd like to progress on this but in order to do that we should pick a
> syntax.
>
> Of the three most discussed syntaxes in this thread my order of
> preference is (by examples):
>
> 1:
>
> (defun sum (a b)
> (declare (function (integer integer) integer))
> (+ a b))
>
> 2:
>
> (defun sum (a b)
> (declare (type (function (integer integer) integer)))
> (+ a b))
>
> 3:
>
> (defun sum (a b)
> (declare (type (integer integer) integer))
> (+ a b))
>
> For the reasons I've already expressed: 1 I like it, 2 I'm okay with it,
> 3 I very much dislike it.
>
> Maintainers WDYT?
>
> Thanks
>
> Andrea
To make a summary of my understanding of this conversation on the
various options so far:
A couple of people mentioned would be a good idea to consider CL's
syntax but this is problematic for how our declare machinery works.
I think Eli and I preferred solution 1.
Stefan suggested we go for 2 as it's more verbose (and this should
discourage users at using it too much).
Adam strongly opposed to 1 as it conflicts with his proposal [1] but
AFAIU he agreed later on that thread on another solution so I guess the
conflict should not be there anymore.
If I've miss-summarized any opinion indeed please feel free to rectify.
I think we should make a decision (maintainers) so we can progress on
this.
Thanks
Andrea
[1] <https://lists.gnu.org/archive/html/emacs-devel/2024-03/msg00118.html>
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-26 10:13 ` Andrea Corallo
@ 2024-03-26 10:28 ` Christopher Dimech
2024-03-26 12:55 ` Eli Zaretskii
` (3 subsequent siblings)
4 siblings, 0 replies; 72+ messages in thread
From: Christopher Dimech @ 2024-03-26 10:28 UTC (permalink / raw)
To: Andrea Corallo
Cc: emacs-devel, Eli Zaretskii, Stefan Kangas, Adam Porter,
Stefan Monnier, Arthur Miller
> Sent: Tuesday, March 26, 2024 at 10:13 PM
> From: "Andrea Corallo" <acorallo@gnu.org>
> To: emacs-devel@gnu.org
> Cc: "Eli Zaretskii" <eliz@gnu.org>, "Stefan Kangas" <stefankangas@gmail.com>, "Adam Porter" <adam@alphapapa.net>, "Stefan Monnier" <monnier@iro.umontreal.ca>, "Arthur Miller" <arthur.miller@live.com>
> Subject: Re: Declaring Lisp function types
>
> Andrea Corallo <acorallo@gnu.org> writes:
>
> > I'd like to progress on this but in order to do that we should pick a
> > syntax.
> >
> > Of the three most discussed syntaxes in this thread my order of
> > preference is (by examples):
> >
> > 1:
> >
> > (defun sum (a b)
> > (declare (function (integer integer) integer))
> > (+ a b))
> >
> > 2:
> >
> > (defun sum (a b)
> > (declare (type (function (integer integer) integer)))
> > (+ a b))
> >
> > 3:
> >
> > (defun sum (a b)
> > (declare (type (integer integer) integer))
> > (+ a b))
> >
> > For the reasons I've already expressed: 1 I like it, 2 I'm okay with it,
> > 3 I very much dislike it.
> >
> > Maintainers WDYT?
> >
> > Thanks
> >
> > Andrea
>
> To make a summary of my understanding of this conversation on the
> various options so far:
>
> A couple of people mentioned would be a good idea to consider CL's
> syntax but this is problematic for how our declare machinery works.
>
> I think Eli and I preferred solution 1.
I approve of preferred solution 1
> Stefan suggested we go for 2 as it's more verbose (and this should
> discourage users at using it too much).
Do not like increase of verbosity or intentions towards discouraging
functionalities that are inherently acceptable to use. If some things
should not be done, there should be no tools for them, especially not
emanating from an official release, as I am more for robustness as the
ultimate completion step.
> Adam strongly opposed to 1 as it conflicts with his proposal [1] but
> AFAIU he agreed later on that thread on another solution so I guess the
> conflict should not be there anymore.
>
> If I've miss-summarized any opinion indeed please feel free to rectify.
>
> I think we should make a decision (maintainers) so we can progress on
> this.
>
> Thanks
>
> Andrea
>
> [1] <https://lists.gnu.org/archive/html/emacs-devel/2024-03/msg00118.html>
>
>
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-26 10:13 ` Andrea Corallo
2024-03-26 10:28 ` Christopher Dimech
@ 2024-03-26 12:55 ` Eli Zaretskii
2024-03-26 16:46 ` Andrea Corallo
2024-03-26 13:05 ` Mattias Engdegård
` (2 subsequent siblings)
4 siblings, 1 reply; 72+ messages in thread
From: Eli Zaretskii @ 2024-03-26 12:55 UTC (permalink / raw)
To: Andrea Corallo; +Cc: emacs-devel, stefankangas, adam, monnier, arthur.miller
> From: Andrea Corallo <acorallo@gnu.org>
> Cc: Eli Zaretskii <eliz@gnu.org>, Stefan Kangas <stefankangas@gmail.com>,
> Adam Porter <adam@alphapapa.net>, Stefan Monnier
> <monnier@iro.umontreal.ca>, Arthur Miller <arthur.miller@live.com>
> Date: Tue, 26 Mar 2024 06:13:26 -0400
>
> Andrea Corallo <acorallo@gnu.org> writes:
>
> To make a summary of my understanding of this conversation on the
> various options so far:
>
> A couple of people mentioned would be a good idea to consider CL's
> syntax but this is problematic for how our declare machinery works.
>
> I think Eli and I preferred solution 1.
>
> Stefan suggested we go for 2 as it's more verbose (and this should
> discourage users at using it too much).
>
> Adam strongly opposed to 1 as it conflicts with his proposal [1] but
> AFAIU he agreed later on that thread on another solution so I guess the
> conflict should not be there anymore.
>
> If I've miss-summarized any opinion indeed please feel free to rectify.
I think your summary is okay. Very few people responded with opinions
anyway.
> I think we should make a decision (maintainers) so we can progress on
> this.
Are you opposed to (2), i.e.
(defun sum (a b)
(declare (type (function (integer integer) integer)))
(+ a b))
If not, I can live with it, and we have 3 people who are okay with it.
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-26 12:55 ` Eli Zaretskii
@ 2024-03-26 16:46 ` Andrea Corallo
2024-04-29 17:48 ` Andrea Corallo
0 siblings, 1 reply; 72+ messages in thread
From: Andrea Corallo @ 2024-03-26 16:46 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: emacs-devel, stefankangas, adam, monnier, arthur.miller
Eli Zaretskii <eliz@gnu.org> writes:
>> From: Andrea Corallo <acorallo@gnu.org>
>> Cc: Eli Zaretskii <eliz@gnu.org>, Stefan Kangas <stefankangas@gmail.com>,
>> Adam Porter <adam@alphapapa.net>, Stefan Monnier
>> <monnier@iro.umontreal.ca>, Arthur Miller <arthur.miller@live.com>
>> Date: Tue, 26 Mar 2024 06:13:26 -0400
>>
>> Andrea Corallo <acorallo@gnu.org> writes:
>>
>> To make a summary of my understanding of this conversation on the
>> various options so far:
>>
>> A couple of people mentioned would be a good idea to consider CL's
>> syntax but this is problematic for how our declare machinery works.
>>
>> I think Eli and I preferred solution 1.
>>
>> Stefan suggested we go for 2 as it's more verbose (and this should
>> discourage users at using it too much).
>>
>> Adam strongly opposed to 1 as it conflicts with his proposal [1] but
>> AFAIU he agreed later on that thread on another solution so I guess the
>> conflict should not be there anymore.
>>
>> If I've miss-summarized any opinion indeed please feel free to rectify.
>
> I think your summary is okay. Very few people responded with opinions
> anyway.
>
>> I think we should make a decision (maintainers) so we can progress on
>> this.
>
> Are you opposed to (2), i.e.
>
> (defun sum (a b)
> (declare (type (function (integer integer) integer)))
> (+ a b))
>
> If not, I can live with it, and we have 3 people who are okay with it.
I'm not opposed, I'm fine with it as well.
Andrea
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-26 16:46 ` Andrea Corallo
@ 2024-04-29 17:48 ` Andrea Corallo
2024-04-29 17:55 ` Stefan Monnier
2024-04-30 14:55 ` Eli Zaretskii
0 siblings, 2 replies; 72+ messages in thread
From: Andrea Corallo @ 2024-04-29 17:48 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: emacs-devel, stefankangas, adam, monnier, arthur.miller
Andrea Corallo <acorallo@gnu.org> writes:
> Eli Zaretskii <eliz@gnu.org> writes:
>
>>> From: Andrea Corallo <acorallo@gnu.org>
>>> Cc: Eli Zaretskii <eliz@gnu.org>, Stefan Kangas <stefankangas@gmail.com>,
>>> Adam Porter <adam@alphapapa.net>, Stefan Monnier
>>> <monnier@iro.umontreal.ca>, Arthur Miller <arthur.miller@live.com>
>>> Date: Tue, 26 Mar 2024 06:13:26 -0400
>>>
>>> Andrea Corallo <acorallo@gnu.org> writes:
>>>
>>> To make a summary of my understanding of this conversation on the
>>> various options so far:
>>>
>>> A couple of people mentioned would be a good idea to consider CL's
>>> syntax but this is problematic for how our declare machinery works.
>>>
>>> I think Eli and I preferred solution 1.
>>>
>>> Stefan suggested we go for 2 as it's more verbose (and this should
>>> discourage users at using it too much).
>>>
>>> Adam strongly opposed to 1 as it conflicts with his proposal [1] but
>>> AFAIU he agreed later on that thread on another solution so I guess the
>>> conflict should not be there anymore.
>>>
>>> If I've miss-summarized any opinion indeed please feel free to rectify.
>>
>> I think your summary is okay. Very few people responded with opinions
>> anyway.
>>
>>> I think we should make a decision (maintainers) so we can progress on
>>> this.
>>
>> Are you opposed to (2), i.e.
>>
>> (defun sum (a b)
>> (declare (type (function (integer integer) integer)))
>> (+ a b))
>>
>> If not, I can live with it, and we have 3 people who are okay with it.
>
> I'm not opposed, I'm fine with it as well.
>
> Andrea
Here we go, I pushed on 'scratch/lisp-func-type-decls' the
implementation of what we discussed with a doc entry. Any suggestion or
is it okay for master?
Thanks
Andrea
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-04-29 17:48 ` Andrea Corallo
@ 2024-04-29 17:55 ` Stefan Monnier
2024-04-29 18:42 ` Andrea Corallo
2024-04-30 14:55 ` Eli Zaretskii
1 sibling, 1 reply; 72+ messages in thread
From: Stefan Monnier @ 2024-04-29 17:55 UTC (permalink / raw)
To: Andrea Corallo
Cc: Eli Zaretskii, emacs-devel, stefankangas, adam, arthur.miller
> Here we go, I pushed on 'scratch/lisp-func-type-decls' the
> implementation of what we discussed with a doc entry. Any suggestion or
> is it okay for master?
Looks pretty good, but I wish the symbol property's name would make it
clear it's talking about the type of what's in the symbol's "function
cell" rather than any other role the symbol may be playing as well.
So maybe `function-type` instead of `declared-type`?
Stefan
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-04-29 17:55 ` Stefan Monnier
@ 2024-04-29 18:42 ` Andrea Corallo
0 siblings, 0 replies; 72+ messages in thread
From: Andrea Corallo @ 2024-04-29 18:42 UTC (permalink / raw)
To: Stefan Monnier
Cc: Eli Zaretskii, emacs-devel, stefankangas, adam, arthur.miller
Stefan Monnier <monnier@iro.umontreal.ca> writes:
>> Here we go, I pushed on 'scratch/lisp-func-type-decls' the
>> implementation of what we discussed with a doc entry. Any suggestion or
>> is it okay for master?
>
> Looks pretty good, but I wish the symbol property's name would make it
> clear it's talking about the type of what's in the symbol's "function
> cell" rather than any other role the symbol may be playing as well.
> So maybe `function-type` instead of `declared-type`?
Right, done now :)
Andrea
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-04-29 17:48 ` Andrea Corallo
2024-04-29 17:55 ` Stefan Monnier
@ 2024-04-30 14:55 ` Eli Zaretskii
2024-04-30 18:29 ` Stefan Monnier
2024-05-01 20:54 ` Andrea Corallo
1 sibling, 2 replies; 72+ messages in thread
From: Eli Zaretskii @ 2024-04-30 14:55 UTC (permalink / raw)
To: Andrea Corallo; +Cc: emacs-devel, stefankangas, adam, monnier, arthur.miller
> From: Andrea Corallo <acorallo@gnu.org>
> Cc: emacs-devel@gnu.org, stefankangas@gmail.com, adam@alphapapa.net,
> monnier@iro.umontreal.ca, arthur.miller@live.com
> Date: Mon, 29 Apr 2024 13:48:01 -0400
>
> Here we go, I pushed on 'scratch/lisp-func-type-decls' the
> implementation of what we discussed with a doc entry. Any suggestion or
> is it okay for master?
I think you can land it on master, but please expand this terse
description:
@item (type @var{type})
Declare @var{type} to be the type of this function. This is used for
documentation by @code{describe-function}. Also it can be used by the
native compiler (@pxref{Native-Compilation}) for improving code
generation and for deriving more precisely the type of other functions
without type declaration.
Without any discussion of what can be @var{type} and no examples, this
is too abstract. I learned more about it from the other parts of the
changeset, where you actually use this. So please say something about
what can be @var{type}, and add one or two examples.
Also, should we say something in NEWS about this?
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-04-30 14:55 ` Eli Zaretskii
@ 2024-04-30 18:29 ` Stefan Monnier
2024-05-01 20:57 ` Andrea Corallo
2024-05-01 20:54 ` Andrea Corallo
1 sibling, 1 reply; 72+ messages in thread
From: Stefan Monnier @ 2024-04-30 18:29 UTC (permalink / raw)
To: Eli Zaretskii
Cc: Andrea Corallo, emacs-devel, stefankangas, adam, arthur.miller
> @item (type @var{type})
> Declare @var{type} to be the type of this function. This is used for
> documentation by @code{describe-function}. Also it can be used by the
> native compiler (@pxref{Native-Compilation}) for improving code
> generation and for deriving more precisely the type of other functions
> without type declaration.
>
> Without any discussion of what can be @var{type} and no examples, this
> is too abstract. I learned more about it from the other parts of the
> changeset, where you actually use this. So please say something about
> what can be @var{type}, and add one or two examples.
Thanks Eli for reminding me: as mentioned earlier, I think we should
clarify what are the possible consequences if a type does not faithfully
reflect the behavior of the function. Examples of questions that one
should be able to answer based on the doc:
- Can an incorrect type affect Emacs' behavior (other than performance)?
- And if so, can it cause a crash?
- What if the type is/was right but an advice does
not obey the original type of the advised function?
The doc doesn't need to answer those questions directly, but it should
describe the possible effects of type annotations in enough details that
we can answer those questions.
Stefan
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-04-30 18:29 ` Stefan Monnier
@ 2024-05-01 20:57 ` Andrea Corallo
2024-05-01 21:06 ` Stefan Monnier
2024-05-02 6:15 ` Eli Zaretskii
0 siblings, 2 replies; 72+ messages in thread
From: Andrea Corallo @ 2024-05-01 20:57 UTC (permalink / raw)
To: Stefan Monnier
Cc: Eli Zaretskii, emacs-devel, stefankangas, adam, arthur.miller
Stefan Monnier <monnier@iro.umontreal.ca> writes:
>> @item (type @var{type})
>> Declare @var{type} to be the type of this function. This is used for
>> documentation by @code{describe-function}. Also it can be used by the
>> native compiler (@pxref{Native-Compilation}) for improving code
>> generation and for deriving more precisely the type of other functions
>> without type declaration.
>>
>> Without any discussion of what can be @var{type} and no examples, this
>> is too abstract. I learned more about it from the other parts of the
>> changeset, where you actually use this. So please say something about
>> what can be @var{type}, and add one or two examples.
>
> Thanks Eli for reminding me: as mentioned earlier, I think we should
> clarify what are the possible consequences if a type does not faithfully
> reflect the behavior of the function. Examples of questions that one
> should be able to answer based on the doc:
>
> - Can an incorrect type affect Emacs' behavior (other than performance)?
> - And if so, can it cause a crash?
> - What if the type is/was right but an advice does
> not obey the original type of the advised function?
>
> The doc doesn't need to answer those questions directly, but it should
> describe the possible effects of type annotations in enough details that
> we can answer those questions.
Thanks, I think it should be more clear now. I don't think we want to
be over specific there as what the implementation does when the
'promise' of the declaration is not respected might change in the
future.
Andrea
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-05-01 20:57 ` Andrea Corallo
@ 2024-05-01 21:06 ` Stefan Monnier
2024-05-02 6:16 ` Eli Zaretskii
2024-05-02 10:16 ` Andrea Corallo
2024-05-02 6:15 ` Eli Zaretskii
1 sibling, 2 replies; 72+ messages in thread
From: Stefan Monnier @ 2024-05-01 21:06 UTC (permalink / raw)
To: Andrea Corallo
Cc: Eli Zaretskii, emacs-devel, stefankangas, adam, arthur.miller
> Thanks, I think it should be more clear now. I don't think we want to
> be over specific there as what the implementation does when the
> 'promise' of the declaration is not respected might change in
> the future.
I think we need to mention very explicitly if "segfault" is considered
a valid possible outcome or not.
Stefan
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-05-01 21:06 ` Stefan Monnier
@ 2024-05-02 6:16 ` Eli Zaretskii
2024-05-02 10:16 ` Andrea Corallo
1 sibling, 0 replies; 72+ messages in thread
From: Eli Zaretskii @ 2024-05-02 6:16 UTC (permalink / raw)
To: Stefan Monnier; +Cc: acorallo, emacs-devel, stefankangas, adam, arthur.miller
> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Cc: Eli Zaretskii <eliz@gnu.org>, emacs-devel@gnu.org,
> stefankangas@gmail.com, adam@alphapapa.net, arthur.miller@live.com
> Date: Wed, 01 May 2024 17:06:47 -0400
>
> > Thanks, I think it should be more clear now. I don't think we want to
> > be over specific there as what the implementation does when the
> > 'promise' of the declaration is not respected might change in
> > the future.
>
> I think we need to mention very explicitly if "segfault" is considered
> a valid possible outcome or not.
Definitely. As well as any other "drastic" examples of UB.
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-05-01 21:06 ` Stefan Monnier
2024-05-02 6:16 ` Eli Zaretskii
@ 2024-05-02 10:16 ` Andrea Corallo
1 sibling, 0 replies; 72+ messages in thread
From: Andrea Corallo @ 2024-05-02 10:16 UTC (permalink / raw)
To: Stefan Monnier
Cc: Eli Zaretskii, emacs-devel, stefankangas, adam, arthur.miller
Stefan Monnier <monnier@iro.umontreal.ca> writes:
>> Thanks, I think it should be more clear now. I don't think we want to
>> be over specific there as what the implementation does when the
>> 'promise' of the declaration is not respected might change in
>> the future.
>
> I think we need to mention very explicitly if "segfault" is considered
> a valid possible outcome or not.
Done
Thanks
Andrea
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-05-01 20:57 ` Andrea Corallo
2024-05-01 21:06 ` Stefan Monnier
@ 2024-05-02 6:15 ` Eli Zaretskii
2024-05-02 10:12 ` Andrea Corallo
1 sibling, 1 reply; 72+ messages in thread
From: Eli Zaretskii @ 2024-05-02 6:15 UTC (permalink / raw)
To: Andrea Corallo; +Cc: monnier, emacs-devel, stefankangas, adam, arthur.miller
> From: Andrea Corallo <acorallo@gnu.org>
> Cc: Eli Zaretskii <eliz@gnu.org>, emacs-devel@gnu.org,
> stefankangas@gmail.com, adam@alphapapa.net, arthur.miller@live.com
> Date: Wed, 01 May 2024 16:57:58 -0400
>
> Stefan Monnier <monnier@iro.umontreal.ca> writes:
>
> > Thanks Eli for reminding me: as mentioned earlier, I think we should
> > clarify what are the possible consequences if a type does not faithfully
> > reflect the behavior of the function. Examples of questions that one
> > should be able to answer based on the doc:
> >
> > - Can an incorrect type affect Emacs' behavior (other than performance)?
> > - And if so, can it cause a crash?
> > - What if the type is/was right but an advice does
> > not obey the original type of the advised function?
> >
> > The doc doesn't need to answer those questions directly, but it should
> > describe the possible effects of type annotations in enough details that
> > we can answer those questions.
>
> Thanks, I think it should be more clear now. I don't think we want to
> be over specific there as what the implementation does when the
> 'promise' of the declaration is not respected might change in the
> future.
The text you added says an incorrect type produces undefined behavior.
Is that true for all alternatives of calling the function:
interpreted, byte-compiled, and native-compiled, or only with some of
these?
"Undefined behavior" sounds scary, and I wonder whether it is really
accurate. If the practical expressions of this UB are only some
specific ones, perhaps we should mention them? For example, UB
generally means your entire system could be brought down, but I very
much doubt that this could happen due to incorrect type declaration,
could it?
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-05-02 6:15 ` Eli Zaretskii
@ 2024-05-02 10:12 ` Andrea Corallo
2024-05-02 11:15 ` Eli Zaretskii
2024-05-02 13:20 ` Stefan Monnier
0 siblings, 2 replies; 72+ messages in thread
From: Andrea Corallo @ 2024-05-02 10:12 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: monnier, emacs-devel, stefankangas, adam, arthur.miller
Eli Zaretskii <eliz@gnu.org> writes:
>> From: Andrea Corallo <acorallo@gnu.org>
>> Cc: Eli Zaretskii <eliz@gnu.org>, emacs-devel@gnu.org,
>> stefankangas@gmail.com, adam@alphapapa.net, arthur.miller@live.com
>> Date: Wed, 01 May 2024 16:57:58 -0400
>>
>> Stefan Monnier <monnier@iro.umontreal.ca> writes:
>>
>> > Thanks Eli for reminding me: as mentioned earlier, I think we should
>> > clarify what are the possible consequences if a type does not faithfully
>> > reflect the behavior of the function. Examples of questions that one
>> > should be able to answer based on the doc:
>> >
>> > - Can an incorrect type affect Emacs' behavior (other than performance)?
>> > - And if so, can it cause a crash?
>> > - What if the type is/was right but an advice does
>> > not obey the original type of the advised function?
>> >
>> > The doc doesn't need to answer those questions directly, but it should
>> > describe the possible effects of type annotations in enough details that
>> > we can answer those questions.
>>
>> Thanks, I think it should be more clear now. I don't think we want to
>> be over specific there as what the implementation does when the
>> 'promise' of the declaration is not respected might change in the
>> future.
>
> The text you added says an incorrect type produces undefined behavior.
> Is that true for all alternatives of calling the function:
> interpreted, byte-compiled, and native-compiled, or only with some of
> these?
AFAIK only native-compiled ATM. Do you think we should specify that?
> "Undefined behavior" sounds scary, and I wonder whether it is really
> accurate. If the practical expressions of this UB are only some
> specific ones, perhaps we should mention them? For example, UB
> generally means your entire system could be brought down, but I very
> much doubt that this could happen due to incorrect type declaration,
> could it?
There are probably very few cases that can cause this (ATM I could think
only of one) but if one pokes at that is actually not that difficult:
(defun foo ()
(declare (type (function () cons)))
3)
(defun bar ()
(car (foo)))
Compiling this code and calling car crashes my Emacs.
PS We might want to control this in the future adding a compilation
parameter 'safety'.
Andrea
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-05-02 10:12 ` Andrea Corallo
@ 2024-05-02 11:15 ` Eli Zaretskii
2024-05-02 13:20 ` Stefan Monnier
1 sibling, 0 replies; 72+ messages in thread
From: Eli Zaretskii @ 2024-05-02 11:15 UTC (permalink / raw)
To: Andrea Corallo; +Cc: monnier, emacs-devel, stefankangas, adam, arthur.miller
> From: Andrea Corallo <acorallo@gnu.org>
> Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org, stefankangas@gmail.com,
> adam@alphapapa.net, arthur.miller@live.com
> Date: Thu, 02 May 2024 06:12:42 -0400
>
> Eli Zaretskii <eliz@gnu.org> writes:
>
> > The text you added says an incorrect type produces undefined behavior.
> > Is that true for all alternatives of calling the function:
> > interpreted, byte-compiled, and native-compiled, or only with some of
> > these?
>
> AFAIK only native-compiled ATM. Do you think we should specify that?
Yes, please.
> > "Undefined behavior" sounds scary, and I wonder whether it is really
> > accurate. If the practical expressions of this UB are only some
> > specific ones, perhaps we should mention them? For example, UB
> > generally means your entire system could be brought down, but I very
> > much doubt that this could happen due to incorrect type declaration,
> > could it?
>
> There are probably very few cases that can cause this (ATM I could think
> only of one) but if one pokes at that is actually not that difficult:
>
> (defun foo ()
> (declare (type (function () cons)))
> 3)
>
> (defun bar ()
> (car (foo)))
>
> Compiling this code and calling car crashes my Emacs.
It would be fine for now to say that incorrect type declaration could
crash Emacs if the code is natively-compiled and loaded.
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-05-02 10:12 ` Andrea Corallo
2024-05-02 11:15 ` Eli Zaretskii
@ 2024-05-02 13:20 ` Stefan Monnier
1 sibling, 0 replies; 72+ messages in thread
From: Stefan Monnier @ 2024-05-02 13:20 UTC (permalink / raw)
To: Andrea Corallo
Cc: Eli Zaretskii, emacs-devel, stefankangas, adam, arthur.miller
> There are probably very few cases that can cause this (ATM I could think
> only of one) but if one pokes at that is actually not that difficult:
[...]
> Compiling this code and calling car crashes my Emacs.
I like the current wording on your branch, thank you!
Stefan
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-04-30 14:55 ` Eli Zaretskii
2024-04-30 18:29 ` Stefan Monnier
@ 2024-05-01 20:54 ` Andrea Corallo
2024-05-02 10:22 ` Eli Zaretskii
1 sibling, 1 reply; 72+ messages in thread
From: Andrea Corallo @ 2024-05-01 20:54 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: emacs-devel, stefankangas, adam, monnier, arthur.miller
Eli Zaretskii <eliz@gnu.org> writes:
>> From: Andrea Corallo <acorallo@gnu.org>
>> Cc: emacs-devel@gnu.org, stefankangas@gmail.com, adam@alphapapa.net,
>> monnier@iro.umontreal.ca, arthur.miller@live.com
>> Date: Mon, 29 Apr 2024 13:48:01 -0400
>>
>> Here we go, I pushed on 'scratch/lisp-func-type-decls' the
>> implementation of what we discussed with a doc entry. Any suggestion or
>> is it okay for master?
>
> I think you can land it on master, but please expand this terse
> description:
>
> @item (type @var{type})
> Declare @var{type} to be the type of this function. This is used for
> documentation by @code{describe-function}. Also it can be used by the
> native compiler (@pxref{Native-Compilation}) for improving code
> generation and for deriving more precisely the type of other functions
> without type declaration.
Agree, I tried to add some of this.
> Without any discussion of what can be @var{type} and no examples, this
> is too abstract. I learned more about it from the other parts of the
> changeset, where you actually use this. So please say something about
> what can be @var{type}, and add one or two examples.
>
> Also, should we say something in NEWS about this?
Entry added.
Please let me know if you like me to merge it or I can improve it
further.
Thanks
Andrea
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-05-01 20:54 ` Andrea Corallo
@ 2024-05-02 10:22 ` Eli Zaretskii
2024-05-02 15:18 ` Andrea Corallo
0 siblings, 1 reply; 72+ messages in thread
From: Eli Zaretskii @ 2024-05-02 10:22 UTC (permalink / raw)
To: Andrea Corallo; +Cc: emacs-devel, stefankangas, adam, monnier, arthur.miller
> From: Andrea Corallo <acorallo@gnu.org>
> Cc: emacs-devel@gnu.org, stefankangas@gmail.com, adam@alphapapa.net,
> monnier@iro.umontreal.ca, arthur.miller@live.com
> Date: Wed, 01 May 2024 16:54:04 -0400
>
> Eli Zaretskii <eliz@gnu.org> writes:
>
> > Without any discussion of what can be @var{type} and no examples, this
> > is too abstract. I learned more about it from the other parts of the
> > changeset, where you actually use this. So please say something about
> > what can be @var{type}, and add one or two examples.
> >
> > Also, should we say something in NEWS about this?
>
> Entry added.
>
> Please let me know if you like me to merge it or I can improve it
> further.
Thanks. I still have a few minor comments below, but we can handle
these after this lands on master.
> +@var{type} is a type specifier in the form @code{(function (ARG-1-TYPE
> +... ARG-N-TYPE) RETURN-TYPE)}. Argument types can be interleaved with
The @code{..} part should be wrapped in @w{..}, to prevent its
breaking between two lines.
> +symbols @code{&optional} and @code{&rest} to match the @pxref{Argument
> +List} of the function.
This is not a good use of @pxref. You want @ref there. Moreover,
such HTML-like style of cross-references doesn't work well in Texinfo,
because at least the info and the printed output formats add stuff,
like "See" to the reference. So my recommendation is to use a wordier
...to match the function's arguments (@pxref{Argument List}).
> +@lisp
> +(defun positive-p (x)
> + (declare (type (function (number) boolean)))
> + (when (> x 0)
> + t))
> +@end lisp
If you don't want to have the example broken between two pages, use
@group:
@lisp
@group
(defun positive-p (x)
(declare (type (function (number) boolean)))
(when (> x 0)
t))
@end group
@end lisp
> +@lisp
> +(defun cons-or-number (x &optional err-msg)
> + (declare (type (function ((or cons number) &optional string)
> + (member is-cons is-number))))
> + (if (consp x)
> + 'is-cons
> + (if (numberp x)
> + 'is-number
> + (error (or err-msg "Unexpected input")))))
> +@end lisp
Same here.
> +More types are described in @pxref{Lisp Data Types}.
The problematic cross-reference again.
> --- a/etc/NEWS
> +++ b/etc/NEWS
> @@ -1935,6 +1935,10 @@ unibyte string.
> \f
> * Lisp Changes in Emacs 30.1
>
> +** Function type declaration
This should end in a period. Also, since you have updated the manual,
it should be marked with "+++".
> +It is now possible, using the 'declare' macro, to declare expected types
> +of function arguments and return type.
Suggest to reword:
It is now possible to declare the expected type of a function's
arguments using the 'declare' macro.
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-05-02 10:22 ` Eli Zaretskii
@ 2024-05-02 15:18 ` Andrea Corallo
2024-05-02 16:32 ` Eli Zaretskii
0 siblings, 1 reply; 72+ messages in thread
From: Andrea Corallo @ 2024-05-02 15:18 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: emacs-devel, stefankangas, adam, monnier, arthur.miller
Eli Zaretskii <eliz@gnu.org> writes:
>> From: Andrea Corallo <acorallo@gnu.org>
>> Cc: emacs-devel@gnu.org, stefankangas@gmail.com, adam@alphapapa.net,
>> monnier@iro.umontreal.ca, arthur.miller@live.com
>> Date: Wed, 01 May 2024 16:54:04 -0400
>>
>> Eli Zaretskii <eliz@gnu.org> writes:
>>
>> > Without any discussion of what can be @var{type} and no examples, this
>> > is too abstract. I learned more about it from the other parts of the
>> > changeset, where you actually use this. So please say something about
>> > what can be @var{type}, and add one or two examples.
>> >
>> > Also, should we say something in NEWS about this?
>>
>> Entry added.
>>
>> Please let me know if you like me to merge it or I can improve it
>> further.
>
> Thanks. I still have a few minor comments below, but we can handle
> these after this lands on master.
Hi Eli,
I've addressed your suggestions (hope I'm not missing something) and
pushed the merge to master.
Happy to improve it (or see it improved) further there if necessary.
I just left this out:
> Suggest to reword:
>
> It is now possible to declare the expected type of a function's
> arguments using the 'declare' macro.
as is not just about input arguments but also return type.
Andrea
PS thanks for the review, it has improved my texinfo skills 😀🚀.
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-05-02 15:18 ` Andrea Corallo
@ 2024-05-02 16:32 ` Eli Zaretskii
0 siblings, 0 replies; 72+ messages in thread
From: Eli Zaretskii @ 2024-05-02 16:32 UTC (permalink / raw)
To: Andrea Corallo; +Cc: emacs-devel, stefankangas, adam, monnier, arthur.miller
> From: Andrea Corallo <acorallo@gnu.org>
> Cc: emacs-devel@gnu.org, stefankangas@gmail.com, adam@alphapapa.net,
> monnier@iro.umontreal.ca, arthur.miller@live.com
> Date: Thu, 02 May 2024 11:18:03 -0400
>
> Eli Zaretskii <eliz@gnu.org> writes:
>
> > Thanks. I still have a few minor comments below, but we can handle
> > these after this lands on master.
>
> Hi Eli,
>
> I've addressed your suggestions (hope I'm not missing something) and
> pushed the merge to master.
Thanks.
> Happy to improve it (or see it improved) further there if necessary.
I made a couple of minor copyedits.
> I just left this out:
>
> > Suggest to reword:
> >
> > It is now possible to declare the expected type of a function's
> > arguments using the 'declare' macro.
>
> as is not just about input arguments but also return type.
I fixed that as well.
> PS thanks for the review, it has improved my texinfo skills 😀🚀.
That was the goal ;-)
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-26 10:13 ` Andrea Corallo
2024-03-26 10:28 ` Christopher Dimech
2024-03-26 12:55 ` Eli Zaretskii
@ 2024-03-26 13:05 ` Mattias Engdegård
2024-03-26 13:44 ` Stefan Monnier
2024-03-26 14:28 ` Joost Kremers
4 siblings, 0 replies; 72+ messages in thread
From: Mattias Engdegård @ 2024-03-26 13:05 UTC (permalink / raw)
To: Andrea Corallo
Cc: emacs-devel, Eli Zaretskii, Stefan Kangas, Adam Porter,
Stefan Monnier, Arthur Miller
26 mars 2024 kl. 11.13 skrev Andrea Corallo <acorallo@gnu.org>:
>> (declare (type (function (integer integer) integer)))
Firmly in favour of this.
But we also need to define the exact semantics of such a declaration.
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-26 10:13 ` Andrea Corallo
` (2 preceding siblings ...)
2024-03-26 13:05 ` Mattias Engdegård
@ 2024-03-26 13:44 ` Stefan Monnier
2024-03-26 14:28 ` Joost Kremers
4 siblings, 0 replies; 72+ messages in thread
From: Stefan Monnier @ 2024-03-26 13:44 UTC (permalink / raw)
To: Andrea Corallo
Cc: emacs-devel, Eli Zaretskii, Stefan Kangas, Adam Porter,
Arthur Miller
> Stefan suggested we go for 2 as it's more verbose (and this should
> discourage users at using it too much).
Side note: the main reason I'm in favor of 2 is because it's simpler and
cleaner. The "more verbose" is just a kind of side-benefit to try and
reassure those who are afraid of annotations becoming the norm.
Stefan
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-26 10:13 ` Andrea Corallo
` (3 preceding siblings ...)
2024-03-26 13:44 ` Stefan Monnier
@ 2024-03-26 14:28 ` Joost Kremers
2024-03-26 14:37 ` Stefan Monnier
4 siblings, 1 reply; 72+ messages in thread
From: Joost Kremers @ 2024-03-26 14:28 UTC (permalink / raw)
To: Andrea Corallo
Cc: emacs-devel, Eli Zaretskii, Stefan Kangas, Adam Porter,
Stefan Monnier, Arthur Miller
On Tue, Mar 26 2024, Andrea Corallo wrote:
> Andrea Corallo <acorallo@gnu.org> writes:
>> 1:
>>
>> (defun sum (a b)
>> (declare (function (integer integer) integer))
>> (+ a b))
>>
>> 2:
>>
>> (defun sum (a b)
>> (declare (type (function (integer integer) integer)))
>> (+ a b))
>>
>> 3:
>>
>> (defun sum (a b)
>> (declare (type (integer integer) integer))
>> (+ a b))
>>
>> For the reasons I've already expressed: 1 I like it, 2 I'm okay with it,
>> 3 I very much dislike it.
>>
>> Maintainers WDYT?
I'm not a maintainer, so ignore this message if you like, but having just reread
the info node on `declare`, 2 doesn't make sense to me. `declare` takes an
argument SPECS, where "[e]ach element in SPECS should have the form ‘(PROPERTY
ARGS...)’". Using `type` as PROPERTY makes sense, but if its argument can be
`(function in-types out-type), you'd expect that it could also be `(macro
in-types out-type)`, possibly among other options (`closure`? `command`?).
For similar reasons, using `function` as the PROPERTY is also a bit strange.
(Unless this form would be restricted to actual functions? I didn't read that
anywhere in the thread.)
So `type` seems to make sense. Or, if that is too generic a term, why not use
`signature` instead?
--
Joost Kremers
Life has its moments
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-26 14:28 ` Joost Kremers
@ 2024-03-26 14:37 ` Stefan Monnier
0 siblings, 0 replies; 72+ messages in thread
From: Stefan Monnier @ 2024-03-26 14:37 UTC (permalink / raw)
To: Joost Kremers
Cc: Andrea Corallo, emacs-devel, Eli Zaretskii, Stefan Kangas,
Adam Porter, Arthur Miller
> Using `type` as PROPERTY makes sense, but if its argument can be
> `(function in-types out-type), you'd expect that it could also be `(macro
> in-types out-type)`, possibly among other options (`closure`? `command`?).
In principle, it can indeed be other things than (function (FOOs) BAR),
but if it's used within a `defun`, in practice it's likely to always be
of the form (function (FOOs) BAR).
Stefan
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
@ 2024-03-16 7:46 Arthur Miller
2024-03-16 15:46 ` Emanuel Berg
2024-03-18 9:02 ` Andrea Corallo
0 siblings, 2 replies; 72+ messages in thread
From: Arthur Miller @ 2024-03-16 7:46 UTC (permalink / raw)
To: acorallo; +Cc: emacs-devel
Stefan Monnier via "Emacs development discussions."
<emacs-devel@gnu.org> writes:
>>> (declaim (ftype (function (integer integer) integer) sum))
>>> ;; ^^inputs ^^output [optional]
>>> (defun sum (a b)
>>> (declare (integer a b))
>>> (+ a b))
>>
>> Non-starter for me: the separation into two steps makes it unclear what
>> the declaration applies to (e.g. when re-running the above code, does
>> the `declaim` apply to the old definition (the one active when the
>> `declaim` is executed)® the the one that's about to be installed)?
>>
>>> ;;2
>>> (defun sum (a b)
>>> (declare (integer a b))
>>> (+ a b))
>>
>> None starter because of how we defined `declare`, where we'd have to
>> define every existing type as a valid declaration idenitifer.
>>
>>> ;;3 through 'defstar' (a CL library not in the standard)
>>> (defun* sum ((a integer) (b integer))
>>> (+ a b))
>>> ;;4 again through 'defstar'
>>> (defun* (sum -> integer) ((a integer) (b integer))
>>> (+ a b))
>>
>> Acceptable, with some tweaks to better fit my favorite bikeshed color.
>>
>>> (defun sum (a b)
>>> (declare (ftype (function (integer integer) integer)))
>>> (+ a b))
>>
>> The `f` of `ftype` is redundant with the following `function`, so we
>> could shorten that to:
>>
>> (defun sum (a b)
>> (declare (ftype (integer integer) integer))
>> (+ a b))
>>
>>> (defun sum (a b)
>>> (declare (function (integer integer) integer))
>>> (+ a b))
>>
>> It's cute, I guess. Whether to prefer `function`, `ftype`, or Adam's `type`,
>> is largely a "bikeshed color" choice. I do prefer the latter two
>> because we already know that this is a function, whereas we don't know
>> that this is a *type* (and they're shorter, to boot).
>>
>> Later you said:
>>> Fact is, we already use the form (function (ATYPES) RTYPE) as type
>>> specifier for functions. So (ftype (function (ATYPES) RTYPE)) would be
>>> the most correct form semantically, where `ftype` (or `type` or really
>>> what we prefer) would be the declaration which takes the type specifier
>>> as argument.
>>
>> Of course (declare (ftype (integer integer) integer))
>> would still end up generating something like
>>
>> (foo-declare-type 'sum '(function (integer integer) integer))
>
>My fear it's this is a bit more convoluted and this extra step makes it
>less understandable/justifiable. I like the symmetry of having
>'function' both in the input (the declaration) and the output (the final
>type itself). Maybe my background as physicist makes symmetry too
>central for me? :)
>
>> so I see no semantic issue with using `ftype` or `type` here, unless
>> there are functions whose type could take another form than (function
>> <args> <rettype>)? Are you thinking of types like
>> (or (function (int) int) (function (float) float))?
>
>That's a good example why it would be good to be able to accept the type
>specifier as a declaration with no tricks. On the specific case I'm not
>sure we want to support this in the inner machinery (at least for now).
>
>> More important I think is to document what such annotations mean and
>> what they should look like (currently, this is not super important,
>> because the annotations live together with the code that uses them, but
>> if we move them outside of `comp.el`, the "contract" needs to be made
>> more explicit).
>>
>> - How they interact with `&optional` and `&rest` (or even `&key` for
>> `c-defun`).
>
>ATM we already support in type specifiers `&optional` and `&rest`:
>
>(subr-type (native-compile '(lambda (x &optional y &rest z)))) =>
>(function (t &optional t &rest t) null)
>
>Not sure we want to handle &key as well as it looks to me not very
>native to the elisp machinery. OTOH cl-defun just expands to the native
>elisp call convention.
>
>> - What will/could happen if one of the arguments does not have the
>> specified type?
>
>I think if ones does a declaration has to declare the type of all
>arguments (rest should be optional).
>
>> - What will/could happen if the result does not have the
>> specified type?
>
>I think we want to complete it with the inferred return type if we have
>it or t otherwise.
>
>> - Do we have types to say "arg unused" or "no return value"?
>
>We don't have "arg unused" because the function type (or signature) is
>like the contract with the outside word, it should not matter how (and
>if) and arg is used inside.
>
>OTOH we have "no return value" and it's nil
>
>(subr-type (native-compile '(lambda (x) (error x)))) =>
>(function (t) nil)
>
>> - Can we have higher-order function types, like
>>
>> (function (proc (function (proc string) void)) void)
>>
>> and if so, again, what does it mean in terms of what can happen if the
>> runtime values don't actually match the announced types (e.g. what
>> happens (and when) if we pass a function that has the "wrong type")?
>
>I don't kwnow if we want to allow this to be future proof, ATM certanly
>the compiler does not use it and I don't think it could help code
>generation. OTOH might be nice for documentation?
>
>As a note: AFAIR SBCL doesn't go beyond something like:
>(function (integer function) function)
>
>That if arguments/ret values are functions it forgets the inner details
>of their type specifier.
>
>Anyway I certanly agree we should better document this once it's shaped,
>and I'll try my best.
>
>But generally speaking I've the feeling there might be other cases we
>don't see ATM where accepting directly the type specifier as valid
>declaration graciously/naturally solves potential issues we could hit
>otherwise.
>
>Thanks
Please, if you can, just (re)use SBCL syntax. It makes life easier
for those who are already familiar. Those who are not have to learn
something new anyway, so for them it does not matter.
Great work, thank you working so much with this.
best regards
/arthur
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-16 7:46 Arthur Miller
@ 2024-03-16 15:46 ` Emanuel Berg
2024-03-18 9:02 ` Andrea Corallo
1 sibling, 0 replies; 72+ messages in thread
From: Emanuel Berg @ 2024-03-16 15:46 UTC (permalink / raw)
To: emacs-devel
Arthur Miller wrote:
> Please, if you can, just (re)use SBCL syntax. It makes life
> easier for those who are already familiar. Those who are not
> have to learn something new anyway, so for them it does
> not matter.
Yes, and especially if the SBCL syntax is good to begin with.
--
underground experts united
https://dataswamp.org/~incal
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-16 7:46 Arthur Miller
2024-03-16 15:46 ` Emanuel Berg
@ 2024-03-18 9:02 ` Andrea Corallo
2024-03-18 9:58 ` Arthur Miller
1 sibling, 1 reply; 72+ messages in thread
From: Andrea Corallo @ 2024-03-18 9:02 UTC (permalink / raw)
To: Arthur Miller; +Cc: emacs-devel
Arthur Miller <arthur.miller@live.com> writes:
> Stefan Monnier via "Emacs development discussions."
> <emacs-devel@gnu.org> writes:
>
>>>> (declaim (ftype (function (integer integer) integer) sum))
>>>> ;; ^^inputs ^^output [optional]
>>>> (defun sum (a b)
>>>> (declare (integer a b))
>>>> (+ a b))
>>>
>>> Non-starter for me: the separation into two steps makes it unclear what
>>> the declaration applies to (e.g. when re-running the above code, does
>>> the `declaim` apply to the old definition (the one active when the
>>> `declaim` is executed)® the the one that's about to be installed)?
>>>
>>>> ;;2
>>>> (defun sum (a b)
>>>> (declare (integer a b))
>>>> (+ a b))
>>>
>>> None starter because of how we defined `declare`, where we'd have to
>>> define every existing type as a valid declaration idenitifer.
>>>
>>>> ;;3 through 'defstar' (a CL library not in the standard)
>>>> (defun* sum ((a integer) (b integer))
>>>> (+ a b))
>>>> ;;4 again through 'defstar'
>>>> (defun* (sum -> integer) ((a integer) (b integer))
>>>> (+ a b))
>>>
>>> Acceptable, with some tweaks to better fit my favorite bikeshed color.
>>>
>>>> (defun sum (a b)
>>>> (declare (ftype (function (integer integer) integer)))
>>>> (+ a b))
>>>
>>> The `f` of `ftype` is redundant with the following `function`, so we
>>> could shorten that to:
>>>
>>> (defun sum (a b)
>>> (declare (ftype (integer integer) integer))
>>> (+ a b))
>>>
>>>> (defun sum (a b)
>>>> (declare (function (integer integer) integer))
>>>> (+ a b))
>>>
>>> It's cute, I guess. Whether to prefer `function`, `ftype`, or Adam's `type`,
>>> is largely a "bikeshed color" choice. I do prefer the latter two
>>> because we already know that this is a function, whereas we don't know
>>> that this is a *type* (and they're shorter, to boot).
>>>
>>> Later you said:
>>>> Fact is, we already use the form (function (ATYPES) RTYPE) as type
>>>> specifier for functions. So (ftype (function (ATYPES) RTYPE)) would be
>>>> the most correct form semantically, where `ftype` (or `type` or really
>>>> what we prefer) would be the declaration which takes the type specifier
>>>> as argument.
>>>
>>> Of course (declare (ftype (integer integer) integer))
>>> would still end up generating something like
>>>
>>> (foo-declare-type 'sum '(function (integer integer) integer))
>>
>>My fear it's this is a bit more convoluted and this extra step makes it
>>less understandable/justifiable. I like the symmetry of having
>>'function' both in the input (the declaration) and the output (the final
>>type itself). Maybe my background as physicist makes symmetry too
>>central for me? :)
>>
>>> so I see no semantic issue with using `ftype` or `type` here, unless
>>> there are functions whose type could take another form than (function
>>> <args> <rettype>)? Are you thinking of types like
>>> (or (function (int) int) (function (float) float))?
>>
>>That's a good example why it would be good to be able to accept the type
>>specifier as a declaration with no tricks. On the specific case I'm not
>>sure we want to support this in the inner machinery (at least for now).
>>
>>> More important I think is to document what such annotations mean and
>>> what they should look like (currently, this is not super important,
>>> because the annotations live together with the code that uses them, but
>>> if we move them outside of `comp.el`, the "contract" needs to be made
>>> more explicit).
>>>
>>> - How they interact with `&optional` and `&rest` (or even `&key` for
>>> `c-defun`).
>>
>>ATM we already support in type specifiers `&optional` and `&rest`:
>>
>>(subr-type (native-compile '(lambda (x &optional y &rest z)))) =>
>>(function (t &optional t &rest t) null)
>>
>>Not sure we want to handle &key as well as it looks to me not very
>>native to the elisp machinery. OTOH cl-defun just expands to the native
>>elisp call convention.
>>
>>> - What will/could happen if one of the arguments does not have the
>>> specified type?
>>
>>I think if ones does a declaration has to declare the type of all
>>arguments (rest should be optional).
>>
>>> - What will/could happen if the result does not have the
>>> specified type?
>>
>>I think we want to complete it with the inferred return type if we have
>>it or t otherwise.
>>
>>> - Do we have types to say "arg unused" or "no return value"?
>>
>>We don't have "arg unused" because the function type (or signature) is
>>like the contract with the outside word, it should not matter how (and
>>if) and arg is used inside.
>>
>>OTOH we have "no return value" and it's nil
>>
>>(subr-type (native-compile '(lambda (x) (error x)))) =>
>>(function (t) nil)
>>
>>> - Can we have higher-order function types, like
>>>
>>> (function (proc (function (proc string) void)) void)
>>>
>>> and if so, again, what does it mean in terms of what can happen if the
>>> runtime values don't actually match the announced types (e.g. what
>>> happens (and when) if we pass a function that has the "wrong type")?
>>
>>I don't kwnow if we want to allow this to be future proof, ATM certanly
>>the compiler does not use it and I don't think it could help code
>>generation. OTOH might be nice for documentation?
>>
>>As a note: AFAIR SBCL doesn't go beyond something like:
>>(function (integer function) function)
>>
>>That if arguments/ret values are functions it forgets the inner details
>>of their type specifier.
>>
>>Anyway I certanly agree we should better document this once it's shaped,
>>and I'll try my best.
>>
>>But generally speaking I've the feeling there might be other cases we
>>don't see ATM where accepting directly the type specifier as valid
>>declaration graciously/naturally solves potential issues we could hit
>>otherwise.
>>
>>Thanks
>
> Please, if you can, just (re)use SBCL syntax. It makes life easier
> for those who are already familiar. Those who are not have to learn
> something new anyway, so for them it does not matter.
>
> Great work, thank you working so much with this.
Hi Arthur,
I agree on the principle, but unfortunately as mentioned using the CL
syntax in the Emacs declare machinery is problematic for how this second
one is constructed. I think is not a realistic option.
Thanks
Andrea
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Declaring Lisp function types
2024-03-18 9:02 ` Andrea Corallo
@ 2024-03-18 9:58 ` Arthur Miller
0 siblings, 0 replies; 72+ messages in thread
From: Arthur Miller @ 2024-03-18 9:58 UTC (permalink / raw)
To: Andrea Corallo; +Cc: emacs-devel
Andrea Corallo <acorallo@gnu.org> writes:
> Arthur Miller <arthur.miller@live.com> writes:
>
>> Stefan Monnier via "Emacs development discussions."
>> <emacs-devel@gnu.org> writes:
>>
>>>>> (declaim (ftype (function (integer integer) integer) sum))
>>>>> ;; ^^inputs ^^output [optional]
>>>>> (defun sum (a b)
>>>>> (declare (integer a b))
>>>>> (+ a b))
>>>>
>>>> Non-starter for me: the separation into two steps makes it unclear what
>>>> the declaration applies to (e.g. when re-running the above code, does
>>>> the `declaim` apply to the old definition (the one active when the
>>>> `declaim` is executed)® the the one that's about to be installed)?
>>>>
>>>>> ;;2
>>>>> (defun sum (a b)
>>>>> (declare (integer a b))
>>>>> (+ a b))
>>>>
>>>> None starter because of how we defined `declare`, where we'd have to
>>>> define every existing type as a valid declaration idenitifer.
>>>>
>>>>> ;;3 through 'defstar' (a CL library not in the standard)
>>>>> (defun* sum ((a integer) (b integer))
>>>>> (+ a b))
>>>>> ;;4 again through 'defstar'
>>>>> (defun* (sum -> integer) ((a integer) (b integer))
>>>>> (+ a b))
>>>>
>>>> Acceptable, with some tweaks to better fit my favorite bikeshed color.
>>>>
>>>>> (defun sum (a b)
>>>>> (declare (ftype (function (integer integer) integer)))
>>>>> (+ a b))
>>>>
>>>> The `f` of `ftype` is redundant with the following `function`, so we
>>>> could shorten that to:
>>>>
>>>> (defun sum (a b)
>>>> (declare (ftype (integer integer) integer))
>>>> (+ a b))
>>>>
>>>>> (defun sum (a b)
>>>>> (declare (function (integer integer) integer))
>>>>> (+ a b))
>>>>
>>>> It's cute, I guess. Whether to prefer `function`, `ftype`, or Adam's `type`,
>>>> is largely a "bikeshed color" choice. I do prefer the latter two
>>>> because we already know that this is a function, whereas we don't know
>>>> that this is a *type* (and they're shorter, to boot).
>>>>
>>>> Later you said:
>>>>> Fact is, we already use the form (function (ATYPES) RTYPE) as type
>>>>> specifier for functions. So (ftype (function (ATYPES) RTYPE)) would be
>>>>> the most correct form semantically, where `ftype` (or `type` or really
>>>>> what we prefer) would be the declaration which takes the type specifier
>>>>> as argument.
>>>>
>>>> Of course (declare (ftype (integer integer) integer))
>>>> would still end up generating something like
>>>>
>>>> (foo-declare-type 'sum '(function (integer integer) integer))
>>>
>>>My fear it's this is a bit more convoluted and this extra step makes it
>>>less understandable/justifiable. I like the symmetry of having
>>>'function' both in the input (the declaration) and the output (the final
>>>type itself). Maybe my background as physicist makes symmetry too
>>>central for me? :)
>>>
>>>> so I see no semantic issue with using `ftype` or `type` here, unless
>>>> there are functions whose type could take another form than (function
>>>> <args> <rettype>)? Are you thinking of types like
>>>> (or (function (int) int) (function (float) float))?
>>>
>>>That's a good example why it would be good to be able to accept the type
>>>specifier as a declaration with no tricks. On the specific case I'm not
>>>sure we want to support this in the inner machinery (at least for now).
>>>
>>>> More important I think is to document what such annotations mean and
>>>> what they should look like (currently, this is not super important,
>>>> because the annotations live together with the code that uses them, but
>>>> if we move them outside of `comp.el`, the "contract" needs to be made
>>>> more explicit).
>>>>
>>>> - How they interact with `&optional` and `&rest` (or even `&key` for
>>>> `c-defun`).
>>>
>>>ATM we already support in type specifiers `&optional` and `&rest`:
>>>
>>>(subr-type (native-compile '(lambda (x &optional y &rest z)))) =>
>>>(function (t &optional t &rest t) null)
>>>
>>>Not sure we want to handle &key as well as it looks to me not very
>>>native to the elisp machinery. OTOH cl-defun just expands to the native
>>>elisp call convention.
>>>
>>>> - What will/could happen if one of the arguments does not have the
>>>> specified type?
>>>
>>>I think if ones does a declaration has to declare the type of all
>>>arguments (rest should be optional).
>>>
>>>> - What will/could happen if the result does not have the
>>>> specified type?
>>>
>>>I think we want to complete it with the inferred return type if we have
>>>it or t otherwise.
>>>
>>>> - Do we have types to say "arg unused" or "no return value"?
>>>
>>>We don't have "arg unused" because the function type (or signature) is
>>>like the contract with the outside word, it should not matter how (and
>>>if) and arg is used inside.
>>>
>>>OTOH we have "no return value" and it's nil
>>>
>>>(subr-type (native-compile '(lambda (x) (error x)))) =>
>>>(function (t) nil)
>>>
>>>> - Can we have higher-order function types, like
>>>>
>>>> (function (proc (function (proc string) void)) void)
>>>>
>>>> and if so, again, what does it mean in terms of what can happen if the
>>>> runtime values don't actually match the announced types (e.g. what
>>>> happens (and when) if we pass a function that has the "wrong type")?
>>>
>>>I don't kwnow if we want to allow this to be future proof, ATM certanly
>>>the compiler does not use it and I don't think it could help code
>>>generation. OTOH might be nice for documentation?
>>>
>>>As a note: AFAIR SBCL doesn't go beyond something like:
>>>(function (integer function) function)
>>>
>>>That if arguments/ret values are functions it forgets the inner details
>>>of their type specifier.
>>>
>>>Anyway I certanly agree we should better document this once it's shaped,
>>>and I'll try my best.
>>>
>>>But generally speaking I've the feeling there might be other cases we
>>>don't see ATM where accepting directly the type specifier as valid
>>>declaration graciously/naturally solves potential issues we could hit
>>>otherwise.
>>>
>>>Thanks
>>
>> Please, if you can, just (re)use SBCL syntax. It makes life easier
>> for those who are already familiar. Those who are not have to learn
>> something new anyway, so for them it does not matter.
>>
>> Great work, thank you working so much with this.
>
> Hi Arthur,
>
> I agree on the principle, but unfortunately as mentioned using the CL
> syntax in the Emacs declare machinery is problematic for how this second
> one is constructed. I think is not a realistic option.
Allright, that is unfortunate, but I understand, thanks for the clarification.
/best regards
> Thanks
>
> Andrea
^ permalink raw reply [flat|nested] 72+ messages in thread
end of thread, other threads:[~2024-05-02 16:32 UTC | newest]
Thread overview: 72+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-02-23 16:02 Declaring Lisp function types Andrea Corallo
2024-02-23 23:35 ` Adam Porter
2024-02-24 7:10 ` Eli Zaretskii
2024-02-24 8:53 ` Tomas Hlavaty
2024-02-24 9:08 ` Adam Porter
2024-02-24 9:24 ` Andrea Corallo
2024-02-24 15:13 ` Tomas Hlavaty
2024-02-24 15:21 ` Tomas Hlavaty
2024-02-24 15:24 ` Tomas Hlavaty
2024-02-24 8:56 ` Adam Porter
2024-02-24 10:03 ` Eli Zaretskii
2024-02-25 7:35 ` Adam Porter
2024-02-24 9:21 ` Andrea Corallo
2024-02-25 17:04 ` Alan Mackenzie
2024-02-25 17:15 ` Eli Zaretskii
2024-02-25 17:16 ` [External] : " Drew Adams
2024-02-26 16:25 ` Andrea Corallo
2024-02-29 3:50 ` Richard Stallman
2024-02-29 6:10 ` Adam Porter
2024-02-29 9:02 ` Andrea Corallo
2024-02-26 3:38 ` Richard Stallman
2024-02-26 16:38 ` [External] : " Drew Adams
2024-02-26 16:54 ` Eli Zaretskii
2024-02-26 17:44 ` Andrea Corallo
2024-02-26 16:52 ` Andrea Corallo
2024-02-26 18:10 ` Tomas Hlavaty
2024-03-02 21:19 ` Stefan Monnier via Emacs development discussions.
2024-03-03 9:52 ` Andrea Corallo
2024-03-03 14:52 ` Stefan Monnier
2024-03-03 17:31 ` Andrea Corallo
2024-03-03 18:13 ` Stefan Monnier
2024-03-15 16:49 ` Andrea Corallo
2024-03-15 18:19 ` Tomas Hlavaty
2024-03-15 18:38 ` Eli Zaretskii
2024-03-16 13:39 ` Tomas Hlavaty
2024-03-16 14:06 ` Eli Zaretskii
2024-03-16 14:56 ` Tomas Hlavaty
2024-03-16 15:43 ` Emanuel Berg
2024-03-16 15:44 ` Eli Zaretskii
2024-03-16 15:54 ` Emanuel Berg
2024-03-18 8:55 ` Lele Gaifax
2024-03-16 0:01 ` Adam Porter
2024-03-18 9:25 ` Andrea Corallo
2024-03-26 10:13 ` Andrea Corallo
2024-03-26 10:28 ` Christopher Dimech
2024-03-26 12:55 ` Eli Zaretskii
2024-03-26 16:46 ` Andrea Corallo
2024-04-29 17:48 ` Andrea Corallo
2024-04-29 17:55 ` Stefan Monnier
2024-04-29 18:42 ` Andrea Corallo
2024-04-30 14:55 ` Eli Zaretskii
2024-04-30 18:29 ` Stefan Monnier
2024-05-01 20:57 ` Andrea Corallo
2024-05-01 21:06 ` Stefan Monnier
2024-05-02 6:16 ` Eli Zaretskii
2024-05-02 10:16 ` Andrea Corallo
2024-05-02 6:15 ` Eli Zaretskii
2024-05-02 10:12 ` Andrea Corallo
2024-05-02 11:15 ` Eli Zaretskii
2024-05-02 13:20 ` Stefan Monnier
2024-05-01 20:54 ` Andrea Corallo
2024-05-02 10:22 ` Eli Zaretskii
2024-05-02 15:18 ` Andrea Corallo
2024-05-02 16:32 ` Eli Zaretskii
2024-03-26 13:05 ` Mattias Engdegård
2024-03-26 13:44 ` Stefan Monnier
2024-03-26 14:28 ` Joost Kremers
2024-03-26 14:37 ` Stefan Monnier
-- strict thread matches above, loose matches on Subject: below --
2024-03-16 7:46 Arthur Miller
2024-03-16 15:46 ` Emanuel Berg
2024-03-18 9:02 ` Andrea Corallo
2024-03-18 9:58 ` Arthur Miller
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).