On using `=` vs `:=` for assignment

news to me

There’s abundant evidence out there in the wild, if you care to look. The sentiment is probably changing. But if you go back far enough, there was a time when most mathematicians had never programmed a computer, and = for assignment was vigorously objected to. In equations a = b does not mean “give a the value of b”, not even slightly.

7 Likes

I did my undergrad in math. There are all sorts of different conventions people follow and I never once saw anybody (professor or student) make a big stink about using :=.

what’s more common is probably to just say let x =

There’s little point in fighting the last generation’s battle, the convention can no longer be dislodged. My high school computer programming teacher made a point of explaining that Pascal (which was the instruction language) does this ‘correctly’ by using := for assignment, and was dismissive of other languages which use = for assignment and == for equality.

Though that battle was lost, this doesn’t mean it was never fought.

7 Likes

Now I know where MathCad uses this same terminology for assignment!

2 Likes

Then you have Python that assigns with both = and :=, the latter usually qualified as the walrus operator in “named expressions”, the difference being the former isn’t a valid subexpression with a value and the latter is more like Julia’s = but it doesn’t support many things like chained assignment or indexing to avoid usage overlap with the former.

1 Like

If we used := for assignment and = for equality test, then we would have consistency with respect to operator negation (= and !=, and == and !== for identity test). And then a !<op> b could be the same as !(a <op> b) for all infix operstors: ! for infix operators · Issue #25512 · JuliaLang/julia · GitHub

6 Likes

I would have no objections if Julia had picked := for assignment, right at the beginning. But I expect I’m in the minority in that. Most developers would see that as unnecessary visual noise, with an old-fashioned flavor, and would find it off-putting. The meaning of = and == is part of the common language of programming now, and mathematical purity is a bad reason to frustrate developers.

Regardless, there’s no chance a change like that will ever happen, I would guess that one in three lines of Julia have an assignment on them. My favorite choice for assignment is <-, but it introduces parse ambiguity for statements like i<-7. Alas.

There’s actually nothing preventing if i = 7 ... from meaning equality, it’s a parse error now. But that’s yet another change where I can’t imagine getting a consensus behind it. You’d still need == for things like a = b == 4. I’d vote for allowing = to mean equality in if expressions if it ever came up, fwiw, while understanding why having two ways to spell == has never caught on.

7 Likes

I’m not advocating for changing the assignment operator, I’m saying how great := would have been, in an ideal dream world.

5 Likes

Note that this parse error is just a very fragile and easy to fool check trying to help people avoid making a common mistake.

julia> let i = 10
           if i = true
               i
           end
       end
ERROR: ParseError:
# Error @ REPL[7]:2:10
let i = 10
    if i = true
#        ╙ ── unexpected `=`

vs

julia> let i = 10
           if (i = true)
               i
           end
       end
true
3 Likes

Personally I find := abhorrent. It reminds me of Pascal.

6 Likes

Ah, yes. The first programming language I tried (and failed) to learn. They nailed the assignment operator though :grin:, and it’s what I use for pseudocode, and even sometimes in maths.

4 Likes

A lot of constructs in Julia remind me of Pascal and its descendants. Type declarations in Pascal are name : type, in Julia name :: type, which I wrote in a maximally-Pascalesque fashion (I believe name:Type would be legal Pascal, although I haven’t used it this century). One-based indexing, end as a block terminator, begin .. end for explicit blocks, t isa Type vs. Oberon’s t IS Type, function for a procedure which returns a value (ditching procedure itself was wise). struct syntax is more like a Pascal record than a C struct. Even some esoterica like arrays storing their length, and strings being backed by an array (hence also length encoded, obviously without the unduly restrictive 255 character limit, which most languages in the Pascal family dropped).

Syntactically, Julia clearly belongs to the Wirth school of languages, not the Bell Labs school, a decision I much prefer.

Go manages to use := without pissing people off, although with a different meaning, it distinguishes a declaration from an assignment.

But I think Julia made the right choice using = for assignment. It’s less about := in my opinion, than it is about ==. The comparison operators Julia chose are practically universal in modern languages, and if = meant ==, then clearly == would have to mean ===, so a typo would end up using a comparison operator which is much more restrictive than intended, that’s a good way to upset developers. If one isn’t going to use the freed token, there is little point in freeing it.

Plus when one is used to = for assignment, := just imposes extra typing and visual noise to no benefit. As I said in the last post, I would have no objections if Julia had gone that route, but I guarantee you people would complain about it frequently.

Might be worth observing that a 2.0 Julia could add := for a declaration. Perhaps not “you must declare with :=” but rather “you may use := to insist on a declaration”, that would do a few nice things: the compiler could throw an error if such a name were already in the same scope, it would resolve the edge-case issues of scope which currently call for local, basically it could serve as a lightweight replacement for local but with different and more useful behavior in the top scope.

Maybe even mandatory, that would require every Julia file in existence to be rewritten but in a way which a program could do correctly. After all, the compiler is already identifying declarations and reassignments, adding a rewrite based on that is not difficult. Making the programmer annotate “this is a new variable” eliminates a lot of subtle bugs, and makes it easier to read a program for the first time as well.

But I like the philosophy of Julia that it’s a dynamic language which one can progressively annotate for correctness and performance, making explicit declaration opt-in might be more in keeping with that.

4 Likes

Just a historical note: the whatever ... end block delimiters were present in Algol 60, which Wirth had little to do with. It is more correct to say that Wirth’s languages were influenced by the latter than the other way around.

Yes, Julia’s surface syntax borrows a lot from Fortran and Algol, just like every language outside the Lisp family today (consider for, if, etc). So does C and its descendants, with the major change of delimiting blocks with {}.

3 Likes

Just a historical note: := is from Algol 60 as well. So if you hate Pascal you should hate Algol 60 for consistency :wink:

What you say is of course correct, but it’s not so useful for discussing language families: the Wirth languages conserved these language elements, while the Bell Labs school did not. They share Algol as a common ancestor. I often enough refer to ‘Algolic’ languages when contrasting the syntax with, for example, Lisps.

6 Likes

I don’t dislike Pascal because of :=, I care very little about particular syntax choices in any computer language. It’s just that := triggers memories of being taught programming in high school using Turbo Pascal which I consider totally inappropriate for that task: it is very “structured” in the B&D sense, but all that achieves is requiring a ton of boilerplate to accomplish simple tasks. This makes it a sort of anti-Lisp. (I consider Julia a Lisp, with M-expression syntax to trick the uninitiated who place too much emphasis on syntax :stuck_out_tongue_winking_eye:).

I never had any interaction with Algol 60, so I don’t emotionally relate to that language :wink:

4 Likes

Turbo Pascal was my first language, second if we count writing 20 GOTO 10 sorts of BASIC programs. But I taught it to myself a year or two before it was used as the instruction language in AP Computer Science, so my associations with it are largely positive. I would even argue that it’s a better teaching language than Java, which replaced it. But this is a low bar.

I would think Julia would make a lovely first language, although for teaching purposes I would choose Lua for the first year. Julia is a big language, which is all to the good, but for teaching one wants a small language, at least at first. Lua is minimalist but powerful, suitable for teaching algorithms without complicating this with data structures. Since there is somewhat of an obligation to teach students what objects are, given that the paradigm is still prevalent, Lua is a great language for teaching them, because they aren’t a language feature, they’re just another way to use tables. One could easily teach the entire language to high school students in a single year, including a few weeks on the implementation and userdata system, as a crash-course introduction to C.

The transition from Lua to Julia is very smooth, I can testify from first-hand experience, since I was using Lua professionally before embarking on the path of Julia. The only issue I see from a pedagogical standpoint is that Julia’s type system is eccentric in a way which would spoil the students for other languages. I’d call that a good thing, however.

4 Likes

Using := for assignment seems to me problematic because of interpretation from theory papers of := as definition. Assignment is in some sense the opposite of definition, as the L-value is mutating.

Having said that, a different operator for assignment feels like a good idea. What about <- . Perhaps this would help rope in a few R users as well.

1 Like

Y’all, can we please try to stick to the topics at hand? Thread splits like these can be messy and just aren’t as cohesive as intentionally-started topics — and this is now a split topic from a split topic from a split topic.

2 Likes

Is that not the point of having the splitting feature? Conversations have a tendency to drift, and it’s seldom obvious in advance that an offhand comment related to the topic will turn into its own discussion. For this thread, the topic was how assignment behaves. I made an offhand, but on-topic, observation, that = means equality and not assignment in maths, which lead to this thread.

It’s great that you split it off, that keeps the original threads topical but leaves a link so someone who wants to read the full evolution can do so. The alternative is doing that manually, which would take a crystal ball: In some parallel world there was one or two comments about :=, which wouldn’t be out of place in the original topic thread, and that was all.

Us mere users can’t gather up posts and bundle them into a new topic, so starting a different thread once it’s clear that we’ve drifted into some new interest means posting a new thread, posting a link to it in the old thread, and posting a link to the old thread so people can catch up on the conversation. This is an inferior version of what the moderators do anyway in breaking a thread off.

I recognize that it’s extra work in what can be a thankless task already. Does moderation have permissions fine-grained enough that you could deputize a few regulars to have the thread-split functionality without the more powerful (and abusable) moderator privileges which go with it? Because I don’t think lecturing people about staying on topic will be effective, topics change, which is why the thread-splitting power is so useful to begin with.