[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: global vars and #:declarative? (was [critical bug] The set! doesn't
From: |
Taylan Kammer |
Subject: |
Re: global vars and #:declarative? (was [critical bug] The set! doesn't work in indirect reference) |
Date: |
Thu, 19 Sep 2024 17:33:23 +0200 |
User-agent: |
Mozilla Thunderbird |
On 19.09.2024 14:30, Nala Ginrut wrote:
> Although I mostly put global var like global parameters in such a module, I
> think there's always something that needs a globally setter.
> The parameter works when you could get the state first in the runtime,
> then you can bind it with pameterize. But for the case that you have to
> call another function first, then check the state change or not, the easier
> way is to take advantage of side-effects.
Parameter objects can also be set permanently by calling them on a value:
scheme@(guile-user)> (define x (make-parameter 1))
scheme@(guile-user)> (x 2)
$1 = 1
scheme@(guile-user)> (x)
$2 = 2
(Note that, when calling it to change the value, it returns the previous value.)
I'm not sure if there's ever a really good reason to use mutable global
variables instead of parameters.
Perhaps reading a variable is more efficient than reading a parameter's value.
Usually, that's going to be an unnecessary micro-optimization. But even if such
an optimization were needed, one could just bind the value of a parameter to a
local variable where needed:
(let ((value (my-parameter)))
(loop-a-million-times
(lambda () (do-something-with value))))
If I'm not mistaken: Using a local variable is often more efficient than using
a global variable, so if you needed to micro-optimize code for maximum
efficiency, you would want to do this anyway.
There's one potential issue with using parameters like this: Their value is
thread-local. If you change a parameter's value from one thread, with the
setting syntax above (calling it on a value), it will never become visible to
other threads that are currently executing. However, setting it before spawning
a new thread will ensure that the new thread sees the new value:
scheme@(guile-user)> (x 3)
$5 = 2
scheme@(guile-user)> (join-thread (begin-thread (x)))
$6 = 3
scheme@(guile-user)> (join-thread (begin-thread (x 4) (x)))
$7 = 4
scheme@(guile-user)> (x)
$8 = 3
Hope that helps!
- Taylan