unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* when to call provide, first or last?
@ 2012-02-27 12:47 Le Wang
  2012-02-27 12:59 ` Juanma Barranquero
  2012-02-27 13:35 ` Stefan Monnier
  0 siblings, 2 replies; 13+ messages in thread
From: Le Wang @ 2012-02-27 12:47 UTC (permalink / raw)
  To: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 382 bytes --]

Hi,

What's the accepted idiom for calling (provide 'foo-feature)?  I picked up
the habit of calling it first in every library I write.  This way two
libraries can call functions from each other without causing a circular
dependency.

But I had a look through lisp/*.el and everything calls provide last.  Is
there some disadvantage to calling it first that I'm not seeing?

-- 
Le

[-- Attachment #2: Type: text/html, Size: 424 bytes --]

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

* Re: when to call provide, first or last?
  2012-02-27 12:47 when to call provide, first or last? Le Wang
@ 2012-02-27 12:59 ` Juanma Barranquero
  2012-02-27 13:09   ` Le Wang
  2012-02-27 13:35 ` Stefan Monnier
  1 sibling, 1 reply; 13+ messages in thread
From: Juanma Barranquero @ 2012-02-27 12:59 UTC (permalink / raw)
  To: Le Wang; +Cc: emacs-devel

On Mon, Feb 27, 2012 at 13:47, Le Wang <l26wang@gmail.com> wrote:

> Is there some disadvantage to calling it first that I'm not seeing?

Try loading this file my-feature.el:

;;; starts here
(provide 'my-feature)
)
(defun my-function ()
  "")
;;; ends here

with  emacs -Q -l my-feature.el, and you'll get:

load-with-code-conversion: Invalid read syntax: ")"

(featurep 'my-feature) => t
(fboundp 'my-function) => nil

In other words, having `provide' at the end guarantees that the
feature does not enter the feature list unless the file was correctly
loaded.

    Juanma



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

* Re: when to call provide, first or last?
  2012-02-27 12:59 ` Juanma Barranquero
@ 2012-02-27 13:09   ` Le Wang
  2012-02-27 13:25     ` Juanma Barranquero
  0 siblings, 1 reply; 13+ messages in thread
From: Le Wang @ 2012-02-27 13:09 UTC (permalink / raw)
  To: Juanma Barranquero; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 837 bytes --]

On Mon, Feb 27, 2012 at 8:59 PM, Juanma Barranquero <lekktu@gmail.com>wrote:

> On Mon, Feb 27, 2012 at 13:47, Le Wang <l26wang@gmail.com> wrote:
>
> > Is there some disadvantage to calling it first that I'm not seeing?
>
> Try loading this file my-feature.el:
>
> ;;; starts here
> (provide 'my-feature)
> )
> (defun my-function ()
>  "")
> ;;; ends here
>
> with  emacs -Q -l my-feature.el, and you'll get:
>
> load-with-code-conversion: Invalid read syntax: ")"
>
> (featurep 'my-feature) => t
> (fboundp 'my-function) => nil
>

What happens next?  You have broken code, and you're either looking at the
backtrace or you get a ding.  How is this a problem?


> In other words, having `provide' at the end guarantees that the
> feature does not enter the feature list unless the file was correctly
> loaded.
>
>     Juanma
>



-- 
Le

[-- Attachment #2: Type: text/html, Size: 1494 bytes --]

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

* Re: when to call provide, first or last?
  2012-02-27 13:09   ` Le Wang
@ 2012-02-27 13:25     ` Juanma Barranquero
  2012-02-27 13:32       ` Le Wang
  0 siblings, 1 reply; 13+ messages in thread
From: Juanma Barranquero @ 2012-02-27 13:25 UTC (permalink / raw)
  To: Le Wang; +Cc: emacs-devel

On Mon, Feb 27, 2012 at 14:08, Le Wang <l26wang@gmail.com> wrote:

>> What happens next?  You have broken code, and you're either looking at the
>> backtrace or you get a ding.  How is this a problem?

The problem is that you can miss the error, and also that (require
'my-feature) will "work" afterwards.

It's better to put it at the end and be sure that having the feature
means that everything went OK.

    Juanma



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

* Re: when to call provide, first or last?
  2012-02-27 13:25     ` Juanma Barranquero
@ 2012-02-27 13:32       ` Le Wang
  2012-02-27 13:44         ` Juanma Barranquero
  0 siblings, 1 reply; 13+ messages in thread
From: Le Wang @ 2012-02-27 13:32 UTC (permalink / raw)
  To: Juanma Barranquero; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1070 bytes --]

On Mon, Feb 27, 2012 at 9:25 PM, Juanma Barranquero <lekktu@gmail.com>wrote:

> On Mon, Feb 27, 2012 at 14:08, Le Wang <l26wang@gmail.com> wrote:
>
> >> What happens next?  You have broken code, and you're either looking at
> the
> >> backtrace or you get a ding.  How is this a problem?
>
> The problem is that you can miss the error, and also that (require
> 'my-feature) will "work" afterwards.
>

So what?  You have broken code.  Bad things happened, and Emacs is in a bad
state either way.

Are you going to fix the bug and try the require again?  If so, then you
probably know enough to know that you should use load now.  If not you're
screwed already.  Go file a bug.


>
> It's better to put it at the end and be sure that having the feature
> means that everything went OK.
>

That's not what provide means.  From the manual,
http://www.gnu.org/software/emacs/manual/html_node/elisp/Named-Features.html
:

This function announces that feature is now loaded, or being loaded, into
the current Emacs session.

NOTE: "or being loaded"



>     Juanma
>



-- 
Le

[-- Attachment #2: Type: text/html, Size: 2011 bytes --]

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

* Re: when to call provide, first or last?
  2012-02-27 12:47 when to call provide, first or last? Le Wang
  2012-02-27 12:59 ` Juanma Barranquero
@ 2012-02-27 13:35 ` Stefan Monnier
  2012-02-27 13:42   ` Le Wang
  1 sibling, 1 reply; 13+ messages in thread
From: Stefan Monnier @ 2012-02-27 13:35 UTC (permalink / raw)
  To: Le Wang; +Cc: emacs-devel

> What's the accepted idiom for calling (provide 'foo-feature)?  I picked up
> the habit of calling it first in every library I write.  This way two
> libraries can call functions from each other without causing a circular
> dependency.

Actually, such mutual dependencies aren't desirable: sometimes they're
hard to avoid so we prefer to live with them, but that doesn't change
the fact that they're not good.

Putting the provide at the end makes sure that if featurep says t, then
it means thatthe feature is actually available, whereas if it's at the
beginning, featurep returning t only mean "we've started to lead the
feature, and well, maybe we've actually loaded it all by now, but I'm
not sure".

The difference is sufficiently unimportant to deserve bikeshedding,
I guess, but in any case, the convention is to put it at the end.
Like every convention, there can be exceptional circumstances that
justify doing it differently, but they have to be exceptional rather
than only based on taste.


        Stefan



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

* Re: when to call provide, first or last?
  2012-02-27 13:35 ` Stefan Monnier
@ 2012-02-27 13:42   ` Le Wang
  2012-02-27 14:25     ` Stefan Monnier
  2012-02-27 15:08     ` Harald Hanche-Olsen
  0 siblings, 2 replies; 13+ messages in thread
From: Le Wang @ 2012-02-27 13:42 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1105 bytes --]

On Mon, Feb 27, 2012 at 9:35 PM, Stefan Monnier <monnier@iro.umontreal.ca>wrote:

> Actually, such mutual dependencies aren't desirable


Can you elaborate on this a little?  In my mind if two files implement
different parts of the same libraby, it's quite natural for mutual
dependencies to occur.


> : sometimes they're
> hard to avoid so we prefer to live with them, but that doesn't change
> the fact that they're not good.
>
> Putting the provide at the end makes sure that if featurep says t, then
> it means thatthe feature is actually available, whereas if it's at the
> beginning, featurep returning t only mean "we've started to lead the
> feature, and well, maybe we've actually loaded it all by now, but I'm
> not sure".
>
> The difference is sufficiently unimportant to deserve bikeshedding,
>

cool word -> bikeshedding


> I guess, but in any case, the convention is to put it at the end.
> Like every convention, there can be exceptional circumstances that
> justify doing it differently, but they have to be exceptional rather
> than only based on taste.
>
>
>        Stefan
>



-- 
Le

[-- Attachment #2: Type: text/html, Size: 1825 bytes --]

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

* Re: when to call provide, first or last?
  2012-02-27 13:32       ` Le Wang
@ 2012-02-27 13:44         ` Juanma Barranquero
  2012-02-27 13:57           ` Le Wang
  0 siblings, 1 reply; 13+ messages in thread
From: Juanma Barranquero @ 2012-02-27 13:44 UTC (permalink / raw)
  To: Le Wang; +Cc: emacs-devel

On Mon, Feb 27, 2012 at 14:32, Le Wang <l26wang@gmail.com> wrote:

> So what?  You have broken code.  Bad things happened, and Emacs is in a bad
> state either way.

No, sorry. One package failing to load does not necessarily leave
"Emacs in a bad state", at least not in theory. That's why
ignore-errors, condition-case and (require x nil t) exist, for
example.

Your way makes a bit more difficult to detect the problem, and a bit
more likely that it will be missed and subsequent requires fail
without warning.

But, hey, it's your code, put it whenever you think it's right.

> This function announces that feature is now loaded, or being loaded, into the current Emacs session.
>
> NOTE: "or being loaded"

Right. And using your method, you can have a feature that does not
mean that the code is loaded or being loaded.

    Juanma



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

* Re: when to call provide, first or last?
  2012-02-27 13:44         ` Juanma Barranquero
@ 2012-02-27 13:57           ` Le Wang
  2012-02-27 14:05             ` Drew Adams
  0 siblings, 1 reply; 13+ messages in thread
From: Le Wang @ 2012-02-27 13:57 UTC (permalink / raw)
  To: Juanma Barranquero; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1231 bytes --]

On Mon, Feb 27, 2012 at 9:44 PM, Juanma Barranquero <lekktu@gmail.com>wrote:

> On Mon, Feb 27, 2012 at 14:32, Le Wang <l26wang@gmail.com> wrote:
>
> > So what?  You have broken code.  Bad things happened, and Emacs is in a
> bad
> > state either way.
>
> No, sorry. One package failing to load does not necessarily leave
> "Emacs in a bad state", at least not in theory. That's why
> ignore-errors, condition-case and (require x nil t) exist, for
> example.
>

So predictable exceptions are handled by those functions already.  But now
things are just borked.


> Your way makes a bit more difficult to detect the problem, and a bit
> more likely that it will be missed and subsequent requires fail
> without warning.
>

This is a valid point.

But, hey, it's your code, put it whenever you think it's right.
>

Sure.  I'm just trying to clarify what the idiomatic way to use it is.
Maybe a summary of this discussion should be in the manual?


> > This function announces that feature is now loaded, or being loaded,
> into the current Emacs session.
> >
> > NOTE: "or being loaded"
>
> Right. And using your method, you can have a feature that does not
> mean that the code is loaded or being loaded.
>
>     Juanma
>



-- 
Le

[-- Attachment #2: Type: text/html, Size: 2221 bytes --]

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

* RE: when to call provide, first or last?
  2012-02-27 13:57           ` Le Wang
@ 2012-02-27 14:05             ` Drew Adams
  0 siblings, 0 replies; 13+ messages in thread
From: Drew Adams @ 2012-02-27 14:05 UTC (permalink / raw)
  To: 'Le Wang', 'Juanma Barranquero'; +Cc: emacs-devel

 
> I'm just trying to clarify what the idiomatic way to use it is.

Put it last, EXCEPT for this situation described in section `(elisp) Named
Features': 

 "Although top-level calls to `require' are evaluated during byte
  compilation, `provide' calls are not.  Therefore, you can ensure that a
  file of definitions is loaded before it is byte-compiled by including a
  `provide' followed by a `require' for the same feature, as in the
  following example.

     (provide 'my-feature)  ; Ignored by byte compiler,
                            ;   evaluated by `load'.
     (require 'my-feature)  ; Evaluated by byte compiler.

  The compiler ignores the `provide', then processes the `require' by
  loading the file in question.  Loading the file does execute the
  `provide' call, so the subsequent `require' call does nothing when the
  file is loaded."

> Maybe a summary of this discussion should be in the manual?

Consider filing a doc bug, after you've reread pertinent parts of the manual and
are still convinced that improvement is in order.





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

* Re: when to call provide, first or last?
  2012-02-27 13:42   ` Le Wang
@ 2012-02-27 14:25     ` Stefan Monnier
  2012-02-27 15:08     ` Harald Hanche-Olsen
  1 sibling, 0 replies; 13+ messages in thread
From: Stefan Monnier @ 2012-02-27 14:25 UTC (permalink / raw)
  To: Le Wang; +Cc: emacs-devel

>> Actually, such mutual dependencies aren't desirable
> Can you elaborate on this a little?  In my mind if two files implement
> different parts of the same libraby, it's quite natural for mutual
> dependencies to occur.

It's actually rare.  Most program decompositions result in *layering*,
with no or very few mutual recursions.  Mutual recursions also can be
tricky: it's easy to get ill-founded recursions if you're not
paying attention.

Even more so if you're only testing your code in "interpreted" mode,
since the byte-compiler will execute the top-level code (especially
macro-expansions) in a different order, so the problem may not appear in
your testing.

Again, nothing terribly important to rule out such things, but enough to
discourage them.


        Stefan



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

* Re: when to call provide, first or last?
  2012-02-27 13:42   ` Le Wang
  2012-02-27 14:25     ` Stefan Monnier
@ 2012-02-27 15:08     ` Harald Hanche-Olsen
  2012-02-27 15:46       ` Le Wang
  1 sibling, 1 reply; 13+ messages in thread
From: Harald Hanche-Olsen @ 2012-02-27 15:08 UTC (permalink / raw)
  To: emacs-devel

[Le Wang <l26wang@gmail.com> (2012-02-27 13:42:34 UTC)]

> cool word -> bikeshedding

Google it. http://bikeshed.org/ is a classic. A must-read.

- Harald



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

* Re: when to call provide, first or last?
  2012-02-27 15:08     ` Harald Hanche-Olsen
@ 2012-02-27 15:46       ` Le Wang
  0 siblings, 0 replies; 13+ messages in thread
From: Le Wang @ 2012-02-27 15:46 UTC (permalink / raw)
  To: Harald Hanche-Olsen; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 463 bytes --]

On Mon, Feb 27, 2012 at 11:08 PM, Harald Hanche-Olsen
<hanche@math.ntnu.no>wrote:

> [Le Wang <l26wang@gmail.com> (2012-02-27 13:42:34 UTC)]
>
> > cool word -> bikeshedding
> Google it. http://bikeshed.org/ is a classic. A must-read.
>
>
I read it.  Thanks!  This will allow me to accurately identify bikeshedding
in others!

I kid of course.  It's pretty embarrassing how much bikeshedding I do.
Knowing is only half the battle, I guess.


- Harald
>
>


-- 
Le

[-- Attachment #2: Type: text/html, Size: 1123 bytes --]

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

end of thread, other threads:[~2012-02-27 15:46 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-02-27 12:47 when to call provide, first or last? Le Wang
2012-02-27 12:59 ` Juanma Barranquero
2012-02-27 13:09   ` Le Wang
2012-02-27 13:25     ` Juanma Barranquero
2012-02-27 13:32       ` Le Wang
2012-02-27 13:44         ` Juanma Barranquero
2012-02-27 13:57           ` Le Wang
2012-02-27 14:05             ` Drew Adams
2012-02-27 13:35 ` Stefan Monnier
2012-02-27 13:42   ` Le Wang
2012-02-27 14:25     ` Stefan Monnier
2012-02-27 15:08     ` Harald Hanche-Olsen
2012-02-27 15:46       ` Le Wang

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