Most active commenters
  • tialaramex(4)
  • ajross(4)

←back to thread

498 points azhenley | 15 comments | | HN request time: 0.563s | source | bottom
Show context
anymouse123456 ◴[] No.45771965[source]
I completely agree with the assertion and the benefits that ensue, but my attention is always snagged by the nomenclature.

I know there are alternate names available to us, but even in the context of this very conversation (and headline), the thing is being called a "variable."

What is a "variable" if not something that varies?

replies(14): >>45772017 #>>45772042 #>>45772062 #>>45772077 #>>45772262 #>>45772625 #>>45773368 #>>45773945 #>>45774039 #>>45775594 #>>45775669 #>>45775698 #>>45775911 #>>45776839 #
1. tialaramex ◴[] No.45772062[source]
In the cases we're interested in here the variable does vary, what it doesn't do is mutate.

Suppose I have a function which sums up all the prices of products in a cart, the total so far will frequently mutate, that's fine. In Rust we need to mark this variable "mut" because it will be mutated as each product's price is added.

After calculating this total, we also add $10 shipping charge. That's a constant, we're (for this piece of code) always saying $10. That's not a variable it's a constant. In Rust we'd use `const` for this but in C you need to use the C pre-processor language instead to make constants, which is kinda wild.

However for each time this function runs we do also need to get the customer ID. The customer ID will vary each time this function runs, as different customers check out their purchases, but it does not mutate during function execution like that total earlier, in Rust these variables don't need an annotation, this is the default. In C you'd ideally want to label these "const" which is the confusing name C gives to immutable variables.

replies(3): >>45772342 #>>45773930 #>>45776499 #
2. ajross ◴[] No.45772342[source]
> In the cases we're interested in here the variable does vary, what it doesn't do is mutate.

Those are synonyms, and this amounts to a retcon. The computer science term "variable" comes directly from standard mathematical function notation, where a variable reflects a quantity being related by the function to other variables. It absolutely is expected to "change", if not across "time" than across the domain of the function being expressed. Computers are discrete devices and a variable that "varies" across its domain inherently implies that it's going to be computed more than once. The sense Carmack is using, where it is not recomputed and just amounts to a shorthand for a longer expression, is a poor fit.

I do think this is sort of a wart in terminology, and the upthread post is basically right that we've been using this wrong for years.

If I ever decide to inflict a static language on the masses, the declaration keywords will be "def" (to define a constant expression) and "var" (to define a mutable/variable quantity). Maybe there's value in distinguishing a "var" declaration from a "mut" reference and so maybe those should have separate syntaxes.

replies(2): >>45772976 #>>45773131 #
3. IshKebab ◴[] No.45772976[source]
Well maybe global constants shouldn't be called "variables", but I don't see how your definition excludes local immutable variables from being called "variables". E.g.

  fn sin(x: f64) -> f64 {
    let x2 = x / PI;
    ...
Is x2 not variable? It's value varies depending on how I assign x.

Anyway this is kind of pointless arguing. We use the word "variable". It's fine.

4. zahlman ◴[] No.45773131[source]
> Those are synonyms, and this amounts to a retcon.

The point is that it varies between calls to a function, rather than within a call. Consider, for example, a name for a value which is a pure function (in the mathematical sense) of the function's (in the CS sense) inputs.

replies(1): >>45773228 #
5. ajross ◴[] No.45773228{3}[source]
Or between iterations of the loop scope in which it's defined, const/immutable definitions absolutely change during the execution of a function. I understand the nitpicky argument, I just think it's kinda dumb. It's a transparent attempt to justify jargon that we all know is needlessly confusing.
replies(1): >>45773456 #
6. tialaramex ◴[] No.45773456{4}[source]
Ah! Actually this idea that the immutable variables in a loop "change during execution" is a serious misunderstanding and some languages have tripped themselves up and had to fix it later when they baked this mistake into the language.

What's happening is that each iteration of the loop these are new variables but they have the same name, they're not the same variables with a different value. When a language designer assumes that's the same thing the result is confusing for programmers and so it usually ends up requiring a language level fix.

e.g. "In C# 5, the loop variable of a foreach will be logically inside the loop"

replies(1): >>45773872 #
7. ajross ◴[] No.45773872{5}[source]
Seems like you're coming around to my side of the fence that calling these clearly distinct constant expressions "variables" is probably a mistake?
replies(1): >>45774125 #
8. barisozmen ◴[] No.45773930[source]
Even if the term 'variable' has roots in math where it is acceptable that it might not mutate, I think for clarity, the naming should be different. It's uneasy to think about something that can vary but not mutate. More clear names can be found.
9. tialaramex ◴[] No.45774125{6}[source]
I don't think so? I've been clear that there are three distinct kinds of thing here - constants, immutable variables, and mutable variables.

In C the first needs us to step outside the language to the macro pre-processor, the second needs the keyword "const" and the third is the default

In Rust the first is a const, the second we can make with let and the third we need let mut, as Carmack says immutable should be the default.

replies(1): >>45774658 #
10. ajross ◴[] No.45774658{7}[source]
There are surely more than three! References can support mutation or not, "constants" may be runtime or compile time.

The point is that the word "variable" inherently reflects change. And choosing it (a-la your malapropism-that-we-all-agree-not-to-notice "immutable variables") to mean something that does (1) is confusing and (2) tends to force us into worse choices[1][2] elsewhere.

A "variable" should reflect the idea of something that can be assigned.

[1] In rust, the idea of something that can change looks like a misspelled dog, and is pronounced so as to imply that it can't speak!

[2] In C++, they threw English out the window and talk about "lvalues" for this idea.

replies(1): >>45782658 #
11. tredre3 ◴[] No.45776499[source]
> In Rust we'd use `const` for this but in C you need to use the C pre-processor language instead to make constants, which is kinda wild.

I get that you're not very familiar with C? Because in C we'd use const as well.

    const int x = 2;
    x = 3; // error: assignment of read-only variable 'x'
replies(2): >>45777534 #>>45777589 #
12. superblas ◴[] No.45777534[source]
Perhaps they’re conflating how you can’t use “const” as a compile time constant (e.g., you can’t declare the size of an array with a “const” variable). If so, C23 solves this by finally getting the constexpr keyword from c++
13. tialaramex ◴[] No.45777589[source]
That's not a constant, that's an immutable variable which is why your diagnostic said it was read-only.

   const int x = 2;
   int *p = &x;
   *p = 3; // Now x is 3
And since I paid for the place where I'm writing this with cash earned writing C a decade or so ago, I think we can rule out "unfamiliar with C" as a symptom.
replies(1): >>45787212 #
14. kelipso ◴[] No.45782658{8}[source]
The term variable is from math is 100s (probably) of years old. Variables in pure functional languages are used exactly the same way it’s used in math. The idea of mutating and non-mutating variable is pretty old too and used in math as well. Neither are going to change.
15. tredre3 ◴[] No.45787212{3}[source]
Now x is 3 but you also get a compiler warning telling you not to do that.

In my opinion it's a bit disingenuous to argue that it isn't a const just because you can ignore the compiler and shoot yourself in the foot. If you listen to the compiler, it is reflected in the assembly that it is a constant value the same as #define x 2.

Is Rust better at enforcing guarantees? Of course. Is `const` in C `const` if you don't ignore compiler warnings and errors? Also of course.

> And since I paid for the place where I'm writing this with cash earned writing C a decade or so ago

Ditto!