Jonathan M Davis wrote:
On Tuesday, July 20, 2010 06:36:57 Justin Johansson wrote:
Perhaps this is a philosophical question, like what is time, though it
is also a novice programmer question as well. The question exactly
being:
"What is the difference between a (constant/immutable) value and the
result of calling a side-effect free function that returns the same?"
May I please petition respondents not to answer in terms of PL syntax.
That is, this question is not about optional parentheses which some
PL's use to make values and nullary function calls look syntactical
alike.
Going beyond syntax and into semantics, does the D language have
any special "opinion" or idiom relating to constant/immutable
values versus nullary function calls?
From my observation, the Scala PL community has had similar questions
poised in the past (about the difference between val's and nullary
functions) and their answer has largely given into constraints
imposed upon Scala's implementation and semantics as are
implementable on the Java Virtual Machine (JWM).
Thanks for answers,
Justin Johansson
1. A const variable is a chunk of memory which can be read as a particular type
but not written to in that context. Optimizations may remove it in some cases.
2. An immutable variable is a chunk of memory which can be read as a particular
type and cannot be written to in any context. Optimizations may remove it in
some cases (and likely more cases than with const).
3. A manifest constant using an enum is a value of a particular type which is
reused throughout the code without being an addressable chunk of memory (though
it may still actually have an address depending on what the compiler does - you
just can't address it yourself). The value never changes and cannot be changed.
4. A pure function which takes no parameters and simply returns a value of a
particular type is not a chunk of memory. It's a procedure at a certain location
in memory, which is therefore addressable for the purposes of calling it (or
passing it around to be called). When it is run, it produces a value, and it
will always produce the same value regardless of when it is run. Optimizations
may remove the call in some cases and simply re-use the result. Also, the
function could be used in CTFE to produce the value at compile time and just use
that value instead of calling the function at runtime. Depending on how the
function is used and how much optimizing the compiler does, the function may
never get called at runtime. But it is ultimately a function rather than a
variable, which means that it is used as a function, including what that means
for addressing it. So, there _will_ be cases where it cannot be optimized out
(like if you're passing around a pointer to it and calling it through the
pointer). It is _not_ a variable. It may get optimized to the point that it's as
efficient as a variable, but then again, it might not be. And there are cases
where it acts very much like the function that it is.
- Jonathan M Davis
Thanks for your time in constructing this well-written, well-considered
and detailed answer :-) Justin