unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* force initialization of a datatype?
@ 2015-11-04 16:28 Stephen Leake
  2015-11-04 19:17 ` Dmitry Gutov
  0 siblings, 1 reply; 8+ messages in thread
From: Stephen Leake @ 2015-11-04 16:28 UTC (permalink / raw)
  To: emacs-devel

I'm working on a type that should check the user provided
inititalization values, and I'm wondering if I can do that with
cl-defstruct, or if I should use eieio defclass instead.

I'd like to ensure that the only available constructors do the
checking.

Here's what I have come up with for cl-defstruct:

(cl-defstruct (path-iterator
	       (:constructor nil)
	       (:copier nil))
  <slots>
  )

(defun make-path-iterator (<user args>)
  (let ((result (vector 'cl-struct-path-iterator <slot values>)))
    <code to check the user args and set the slots in `result'>
    ))

This code compiles and runs correctly, but I'm wondering if it is
acceptable style. Is there a better way to accomplish this for
cl-defstruct?


eieio defclass provides ":initform", which I'm guessing can specify a
function to run at object construction time, but I can't find any
definitive statement to that effect, neither in the Emacs info doc nor
via DuckDuckGo search. The lack of good documentation scares me away
from eieio in general.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: force initialization of a datatype?
  2015-11-04 16:28 force initialization of a datatype? Stephen Leake
@ 2015-11-04 19:17 ` Dmitry Gutov
  2015-11-06 11:56   ` Stephen Leake
  0 siblings, 1 reply; 8+ messages in thread
From: Dmitry Gutov @ 2015-11-04 19:17 UTC (permalink / raw)
  To: Stephen Leake, emacs-devel

On 11/04/2015 06:28 PM, Stephen Leake wrote:

> (defun make-path-iterator (<user args>)
>    (let ((result (vector 'cl-struct-path-iterator <slot values>)))
>      <code to check the user args and set the slots in `result'>
>      ))
>
> This code compiles and runs correctly, but I'm wondering if it is
> acceptable style. Is there a better way to accomplish this for
> cl-defstruct?

Using `vector' looks wrong. I'm not too familiar with constructor 
syntax, but you can process each slot value before an instance gets 
constructed. See the example with &aux in 
http://www.gnu.org/software/emacs/manual/html_node/cl/Structures.html, 
or package-desc-from-define in package.el.

I'm not sure whether you can use a keyword argument with the same name 
as the slot, and convert the passed in value. That's something to try.

> eieio defclass provides ":initform", which I'm guessing can specify a
> function to run at object construction time, but I can't find any
> definitive statement to that effect, neither in the Emacs info doc nor
> via DuckDuckGo search. The lack of good documentation scares me away
> from eieio in general.

If we're talking about xref, I think it would be generally good to 
migrate away from eieio in the core definitions. defstruct is lighter, 
and seems functional enough for our purposes.




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: force initialization of a datatype?
  2015-11-04 19:17 ` Dmitry Gutov
@ 2015-11-06 11:56   ` Stephen Leake
  2015-11-06 12:16     ` Dmitry Gutov
  0 siblings, 1 reply; 8+ messages in thread
From: Stephen Leake @ 2015-11-06 11:56 UTC (permalink / raw)
  To: Dmitry Gutov; +Cc: emacs-devel

Dmitry Gutov <dgutov@yandex.ru> writes:

> On 11/04/2015 06:28 PM, Stephen Leake wrote:
>
>> (defun make-path-iterator (<user args>)
>>    (let ((result (vector 'cl-struct-path-iterator <slot values>)))
>>      <code to check the user args and set the slots in `result'>
>>      ))
>>
>> This code compiles and runs correctly, but I'm wondering if it is
>> acceptable style. Is there a better way to accomplish this for
>> cl-defstruct?
>
> Using `vector' looks wrong. I'm not too familiar with constructor
> syntax, but you can process each slot value before an instance gets
> constructed. See the example with &aux in
> http://www.gnu.org/software/emacs/manual/html_node/cl/Structures.html,
> or package-desc-from-define in package.el.

Thanks for the pointers.

> I'm not sure whether you can use a keyword argument with the same name
> as the slot, and convert the passed in value. That's something to try.

This works:

(cl-defstruct (path-iterator
	       (:constructor nil)
	       (:constructor make-path-iterator
                (user-path &aux (path (path-iter-to-truename user-path))))
	       (:conc-name path-iter-)
	       (:copier nil))
  path ;; user-path converted to absolute directory file truenames.

(defun path-iter-to-truename (path)
...)

However, `xref-find-definitions' doesn't find `make-path-iterator', and
there's no place to put a doc string for `make-path-iterator'.

I'll see if I can fix `xref-find-definitions'.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: force initialization of a datatype?
  2015-11-06 11:56   ` Stephen Leake
@ 2015-11-06 12:16     ` Dmitry Gutov
  2015-11-07  7:05       ` Stephen Leake
  0 siblings, 1 reply; 8+ messages in thread
From: Dmitry Gutov @ 2015-11-06 12:16 UTC (permalink / raw)
  To: Stephen Leake; +Cc: emacs-devel

On 11/06/2015 01:56 PM, Stephen Leake wrote:

> However, `xref-find-definitions' doesn't find `make-path-iterator', and
> there's no place to put a doc string for `make-path-iterator'.

We might have to do with only documenting the related structures (and 
mentioning constructors there).

> I'll see if I can fix `xref-find-definitions'.

Thank you.

Speaking of elisp--xref-find-definitions, you've made some additions to 
it recently.

Could you remove the FIXME comment before it? It's kinda wrong.

Second, are you sure that elisp-xref-find-def-functions shouldn't be 
somewhere in find-func.el? And same for the new code 
elisp--xref-find-definitions that supports structs and generics.

I don't think we should deprecate find-func just yet, and it would make 
sense for M-x find-function to support defstruct functions and generics.



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: force initialization of a datatype?
  2015-11-06 12:16     ` Dmitry Gutov
@ 2015-11-07  7:05       ` Stephen Leake
  2015-11-07 16:27         ` Dmitry Gutov
  0 siblings, 1 reply; 8+ messages in thread
From: Stephen Leake @ 2015-11-07  7:05 UTC (permalink / raw)
  To: Dmitry Gutov; +Cc: emacs-devel

Dmitry Gutov <dgutov@yandex.ru> writes:

> On 11/06/2015 01:56 PM, Stephen Leake wrote:
>
>> However, `xref-find-definitions' doesn't find `make-path-iterator', and
>> there's no place to put a doc string for `make-path-iterator'.
>
> We might have to do with only documenting the related structures (and
> mentioning constructors there).
>
>> I'll see if I can fix `xref-find-definitions'.
>
> Thank you.
>
> Speaking of elisp--xref-find-definitions, you've made some additions
> to it recently.
>
> Could you remove the FIXME comment before it? It's kinda wrong.

I've had that in my local stash for a while, waiting for a significant
change to push in that file.

> Second, are you sure that elisp-xref-find-def-functions shouldn't be
> somewhere in find-func.el? 

I don't follow.

`elisp-xref-find-def-functions' is a hook that is called from
`elisp--xref-find-definitions'; why should it be in find-func?

The only file that currently puts a function on that hook is
cedet/mode-local.el; it adds similar functionality to
`help-fns-describe-function-functions' and `find-function-regexp-alist'.

> And same for the new code elisp--xref-find-definitions that supports
> structs and generics.

That code has a FIXME about moving it to
`elisp-xref-find-def-functions'; there is already code in cl-generic
that puts similar functionality on
`help-fns-describe-function-functions' and `find-function-regexp-alist'.

> I don't think we should deprecate find-func just yet, and it would
> make sense for M-x find-function to support defstruct functions and
> generics.

It does; I just tried it on some of the ones defined in
elisp-mode-tests.el.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: force initialization of a datatype?
  2015-11-07  7:05       ` Stephen Leake
@ 2015-11-07 16:27         ` Dmitry Gutov
  2015-11-07 18:30           ` Stephen Leake
  0 siblings, 1 reply; 8+ messages in thread
From: Dmitry Gutov @ 2015-11-07 16:27 UTC (permalink / raw)
  To: Stephen Leake; +Cc: emacs-devel

On 11/07/2015 09:05 AM, Stephen Leake wrote:

> I don't follow.
>
> `elisp-xref-find-def-functions' is a hook that is called from
> `elisp--xref-find-definitions'; why should it be in find-func?

It would have a different name, of course, and maybe used indirectly 
through calling some of the find-func functions. But like you mentioned, 
we already have find-function-regexp-alist.

> The only file that currently puts a function on that hook is
> cedet/mode-local.el; it adds similar functionality to
> `help-fns-describe-function-functions' and `find-function-regexp-alist'.

Why can't we reuse the contents of those variables?

I think the meat of the code that knows how to find Elisp entities 
should be in one place.

find-func seems to be the natural place for it. And elisp-xref should 
strive to provide a minimal interface over it, until we come to the 
conclusion that the info provided by find-func is definitely not rich 
enough (what we do in that case, it most likely out of scope for Emacs 25).

> That code has a FIXME about moving it to
> `elisp-xref-find-def-functions'; there is already code in cl-generic
> that puts similar functionality on
> `help-fns-describe-function-functions' and `find-function-regexp-alist'.

What if some new third-party facility adds a relevant element to 
elisp-xref-find-def-funtcions, but not find-function-regexp-alist? Or 
vice versa?

>> I don't think we should deprecate find-func just yet, and it would
>> make sense for M-x find-function to support defstruct functions and
>> generics.
>
> It does; I just tried it on some of the ones defined in
> elisp-mode-tests.el.

All right, thanks (I haven't checked, actually). My main concern is 
about the code organization.



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: force initialization of a datatype?
  2015-11-07 16:27         ` Dmitry Gutov
@ 2015-11-07 18:30           ` Stephen Leake
  2015-11-07 20:21             ` Dmitry Gutov
  0 siblings, 1 reply; 8+ messages in thread
From: Stephen Leake @ 2015-11-07 18:30 UTC (permalink / raw)
  To: Dmitry Gutov; +Cc: emacs-devel

Dmitry Gutov <dgutov@yandex.ru> writes:

> On 11/07/2015 09:05 AM, Stephen Leake wrote:
>
>> I don't follow.
>>
>> `elisp-xref-find-def-functions' is a hook that is called from
>> `elisp--xref-find-definitions'; why should it be in find-func?
>
> It would have a different name, of course, and maybe used indirectly
> through calling some of the find-func functions. But like you
> mentioned, we already have find-function-regexp-alist.
>
>> The only file that currently puts a function on that hook is
>> cedet/mode-local.el; it adds similar functionality to
>> `help-fns-describe-function-functions' and `find-function-regexp-alist'.
>
> Why can't we reuse the contents of those variables?

`help-fns-describe-function-functions' is intended to be called from
'describe-function'; it puts the results in a buffer.
`elisp-xref-find-def-functions' puts the results in a list of xrefs. So
the code is different.

`find-function-regexp-alist' is used by `find-function-search-for-symbol',
which in turn is used by `xref-location-marker ((l
xref-elisp-location))'. So we are reusing that variable.

> I think the meat of the code that knows how to find Elisp entities
> should be in one place.

The code that _finds_ elisp entities is
`find-function-search-for-symbol'; that is shared.

The rest of the code is for display. There may be some minor refactoring
opportunities, but the main differences between
`help-fns-describe-function-functions' and
`elisp-xref-find-def-functions' is that one outputs to a buffer, and the
other to a list of xrefs.

>> That code has a FIXME about moving it to
>> `elisp-xref-find-def-functions'; there is already code in cl-generic
>> that puts similar functionality on
>> `help-fns-describe-function-functions' and `find-function-regexp-alist'.
>
> What if some new third-party facility adds a relevant element to
> elisp-xref-find-def-funtcions, but not find-function-regexp-alist? Or
> vice versa?

Not all entries on `elisp-xref-find-def-functions' have a corresponding
entry in `find-function-regexp-alist'; they are not equivalent.

I think you meant `elisp-xref-find-def-functions' vs
`help-fns-describe-function-functions'; whatever xref can display,
describe-function should display, and vice versa.

A difference between the list of things xref can display and those that
describe-function can display is a bug (that includes more than just
those two lists).

There were a lot of such bugs when xref was introduced.

I've fixed some of them with `elisp-xref-find-def-functions', others
with other code in elisp--xref-find-definitions. There are still
a few remaining; see the FIXMEs in elisp-mode.el.

You seem to be suggesting that there should be a way to write one
function for both lists; that's certainly not possible.

We might be able to switch to a dispatching "display-function", with
one backend for help buffers and one for xrefs. But that does not change
the essential point that different code needs to be written for both.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: force initialization of a datatype?
  2015-11-07 18:30           ` Stephen Leake
@ 2015-11-07 20:21             ` Dmitry Gutov
  0 siblings, 0 replies; 8+ messages in thread
From: Dmitry Gutov @ 2015-11-07 20:21 UTC (permalink / raw)
  To: Stephen Leake; +Cc: emacs-devel

On 11/07/2015 08:30 PM, Stephen Leake wrote:

>> Why can't we reuse the contents of those variables?
>
> `help-fns-describe-function-functions' is intended to be called from
> 'describe-function'; it puts the results in a buffer.

Indeed, I (mistakenly) meant the other one.

> `elisp-xref-find-def-functions' puts the results in a list of xrefs. So
> the code is different.

After looking at it more, I mostly agree. It has a distinct value: 
determining additional "type-and-file" combinations corresponding to the 
symbol in question, or something along these lines. (1)

Which extend the behavior of elisp--xref-find-definitions, which 
currently iterates over variables, functions, faces and aliases.

> Not all entries on `elisp-xref-find-def-functions' have a corresponding
> entry in `find-function-regexp-alist'; they are not equivalent.

The other entries seem to have their equivalents inside the 
elisp--xref-find-definitions definition. That probably means something.

> A difference between the list of things xref can display and those that
> describe-function can display is a bug (that includes more than just
> those two lists).

What about M-x find-function not finding certain definitions that 
xref-find-definitions can? I don't exactly have a solid idea for 
improvement, but it seems like xref-mode-local-overload returns a set of 
xrefs pointing to locations that M-x find-function can't jump to.

It'll only jump to the "original" function definition, right?

 > ...
> There were a lot of such bugs when xref was introduced.
>
> I've fixed some of them with `elisp-xref-find-def-functions', others
> with other code in elisp--xref-find-definitions. There are still
> a few remaining; see the FIXMEs in elisp-mode.el.

Thank you.

The only relevant FIXME I see now mentions advised functions.

> You seem to be suggesting that there should be a way to write one
> function for both lists; that's certainly not possible.

You're right.

> We might be able to switch to a dispatching "display-function", with
> one backend for help buffers and one for xrefs. But that does not change
> the essential point that different code needs to be written for both.

Yes, we need different code to "display" the entities: convert them to 
xrefs on one side, and convert them to help buffer contents on the other 
side.

The code that produces the list of the entities, however, could be unified.

I'm not sure that help-fns-describe-function-functions is a close 
counterpart to elisp--xref-find-definitions, however (2). 
describe-symbol-backends seems to be closer to that.

(1) For that reason, the current name of this variable doesn't seem 
fitting: the functions don't find "definitions", they find distinct 
entities bearing the given name. The actual finding of definitions is 
delegated to find-func and its hooks.

(2) help-fns-describe-function-functions's purpose seems to be more 
along the lines of adding extra blurbs to the description of the same 
entity.



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2015-11-07 20:21 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-04 16:28 force initialization of a datatype? Stephen Leake
2015-11-04 19:17 ` Dmitry Gutov
2015-11-06 11:56   ` Stephen Leake
2015-11-06 12:16     ` Dmitry Gutov
2015-11-07  7:05       ` Stephen Leake
2015-11-07 16:27         ` Dmitry Gutov
2015-11-07 18:30           ` Stephen Leake
2015-11-07 20:21             ` Dmitry Gutov

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).