all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Any disadvantages of using put/get instead of defvar?
@ 2014-02-20 17:04 Oleh
  2014-02-20 22:24 ` Tassilo Horn
  0 siblings, 1 reply; 14+ messages in thread
From: Oleh @ 2014-02-20 17:04 UTC (permalink / raw
  To: help-gnu-emacs

Hi all,

I've asked this question on stack overflow and it was suggested that I
ask it here as well.

The situation is that I have a function that uses one global variable.
It's for sure that no other function will want this variable.
In an effort to have all code in one place I want to move from:

    (defvar bar-foo 1)

    ;; bunch of other code

    (defun bar ()
      ;; use bar-foo here
      )

to:


    (defun bar ()
      (let ((foo (or (get 'bar 'foo) 1)))
        ;; use foo here
        ))

So the advantage is that I can move and rename the function
without worry that the function/variable coupling will break,
because now everything is inside one function.

I realize that the variable can still be accessed from outside, but
that doesn't matter much.

One disadvantage listed in the responses was that now the variable
can't be buffer-local any more.

Any other disadvantages to this method?

regards,
Oleh



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

* Re: Any disadvantages of using put/get instead of defvar?
  2014-02-20 17:04 Any disadvantages of using put/get instead of defvar? Oleh
@ 2014-02-20 22:24 ` Tassilo Horn
  2014-02-21  1:40   ` Stefan Monnier
  2014-02-21  9:12   ` Oleh
  0 siblings, 2 replies; 14+ messages in thread
From: Tassilo Horn @ 2014-02-20 22:24 UTC (permalink / raw
  To: Oleh; +Cc: help-gnu-emacs

Oleh <ohwoeowho@gmail.com> writes:

> The situation is that I have a function that uses one global variable.
> It's for sure that no other function will want this variable.  In an
> effort to have all code in one place I want to move from:
>
>     (defvar bar-foo 1)
>     (defun bar ()
>       ;; use bar-foo here
>       )
>
> to:
>
>     (defun bar ()
>       (let ((foo (or (get 'bar 'foo) 1)))
>         ;; use foo here
>         ))
>
> So the advantage is that I can move and rename the function without
> worry that the function/variable coupling will break, because now
> everything is inside one function.

You could also define the variable inside the function, i.e., that's a
buffer-local counter:

  (defun counter ()
    (defvar counter-var 1)
    (setq-local counter-var (1+ counter-var)))

Bye,
Tassilo



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

* Re: Any disadvantages of using put/get instead of defvar?
  2014-02-20 22:24 ` Tassilo Horn
@ 2014-02-21  1:40   ` Stefan Monnier
  2014-02-21 10:29     ` Nicolas Richard
  2014-02-21 11:49     ` Tassilo Horn
  2014-02-21  9:12   ` Oleh
  1 sibling, 2 replies; 14+ messages in thread
From: Stefan Monnier @ 2014-02-21  1:40 UTC (permalink / raw
  To: help-gnu-emacs

> You could also define the variable inside the function, i.e., that's a
> buffer-local counter:
>   (defun counter ()
>     (defvar counter-var 1)
>     (setq-local counter-var (1+ counter-var)))

I'd recommend against it.  Its semantics is pretty much the same as

   (defun counter ()
     (defvar counter-var 1)
     (setq-local counter-var (1+ counter-var)))

except that `counter-var' will only be defined after the first call to
`counter'.

And no, it's not buffer-local.


        Stefan




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

* Re: Any disadvantages of using put/get instead of defvar?
  2014-02-20 22:24 ` Tassilo Horn
  2014-02-21  1:40   ` Stefan Monnier
@ 2014-02-21  9:12   ` Oleh
  2014-02-21  9:39     ` Tassilo Horn
  1 sibling, 1 reply; 14+ messages in thread
From: Oleh @ 2014-02-21  9:12 UTC (permalink / raw
  To: Tassilo Horn; +Cc: help-gnu-emacs

>> The situation is that I have a function that uses one global variable.
>> It's for sure that no other function will want this variable.  In an
>> effort to have all code in one place I want to move from:
>>
>>     (defvar bar-foo 1)
>>     (defun bar ()
>>       ;; use bar-foo here
>>       )
>>
>> to:
>>
>>     (defun bar ()
>>       (let ((foo (or (get 'bar 'foo) 1)))
>>         ;; use foo here
>>         ))
>>
>> So the advantage is that I can move and rename the function without
>> worry that the function/variable coupling will break, because now
>> everything is inside one function.
>
> You could also define the variable inside the function, i.e., that's a
> buffer-local counter:
>
>   (defun counter ()
>     (defvar counter-var 1)
>     (setq-local counter-var (1+ counter-var)))
>

Thanks, Tassilo,

But doesn't `defvar` introduce overhead this way?

I've looked at `(symbol-function 'counter)` and `(byte-compile 'counter)`
and it seems that it does.

regards,
Oleh



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

* Re: Any disadvantages of using put/get instead of defvar?
  2014-02-21  9:12   ` Oleh
@ 2014-02-21  9:39     ` Tassilo Horn
  2014-02-21  9:44       ` Oleh
  2014-02-21  9:51       ` Andreas Röhler
  0 siblings, 2 replies; 14+ messages in thread
From: Tassilo Horn @ 2014-02-21  9:39 UTC (permalink / raw
  To: Oleh; +Cc: help-gnu-emacs

Oleh <ohwoeowho@gmail.com> writes:

>>> The situation is that I have a function that uses one global variable.
>>> It's for sure that no other function will want this variable.  In an
>>> effort to have all code in one place I want to move from:
>>>
>>>     (defvar bar-foo 1)
>>>     (defun bar ()
>>>       ;; use bar-foo here
>>>       )
>>>
>>> to:
>>>
>>>     (defun bar ()
>>>       (let ((foo (or (get 'bar 'foo) 1)))
>>>         ;; use foo here
>>>         ))
>>>
>>> So the advantage is that I can move and rename the function without
>>> worry that the function/variable coupling will break, because now
>>> everything is inside one function.
>>
>> You could also define the variable inside the function, i.e., that's a
>> buffer-local counter:
>>
>>   (defun counter ()
>>     (defvar counter-var 1)
>>     (setq-local counter-var (1+ counter-var)))
>>
>
> Thanks, Tassilo,
>
> But doesn't `defvar` introduce overhead this way?

Well, I've measured my counter above versus a version using symbol
properties as you suggest:

  (defun bar ()
    (let ((foo (or (get 'bar 'foo) 1)))
      (put 'bar 'foo (1+ foo))))

My counter is way faster although it uses defvar and setq-local, so that
overhead is still small compared to looking up/putting a symbol
property.

Bye,
Tassilo



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

* Re: Any disadvantages of using put/get instead of defvar?
  2014-02-21  9:39     ` Tassilo Horn
@ 2014-02-21  9:44       ` Oleh
  2014-02-21  9:51       ` Andreas Röhler
  1 sibling, 0 replies; 14+ messages in thread
From: Oleh @ 2014-02-21  9:44 UTC (permalink / raw
  To: Tassilo Horn; +Cc: help-gnu-emacs

>> But doesn't `defvar` introduce overhead this way?
>
> Well, I've measured my counter above versus a version using symbol
> properties as you suggest:
>
>   (defun bar ()
>     (let ((foo (or (get 'bar 'foo) 1)))
>       (put 'bar 'foo (1+ foo))))
>
> My counter is way faster although it uses defvar and setq-local, so that
> overhead is still small compared to looking up/putting a symbol
> property.
>

Thanks, your suggestion wins then, since it's both pretty and fast.
If there's no new info in this issue, I'll just use your mehtod.

regards,
Oleh



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

* Re: Any disadvantages of using put/get instead of defvar?
  2014-02-21  9:39     ` Tassilo Horn
  2014-02-21  9:44       ` Oleh
@ 2014-02-21  9:51       ` Andreas Röhler
  2014-02-21  9:56         ` Sebastian Wiesner
                           ` (2 more replies)
  1 sibling, 3 replies; 14+ messages in thread
From: Andreas Röhler @ 2014-02-21  9:51 UTC (permalink / raw
  To: help-gnu-emacs

Am 21.02.2014 10:39, schrieb Tassilo Horn:
> Oleh <ohwoeowho@gmail.com> writes:
>
>>>> The situation is that I have a function that uses one global variable.
>>>> It's for sure that no other function will want this variable.  In an
>>>> effort to have all code in one place I want to move from:
>>>>
>>>>      (defvar bar-foo 1)
>>>>      (defun bar ()
>>>>        ;; use bar-foo here
>>>>        )
>>>>
>>>> to:
>>>>
>>>>      (defun bar ()
>>>>        (let ((foo (or (get 'bar 'foo) 1)))
>>>>          ;; use foo here
>>>>          ))
>>>>
>>>> So the advantage is that I can move and rename the function without
>>>> worry that the function/variable coupling will break, because now
>>>> everything is inside one function.
>>>
>>> You could also define the variable inside the function, i.e., that's a
>>> buffer-local counter:
>>>
>>>    (defun counter ()
>>>      (defvar counter-var 1)
>>>      (setq-local counter-var (1+ counter-var)))
>>>
>>
>> Thanks, Tassilo,
>>
>> But doesn't `defvar` introduce overhead this way?
>
> Well, I've measured my counter above versus a version using symbol
> properties as you suggest:
>
>    (defun bar ()
>      (let ((foo (or (get 'bar 'foo) 1)))
>        (put 'bar 'foo (1+ foo))))
>
> My counter is way faster although it uses defvar and setq-local, so that
> overhead is still small compared to looking up/putting a symbol
> property.
>

BTW in earlier times a "let" was used.
IIUC the way to make a function-local value now is "defvar" inside?




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

* Re: Any disadvantages of using put/get instead of defvar?
  2014-02-21  9:51       ` Andreas Röhler
@ 2014-02-21  9:56         ` Sebastian Wiesner
  2014-02-21 11:56         ` Tassilo Horn
       [not found]         ` <mailman.15678.1392983787.10748.help-gnu-emacs@gnu.org>
  2 siblings, 0 replies; 14+ messages in thread
From: Sebastian Wiesner @ 2014-02-21  9:56 UTC (permalink / raw
  To: Andreas Röhler; +Cc: help-gnu-emacs

Am 21.02.2014 10:47 schrieb "Andreas Röhler" <andreas.roehler@easy-emacs.de
>:
>
> Am 21.02.2014 10:39, schrieb Tassilo Horn:
>
>> Oleh <ohwoeowho@gmail.com> writes:
>>
>>>>> The situation is that I have a function that uses one global variable.
>>>>> It's for sure that no other function will want this variable.  In an
>>>>> effort to have all code in one place I want to move from:
>>>>>
>>>>>      (defvar bar-foo 1)
>>>>>      (defun bar ()
>>>>>        ;; use bar-foo here
>>>>>        )
>>>>>
>>>>> to:
>>>>>
>>>>>      (defun bar ()
>>>>>        (let ((foo (or (get 'bar 'foo) 1)))
>>>>>          ;; use foo here
>>>>>          ))
>>>>>
>>>>> So the advantage is that I can move and rename the function without
>>>>> worry that the function/variable coupling will break, because now
>>>>> everything is inside one function.
>>>>
>>>>
>>>> You could also define the variable inside the function, i.e., that's a
>>>> buffer-local counter:
>>>>
>>>>    (defun counter ()
>>>>      (defvar counter-var 1)
>>>>      (setq-local counter-var (1+ counter-var)))
>>>>
>>>
>>> Thanks, Tassilo,
>>>
>>> But doesn't `defvar` introduce overhead this way?
>>
>>
>> Well, I've measured my counter above versus a version using symbol
>> properties as you suggest:
>>
>>    (defun bar ()
>>      (let ((foo (or (get 'bar 'foo) 1)))
>>        (put 'bar 'foo (1+ foo))))
>>
>> My counter is way faster although it uses defvar and setq-local, so that
>> overhead is still small compared to looking up/putting a symbol
>> property.
>>
>
> BTW in earlier times a "let" was used.
> IIUC the way to make a function-local value now is "defvar" inside?

Not if the value should persist across invocations of the function.


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

* Re: Any disadvantages of using put/get instead of defvar?
  2014-02-21  1:40   ` Stefan Monnier
@ 2014-02-21 10:29     ` Nicolas Richard
  2014-02-21 13:57       ` Stefan Monnier
  2014-02-21 11:49     ` Tassilo Horn
  1 sibling, 1 reply; 14+ messages in thread
From: Nicolas Richard @ 2014-02-21 10:29 UTC (permalink / raw
  To: Stefan Monnier; +Cc: help-gnu-emacs

>> You could also define the variable inside the function, i.e., that's a
>> buffer-local counter:
>>   (defun counter ()
>>     (defvar counter-var 1)
>>     (setq-local counter-var (1+ counter-var)))
>
> I'd recommend against it.  Its semantics is pretty much the same as
>
>    (defun counter ()
>      (defvar counter-var 1)
>      (setq-local counter-var (1+ counter-var)))

Did you mean this instead ?

   (defvar counter-var 1)
   (defun counter ()
     (setq-local counter-var (1+ counter-var)))


-- 
Nico.



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

* Re: Any disadvantages of using put/get instead of defvar?
  2014-02-21  1:40   ` Stefan Monnier
  2014-02-21 10:29     ` Nicolas Richard
@ 2014-02-21 11:49     ` Tassilo Horn
  2014-02-21 14:41       ` Stefan Monnier
  1 sibling, 1 reply; 14+ messages in thread
From: Tassilo Horn @ 2014-02-21 11:49 UTC (permalink / raw
  To: Stefan Monnier; +Cc: help-gnu-emacs

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> You could also define the variable inside the function, i.e., that's a
>> buffer-local counter:
>>   (defun counter ()
>>     (defvar counter-var 1)
>>     (setq-local counter-var (1+ counter-var)))
>
> I'd recommend against it.  Its semantics is pretty much the same as
>
>    (defun counter ()
>      (defvar counter-var 1)
>      (setq-local counter-var (1+ counter-var)))
>
> except that `counter-var' will only be defined after the first call to
> `counter'.

Sure (I guess you mean with the defvar before the defun), but Oleh's
goal was not to have the variable and the function separated.

> And no, it's not buffer-local.

Well, it becomes buffer-local as soon as someone calls `counter'.

Bye,
Tassilo



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

* Re: Any disadvantages of using put/get instead of defvar?
  2014-02-21  9:51       ` Andreas Röhler
  2014-02-21  9:56         ` Sebastian Wiesner
@ 2014-02-21 11:56         ` Tassilo Horn
       [not found]         ` <mailman.15678.1392983787.10748.help-gnu-emacs@gnu.org>
  2 siblings, 0 replies; 14+ messages in thread
From: Tassilo Horn @ 2014-02-21 11:56 UTC (permalink / raw
  To: Andreas Röhler; +Cc: help-gnu-emacs

Andreas Röhler <andreas.roehler@easy-emacs.de> writes:

>> Well, I've measured my counter above versus a version using symbol
>> properties as you suggest:
>>
>>    (defun bar ()
>>      (let ((foo (or (get 'bar 'foo) 1)))
>>        (put 'bar 'foo (1+ foo))))
>>
>> My counter is way faster although it uses defvar and setq-local, so that
>> overhead is still small compared to looking up/putting a symbol
>> property.
>>
>
> BTW in earlier times a "let" was used.
> IIUC the way to make a function-local value now is "defvar" inside?

No, not at all.  `defvar' creates a global variable, no matter where
it's called.  Oleh's goal was just to keep a global variable and
function together, because that function is the only one using the
variable.

Another way would be

  (progn
    (defvar bar-foo 0)
    (defun bar ()
      ;; do stuff with bar-foo
      ))

which has the possible benefit that bar-foo is defined as soon as the
file is loaded instead being undefined until the first `bar' call.  And
the wrapping in a `progn' probably reduces the chance that you move
`bar' somewhere and forget `bar-foo'.

Bye,
Tassilo



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

* Re: Any disadvantages of using put/get instead of defvar?
       [not found]         ` <mailman.15678.1392983787.10748.help-gnu-emacs@gnu.org>
@ 2014-02-21 13:45           ` Helmut Eller
  0 siblings, 0 replies; 14+ messages in thread
From: Helmut Eller @ 2014-02-21 13:45 UTC (permalink / raw
  To: help-gnu-emacs

On Fri, Feb 21 2014, Tassilo Horn wrote:

> Another way would be
>
>   (progn
>     (defvar bar-foo 0)
>     (defun bar ()
>       ;; do stuff with bar-foo
>       ))
>
> which has the possible benefit that bar-foo is defined as soon as the
> file is loaded instead being undefined until the first `bar' call.  And
> the wrapping in a `progn' probably reduces the chance that you move
> `bar' somewhere and forget `bar-foo'.

With lexical-binding

(let ((foo 0))
  (defun bar ()
    ...))

is also an option.  This has the advantage that it uses the shortest
names and foo is actually a lexically scoped variable that is not
accessible outside of bar.  One disadvantage is that it's not possible to
look at foo, say for debugging purposes.

Helmut


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

* Re: Any disadvantages of using put/get instead of defvar?
  2014-02-21 10:29     ` Nicolas Richard
@ 2014-02-21 13:57       ` Stefan Monnier
  0 siblings, 0 replies; 14+ messages in thread
From: Stefan Monnier @ 2014-02-21 13:57 UTC (permalink / raw
  To: help-gnu-emacs

> Did you mean this instead ?
>    (defvar counter-var 1)
>    (defun counter ()
>      (setq-local counter-var (1+ counter-var)))

Uh... right, sorry,


        Stefan




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

* Re: Any disadvantages of using put/get instead of defvar?
  2014-02-21 11:49     ` Tassilo Horn
@ 2014-02-21 14:41       ` Stefan Monnier
  0 siblings, 0 replies; 14+ messages in thread
From: Stefan Monnier @ 2014-02-21 14:41 UTC (permalink / raw
  To: Tassilo Horn; +Cc: help-gnu-emacs

> Sure (I guess you mean with the defvar before the defun), but Oleh's
> goal was not to have the variable and the function separated.

If he wants to keep state between invocations of the function, then that
state has to be external (logically) to the function.  So it is best to
reflect this syntactically by making the variable external as well.

If you want it syntactically "closer", you can put it between the
function's name and the function itself (so it's still outside the
function, but at the same time, it's still within the overall
definition):

  (defalias 'counter
    (let ((counter 1))
      (lambda () (setq counter (1+ counter)))))

Of course, this relies on lexical-binding and is not buffer-local.


        Stefan



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

end of thread, other threads:[~2014-02-21 14:41 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-02-20 17:04 Any disadvantages of using put/get instead of defvar? Oleh
2014-02-20 22:24 ` Tassilo Horn
2014-02-21  1:40   ` Stefan Monnier
2014-02-21 10:29     ` Nicolas Richard
2014-02-21 13:57       ` Stefan Monnier
2014-02-21 11:49     ` Tassilo Horn
2014-02-21 14:41       ` Stefan Monnier
2014-02-21  9:12   ` Oleh
2014-02-21  9:39     ` Tassilo Horn
2014-02-21  9:44       ` Oleh
2014-02-21  9:51       ` Andreas Röhler
2014-02-21  9:56         ` Sebastian Wiesner
2014-02-21 11:56         ` Tassilo Horn
     [not found]         ` <mailman.15678.1392983787.10748.help-gnu-emacs@gnu.org>
2014-02-21 13:45           ` Helmut Eller

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.