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