bug#23486: 25.0.93; Modules: features missing from make_function

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

bug#23486: 25.0.93; Modules: features missing from make_function

Philipp Stephani

emacs_env::make_function lacks the following features supported by
`defun':

1. Functions with both optional and rest arguments.
2. Specification of parameter names.
3. Integration with `help-function-arglist'.
4. Specification of interactive forms.
5. Specification of declare forms.
6. Docstrings containing null or non-Unicode characters.

(6) is probably rather unimportant.  (5) is probably not implementable
(would require wrapping `defun', not `lambda').  (1)–(4) are more severe
and quite limit the usefulness of make_function right now; for a
truly generic `defun'-like construct one currently has to eval a `defun'
form wrapping another function.

To solve (1)–(3), I'd propose replacing the "arity" arguments with a
true arglist specification.  This could either be at the C level, e.g.

    ptrdiff_t num_mandatory_args, char** mandatory_arg_names,
    ptrdiff_t num_optional_args, char** optional_arg_names,
    char* rest_arg_name

or by requiring to pass a Lisp argument list.

To solve (4) I'd propose to pass another value for the interactive form,
probably as emacs_value* (to support non-interactive functions).

As an alternative, if people feel this would require too many
parameters, I'd propose reverting the change that adds the documentation
string.  A docstring without arglist is not very useful.  We could also
remove the arity parameters and have the C function check the arity
itself.



In GNU Emacs 25.0.93.5 (x86_64-unknown-linux-gnu, GTK+ Version 3.10.8)
 of 2016-04-24 built on localhost
Repository revision: 0cd2e923dba8d8c7128b0c084ce6af22069e8db5
Windowing system distributor 'The X.Org Foundation', version 11.0.11501000
System Description: Ubuntu 14.04 LTS

Configured using:
 'configure --with-modules'

Configured features:
XPM JPEG TIFF GIF PNG SOUND GSETTINGS NOTIFY FREETYPE XFT ZLIB
TOOLKIT_SCROLL_BARS GTK3 X11 MODULES

Important settings:
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix

Major mode: Lisp Interaction

Minor modes in effect:
  tooltip-mode: t
  global-eldoc-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  tool-bar-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  line-number-mode: t
  transient-mark-mode: t

Recent messages:
For information about GNU Emacs and the GNU system, type C-h C-a.

Load-path shadows:
None found.

Features:
(shadow sort mail-extr emacsbug message dired format-spec rfc822 mml
mml-sec password-cache epg epg-config gnus-util mm-decode mm-bodies
mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader sendmail
rfc2047 rfc2045 ietf-drums mm-util help-fns help-mode easymenu
cl-loaddefs pcase cl-lib mail-prsvr mail-utils time-date mule-util
tooltip eldoc electric uniquify ediff-hook vc-hooks lisp-float-type
mwheel x-win term/common-win x-dnd tool-bar dnd fontset image regexp-opt
fringe tabulated-list newcomment elisp-mode lisp-mode prog-mode register
page menu-bar rfn-eshadow timer select scroll-bar mouse jit-lock
font-lock syntax facemenu font-core frame cl-generic cham georgian
utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean
japanese eucjp-ms cp51932 hebrew greek romanian slovak czech european
ethiopic indian cyrillic chinese charscript case-table epa-hook
jka-cmpr-hook help simple abbrev minibuffer cl-preloaded nadvice
loaddefs button faces cus-face macroexp files text-properties overlay
sha1 md5 base64 format env code-pages mule custom widget
hashtable-print-readable backquote inotify dynamic-setting
system-font-setting font-render-setting move-toolbar gtk x-toolkit x
multi-tty make-network-process emacs)

Memory information:
((conses 16 88004 8077)
 (symbols 48 19855 0)
 (miscs 40 325 197)
 (strings 32 14723 4466)
 (string-bytes 1 436825)
 (vectors 16 12084)
 (vector-slots 8 438946 3946)
 (floats 8 164 12)
 (intervals 56 202 0)
 (buffers 976 12)
 (heap 1024 36386 931))

--
Google Germany GmbH
Erika-Mann-Straße 33
80636 München

Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg
Geschäftsführer: Matthew Scott Sucherman, Paul Terence Manicle

Diese E-Mail ist vertraulich.  Wenn Sie nicht der richtige Adressat sind,
leiten Sie diese bitte nicht weiter, informieren Sie den Absender und löschen
Sie die E-Mail und alle Anhänge.  Vielen Dank.

This e-mail is confidential.  If you are not the right addressee please do not
forward it, please inform the sender, and please erase this e-mail including
any attachments.  Thanks.



Reply | Threaded
Open this post in threaded view
|

bug#23486: 25.0.93; Modules: features missing from make_function

Philipp Stephani


Philipp Stephani <[hidden email]> schrieb am Mo., 9. Mai 2016 um 18:39 Uhr:

emacs_env::make_function lacks the following features supported by
`defun':

1. Functions with both optional and rest arguments.
2. Specification of parameter names.
3. Integration with `help-function-arglist'.
4. Specification of interactive forms.
5. Specification of declare forms.
6. Docstrings containing null or non-Unicode characters.

(6) is probably rather unimportant.  (5) is probably not implementable
(would require wrapping `defun', not `lambda').  (1)–(4) are more severe
and quite limit the usefulness of make_function right now; for a
truly generic `defun'-like construct one currently has to eval a `defun'
form wrapping another function.

To solve (1)–(3), I'd propose replacing the "arity" arguments with a
true arglist specification.  This could either be at the C level, e.g.

    ptrdiff_t num_mandatory_args, char** mandatory_arg_names,
    ptrdiff_t num_optional_args, char** optional_arg_names,
    char* rest_arg_name

or by requiring to pass a Lisp argument list.

I've attached a patch for fixing (1)-(4) and (6). 

0001-Introduce-new-module-function-make_function_ext.patch (10K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

bug#23486: 25.0.93; Modules: features missing from make_function

Noam Postavsky-2
In reply to this post by Philipp Stephani
Philipp Stephani <[hidden email]> writes:

> emacs_env::make_function lacks the following features supported by
> `defun':
>
> 1. Functions with both optional and rest arguments.
> 2. Specification of parameter names.
> 3. Integration with `help-function-arglist'.
> 4. Specification of interactive forms.
> 5. Specification of declare forms.
> 6. Docstrings containing null or non-Unicode characters.
>
> (6) is probably rather unimportant.  (5) is probably not implementable
> (would require wrapping `defun', not `lambda').  (1)–(4) are more severe
> and quite limit the usefulness of make_function right now; for a
> truly generic `defun'-like construct one currently has to eval a `defun'
> form wrapping another function.

Shouldn't modules be providing a DEFUN-like construct instead?  That is,
I thought the idea of modules was to enable writing primitive
subroutines.

>
> To solve (1)–(3), I'd propose replacing the "arity" arguments with a
> true arglist specification.  This could either be at the C level, e.g.
>
>     ptrdiff_t num_mandatory_args, char** mandatory_arg_names,
>     ptrdiff_t num_optional_args, char** optional_arg_names,
>     char* rest_arg_name
>
> or by requiring to pass a Lisp argument list.
>
> To solve (4) I'd propose to pass another value for the interactive form,
> probably as emacs_value* (to support non-interactive functions).
>
> As an alternative, if people feel this would require too many
> parameters, I'd propose reverting the change that adds the documentation
> string.  A docstring without arglist is not very useful.  We could also
> remove the arity parameters and have the C function check the arity
> itself.

I think adding "(fn ARG1 ARG2...)" to the docstring would solve (1)-(3).
What's lacking is a way to add this automagically like DEFUN does.  And
getting the parameters in C variables like DEFUN would also be nice.



Reply | Threaded
Open this post in threaded view
|

bug#23486: 25.0.93; Modules: features missing from make_function

Philipp Stephani


<[hidden email]> schrieb am So., 11. Sep. 2016 um 16:56 Uhr:
Philipp Stephani <[hidden email]> writes:

> emacs_env::make_function lacks the following features supported by
> `defun':
>
> 1. Functions with both optional and rest arguments.
> 2. Specification of parameter names.
> 3. Integration with `help-function-arglist'.
> 4. Specification of interactive forms.
> 5. Specification of declare forms.
> 6. Docstrings containing null or non-Unicode characters.
>
> (6) is probably rather unimportant.  (5) is probably not implementable
> (would require wrapping `defun', not `lambda').  (1)–(4) are more severe
> and quite limit the usefulness of make_function right now; for a
> truly generic `defun'-like construct one currently has to eval a `defun'
> form wrapping another function.

Shouldn't modules be providing a DEFUN-like construct instead?  That is,
I thought the idea of modules was to enable writing primitive
subroutines.

I don't know what the idea of modules originally was. However, defun and DEFUN are composite operations: They create a function object (lambda) and provide an alias for it. Therefore they can't replace the more primitive operations. The current module interface design chooses to provide the primitive operation to make a function object and have the caller call defalias. That's a reasonable choice.
 

>
> To solve (1)–(3), I'd propose replacing the "arity" arguments with a
> true arglist specification.  This could either be at the C level, e.g.
>
>     ptrdiff_t num_mandatory_args, char** mandatory_arg_names,
>     ptrdiff_t num_optional_args, char** optional_arg_names,
>     char* rest_arg_name
>
> or by requiring to pass a Lisp argument list.
>
> To solve (4) I'd propose to pass another value for the interactive form,
> probably as emacs_value* (to support non-interactive functions).
>
> As an alternative, if people feel this would require too many
> parameters, I'd propose reverting the change that adds the documentation
> string.  A docstring without arglist is not very useful.  We could also
> remove the arity parameters and have the C function check the arity
> itself.

I think adding "(fn ARG1 ARG2...)" to the docstring would solve (1)-(3).

That doesn't work, because Emacs ignores this syntax when the arguments are provided explicitly, and since a module function is just a (lambda (&rest args) ...) under the hood, the arglist is always just (&rest args).
 
What's lacking is a way to add this automagically like DEFUN does.  And
getting the parameters in C variables like DEFUN would also be nice.

Maybe, but not for the module interface. The module interface explicitly only provides basic primitives, without macro magic or high-level functions. High-level functionality built on top of the primitives is out of scope. 
Reply | Threaded
Open this post in threaded view
|

bug#23486: 25.0.93; Modules: features missing from make_function

Noam Postavsky-2
Philipp Stephani <[hidden email]> writes:

>
>>  I think adding "(fn ARG1 ARG2...)" to the docstring would solve (1)-(3).
>
> That doesn't work, because Emacs ignores this syntax when the
> arguments are provided explicitly, and since a module function is just
> a (lambda (&rest args) ...) under the hood, the arglist is always just
> (&rest args).

I don't know what you mean here.

    (defun foo (&rest args)
      "Do foo.

    \(fn ARG1 ARG2)")

<f1> f foo RET gives

    foo is a Lisp function.

    (foo ARG1 ARG2)

    Do foo.



Reply | Threaded
Open this post in threaded view
|

bug#23486: 25.0.93; Modules: features missing from make_function

Philipp Stephani


<[hidden email]> schrieb am So., 26. März 2017 um 22:21 Uhr:
Philipp Stephani <[hidden email]> writes:

>
>>  I think adding "(fn ARG1 ARG2...)" to the docstring would solve (1)-(3).
>
> That doesn't work, because Emacs ignores this syntax when the
> arguments are provided explicitly, and since a module function is just
> a (lambda (&rest args) ...) under the hood, the arglist is always just
> (&rest args).

I don't know what you mean here.

    (defun foo (&rest args)
      "Do foo.

    \(fn ARG1 ARG2)")

<f1> f foo RET gives

    foo is a Lisp function.

    (foo ARG1 ARG2)

    Do foo.

OK, that one works, but others don't (e.g. help-function-arglist). The argument names should be transparent, without having to use such tricks. 
Reply | Threaded
Open this post in threaded view
|

bug#23486: 25.0.93; Modules: features missing from make_function

Noam Postavsky-2
In reply to this post by Philipp Stephani
Philipp Stephani <[hidden email]> writes:

> As an alternative, if people feel this would require too many
> parameters, I'd propose reverting the change that adds the documentation
> string.  A docstring without arglist is not very useful.  We could also
> remove the arity parameters and have the C function check the arity
> itself.

Looking at this a bit closer, I do think this adds too many parameters,
and in particular, requiring to pass in names for positional parameters
just makes no sense.  The names are never used (except for displaying
documentation).

But removing the docstring is not great.  IMO, the right solution here
is to use a subr-like object instead of a lambda, as suggested in a
FIXME in emacs-module.c:

  /* FIXME: Use a bytecompiled object, or even better a subr.  */

Then the arity could be checked with `subr-arity' or similar.



Reply | Threaded
Open this post in threaded view
|

bug#23486: 25.0.93; Modules: features missing from make_function

Philipp Stephani


<[hidden email]> schrieb am Mo., 27. März 2017 um 05:56 Uhr:
Philipp Stephani <[hidden email]> writes:

> As an alternative, if people feel this would require too many
> parameters, I'd propose reverting the change that adds the documentation
> string.  A docstring without arglist is not very useful.  We could also
> remove the arity parameters and have the C function check the arity
> itself.

Looking at this a bit closer, I do think this adds too many parameters,
and in particular, requiring to pass in names for positional parameters
just makes no sense.  The names are never used (except for displaying
documentation).

But removing the docstring is not great.  IMO, the right solution here
is to use a subr-like object instead of a lambda, as suggested in a
FIXME in emacs-module.c:

  /* FIXME: Use a bytecompiled object, or even better a subr.  */

Then the arity could be checked with `subr-arity' or similar.

This is now done (commit 31fded0370c3aa6d2c4370cae21cdb7475873483). This fixes (1) through (3). (4) through (6) are still open. That's probably OK if the limitations are documented; modules can always do the equivalent of (eval '(defun ...)) to get complete support. 
Reply | Threaded
Open this post in threaded view
|

bug#23486: 25.0.93; Modules: features missing from make_function

Noam Postavsky-2
Philipp Stephani <[hidden email]> writes:

> This is now done (commit
> 31fded0370c3aa6d2c4370cae21cdb7475873483). This fixes (1) through
> (3). (4) through (6) are still open. That's probably OK if the
> limitations are documented; modules can always do the equivalent of
> (eval ' (defun ...)) to get complete support.

Lisp_Subr's have an intspec field (4), but I agree it's not really
essential.  As I think you mentioned in the OP, supporting `declare' (5)
is not doable by definition (because the effects of 'declare' operate on
the symbol, not the function object).

Docstrings containing null or non-Unicode characters (6) just seems
completely pointless to me.  Are there any cases using that capability
in Emacs (or outside Emacs)?  I would probably consider them as bugs.



Reply | Threaded
Open this post in threaded view
|

bug#23486: 25.0.93; Modules: features missing from make_function

Lars Ingebrigtsen
[hidden email] writes:

> Philipp Stephani <[hidden email]> writes:
>
>> This is now done (commit
>> 31fded0370c3aa6d2c4370cae21cdb7475873483). This fixes (1) through
>> (3). (4) through (6) are still open. That's probably OK if the
>> limitations are documented; modules can always do the equivalent of
>> (eval ' (defun ...)) to get complete support.
>
> Lisp_Subr's have an intspec field (4), but I agree it's not really
> essential.  As I think you mentioned in the OP, supporting `declare' (5)
> is not doable by definition (because the effects of 'declare' operate on
> the symbol, not the function object).
>
> Docstrings containing null or non-Unicode characters (6) just seems
> completely pointless to me.  Are there any cases using that capability
> in Emacs (or outside Emacs)?  I would probably consider them as bugs.

This was the final message in this thread.  Philipp's patch fixed the
main problems, and (5) and (6) doesn't sound like something that
can/should be fixed.  Which leaves (4), which didn't seem essential,
either.

So is there more to be done here, or should this bug report be closed?

--
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no



Reply | Threaded
Open this post in threaded view
|

bug#23486: 25.0.93; Modules: features missing from make_function

Lars Ingebrigtsen
Philipp Stephani <[hidden email]> writes:

> I'd still like to fix (4), just for completeness's sake. How about
> introducing {get,set}_interactive_spec, just like
> {get,set}_function_finalizer?

Sure, sounds logical to me.

--
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no



Reply | Threaded
Open this post in threaded view
|

bug#23486: 25.0.93; Modules: features missing from make_function

Philipp Stephani
Am So., 13. Sept. 2020 um 15:20 Uhr schrieb Lars Ingebrigtsen <[hidden email]>:
>
> Philipp Stephani <[hidden email]> writes:
>
> > I'd still like to fix (4), just for completeness's sake. How about
> > introducing {get,set}_interactive_spec, just like
> > {get,set}_function_finalizer?
>
> Sure, sounds logical to me.
>

OK, I've added something similar to master as commit da0e75e741.