<h1>Assignment is bad</h1>
<p>This is basically the functional language position.
And much of Backus landmark <a href="https://www.google.com/url?sa=t&amp;source=web&amp;rct=j&amp;url=https://dl.acm.org/ft_gateway.cfm%3Fid%3D1283933%26type%3Dpdf&amp;ved=2ahUKEwj4kfCOuInsAhUJzTgGHaRTCpQQFjAAegQICxAC&amp;usg=AOvVaw2CJCimPqlvybGfpxgk5oK2" rel="nofollow noreferrer">Turing award</a>
remains relevant nearly 50 years on.<br />
We could rehash those arguments if we wish; but it's good to have something like the Backus TAL as a point of departure for that.</p>
<h1>Mutation</h1>
<p>Mutation often looks like assignment but is worse</p>
<p>A small Python session showing</p>
<ul>
<li>no assignment</li>
<li>assignment,</li>
<li>mutating function</li>
<li>mutating assignment</li>
</ul>
<h1>Session</h1>
<pre><code> # Functional behavior; no assignment/mutation no problems
&gt;&gt;&gt; a = [1,2,3]
&gt;&gt;&gt; c = [a,a]
&gt;&gt;&gt; c
[[1, 2, 3], [1, 2, 3]]
&gt;&gt;&gt; a+[4]
[1, 2, 3, 4]
&gt;&gt;&gt; c
[[1, 2, 3], [1, 2, 3]] # unchanged

# Assignment; but still harmless
&gt;&gt;&gt; a =[1,2,3]
&gt;&gt;&gt; c = [a,a]
&gt;&gt;&gt; c
[[1, 2, 3], [1, 2, 3]]
&gt;&gt;&gt; a = a + [4]
&gt;&gt;&gt; a
[1, 2, 3, 4] # changed as expected 
&gt;&gt;&gt; c
[[1, 2, 3], [1, 2, 3]] #unchanged as expected 
&gt;&gt;&gt;

#append looks like + but it actually mutates
&gt;&gt;&gt; a = [1,2,3]
&gt;&gt;&gt; c = [a,a]
&gt;&gt;&gt; c
[[1, 2, 3], [1, 2, 3]]
&gt;&gt;&gt; c[0].append(4)
&gt;&gt;&gt; c
[[1, 2, 3, 4], [1, 2, 3, 4]]
# Note how changing c[0] changed c[1]
# ie the unholy alliance between aliasing&amp;mutation

&gt;&gt;&gt; d = [[1,2,3] for i in [1,2]]
&gt;&gt;&gt; d
# A d which looks just like c
[[1, 2, 3], [1, 2, 3]]
&gt;&gt;&gt; d[0].append(4)
&gt;&gt;&gt; d
[[1, 2, 3, 4], [1, 2, 3]]
# But changing c[0] doesn't change c[1]
# ie different aliasing


&gt;&gt;&gt; a = [1,2,3]
&gt;&gt;&gt; c = [a,a]
&gt;&gt;&gt; a[:] = [4,5] # mutation note the ':'
&gt;&gt;&gt; c
[[4, 5], [4, 5]]  # WHAZZAT! 
</code></pre>
<h1>What do I recommend</h1>
<h2>1st choice</h2>
<p>Use a language like Haskell -- no assignment, no mutation.<br />
Or at least Scheme/ML where these are mostly not used</p>
<h2>2nd choice</h2>
<p>Use a language like Python as a &quot;functional assembly language&quot;.<br />
ie Use it like a functional language; don't teach mention append/extend etc the mutating methods.
When some smart Alec comes up using these break his code in the above paradigm!</p>
<p>This is what I often end up doing.</p>
<h2>3rd choice</h2>
<p>Teach all the mess and confuse the students</p>

CC BY-SA 4.0
2020-09-28T12:05:29.560Z
Programming is confusing and it is a big responsibility, like driving a car or dealing with finances. Someday, we will not have those things anymore, but for now we do. Hiding stuff from people does nothing to help them learn and grow. Teach the two hard things immediately and get them nailed down flat from the very beginning.
Scott Rowe
CC BY-SA 4.0
2020-09-28T13:44:00.393Z
Well we'll have agree to disagree on that @Scottrowe We're in 2020. Quite apart from the fact that functional P is now no more ivory-tower : eg clojure, scala, erlang etc, even mainstream imperative/OO are changing course See this microsoft doc Note the "note" «Better to use immutable value types.» What is this other than «Try to program functionally when possible?» https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/value-types
Rushi
CC BY-SA 4.0
2020-09-29T08:20:31.580Z
Python portfolio of examples could be extended with `a += [4]` (mutation)
Aivar Paalberg
CC BY-SA 4.0
2020-09-29T08:59:49.450Z
@aivaarpaalberg yeah sure: "a = a + [4]" assigns to a whereas "a += [4]" mutates a. There are zillions (OK dozens ) of such gotchas waiting the unwary. So what's the point you're making? I'm not sure. My point was (1) to answer why mutation is a problem (2) and worse than assignmentt. eg the well-known [mutable default args](https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments) is (from a pragmatic pov) v important. My point was more philosophic : with all these gotchas why are we teaching? And what exactly are we teaching?
Rushi
CC BY-SA 4.0
2020-09-29T09:05:13.433Z
@ScottRowe thinks these things important. I don't. Not sure where you (aivaarpaalberg) stand on this. And hey that's fine There's 7 billion of us on this spinning rock!
Rushi
CC BY-SA 4.0
2020-09-29T10:19:24.017Z
Programming languages are made by the people for the people. Programming languages tend to reflect it the same way as the spoken languages. One must know that 'cat has nine lives' shouldn't be taken literally and person saying that has not lost touch with reality :-). My native language has no future tense, no gender pronouns, no definite/indefinite articles etc, but I try to use them when I speak english, russian or spanish (unfortunately often forgetting to use them or using improperly). This is not the fault of these languages - this is my fault not knowing or practicing language enough.
Aivar Paalberg
CC BY-SA 4.0
2020-09-29T11:48:22.203Z
@Aivarpaalberg Interesting comment. Isn't the opposite equally true, viz. There are things you can say in Estonian (I'm assuming that's your native language) which you cannot convey with the same nuance and finesse in any other?
Rushi
CC BY-SA 4.0
2020-09-30T15:54:07.417Z
@AivarPaalberg I like your comment on how languages vary. I simply think that we must teach the aspects of computers that do not vary, the aspects that are always true, independent of language. Otherwise, it would be like trying to teach about gender pronouns (as you mentioned), without ever knowing or saying what gender is. Let's begin teaching by stating what is. It really is not that complicated: there is assignment / mutation, and there is indirection. That is what makes a computer, a computer. Nothing more, nothing less than those 2 things.
Scott Rowe
CC BY-SA 4.0
2021-08-31T07:29:39.190Z
I total agree, but find the terminology a bit confusing: What do you mean by assignment?
ctrl-alt-delor
CC BY-SA 4.0
2021-09-02T01:22:12.760Z
@ctrl-alt-delor Assignment means storing a new value in a variable (memory location). Computers can only do 5 things: fetch, store, arithmetic, compare, branch. Indirect Reference is the other major thing, which modifes the fetch and store operations. If you know of anything else that a CPU can do, please say.
Scott Rowe
CC BY-SA 4.0
2021-09-02T05:44:35.170Z
@scottrowe I was asking the author. I know what I think it means, but when reading the answer, I wondered what the author meant.
ctrl-alt-delor
CC BY-SA 4.0
2021-09-02T12:47:35.313Z
@scottrowe "homonym" and "synonym" are not synonyms!! When you treat them as such you paint yourself into a corner. Math-variable and program-variable are similar sounding merely by happenstance. See the comments below https://cseducators.stackexchange.com/q/7037/8837 particularly Bob Harper's differentiation of "assignable" — the programming concept — from "variable" — the math one. Also SolomonSlow's comments are remarkably bullseye
Rushi
CC BY-SA 4.0
2021-09-02T12:54:29.863Z
There's more that needs be said here but as I told @ctrl-alt-delor cant do it now due to some challenges. Hope to return at some point.
Rushi
CC BY-SA 4.0
2020-09-27T13:33:18.027Z
2020-10-11T13:37:05.240Z
2020-10-11T13:37:05.240Z
Rushi
<p>I personally teach mutation almost immediately.  However, I agree with Buffy that <em>more difficult</em> is not really the metric people are using to decide to teach mutation later.  It is about giving certain key habits a chance to grow and develop before you get there.</p>

<p>Most people find recursion naturally more difficult than a loop.  There is no reason why this must be, and folks who learned recursion first will often find the difficult one to be the standard imperative loop.  If you begin a student in a programming world without mutability, what habits will grow?</p>

<p>Certainly recursion will come quite naturally.  So will linked lists and trees.  And certain sloppy habits will be naturally avoided, such as this balderdash:</p>

<pre><code>System.out.println("You found " + hotdogs + "hotdogs!");
System.out.println("How many glasses of water will you drink?");
hotdogs = myScan.nextInt();
</code></pre>

<p>Ultimately, there is a deeper philosophical statement being made by the instructor about which habits they would like to inculcate and foster at the very root of their students' thinking.  These patterns of thought, it is presumed, will modify the initial ways that the students approach problems even later in life.  </p>

<p>I do not know of any research that backs this up, but, of course, much of what we try to impart to our students is not from research, but from intuition. And, who knows?  They might be right about this one.</p>

CC BY-SA 4.0
2021-09-02T01:34:38.063Z
A lot of the ASP.Net web apps I have created lately don't have *any* loops in them. Most of the mutation is to update a database with SQL. So I have not seen a reason to use functional or OO approaches. Am I misunderstanding something?
Scott Rowe
CC BY-SA 4.0
2021-09-14T06:22:43.660Z
@ScottRowe Your programming language is SQL; its used purely functionally when you write only `SELECT`; its mutable side goes under the `UPDATE` s. Loops are everywhere and nowhere! Nowhere because you dont see them (like pointers in Java/Python). Everywhere because everything is by default at the relation level. Programming analogies would be broadcasting in numpy or LINQ in .NET.The thing you think of as your programming language — I guess C# — is more like a glue like shell in traditional *nix usage. So what is the question?  Heck a + in C or ADD in assembly is a 32/64 bit hardware loop!
Rushi
CC BY-SA 4.0
2021-09-14T10:24:28.583Z
@Rusi If we think of SQL as a Domain Specific Language, and C# as basically a DSL also (you described it as being like a shell script, which I agree with) then it's already about as optimized as possible in terms of simple, direct code. So I don't see how making it more cryptic or how re-casting it as Functional or OO would add anything useful. It is already good. There is too little there to 'improve' it. What would you do with such a program to convert it to OO or Functional that wouldn't just add more boilerplate or render it incomprehensible? That's what I am asking. Isn't it good as is?
Scott Rowe
CC BY-SA 4.0
2021-09-14T12:02:00.610Z
@ScottRowe Oh *I* did not wish to improve this configuration -- others may that's another matter. For me SQL is a damn neat functional language. And all the ORM malarkey comes from a misunderstanding viz. that OO is higher level than SQL.  In a sane world OO would be taken as lower-level than SQL! Perhaps the broader framing error in your question is the assumption : *Doing FP means using an FPL.* I suggest an alternative view: FP as a thinking-strategy not a technology -- like flowcharts were decades ago.  See http://blog.languager.org/2012/10/functional-programming-lost-booty.html for more
Rushi
CC BY-SA 4.0
2021-09-14T12:13:46.680Z
Analogous to my «SQL is a neat FPL» here is Simon Peyton Jones -- one of the biggest names in FP today -- saying Excel is the worlds most widely used FPL https://www.slideshare.net/kfrdbs/peyton-jones
Rushi
CC BY-SA 4.0
2021-09-14T15:31:22.543Z
@Rusi Ok, well as long as I have been thinking about it the right way, I don't much care what marketing term people use. Teach the thought process and forget about the bandwagon. It would sure cut down on all the discussion.
Scott Rowe
CC BY-SA 3.0
2017-07-21T02:39:58.523Z
2017-07-21T02:39:58.523Z
Ben I.
<p>I'll give a general answer that you need to think about before it really registers. It applies to both the OOP case and the more C-like case. </p>

<h2>A program with a high percentage of immutable values is easier to reason about and modify.</h2>

<p>Once something gets a value/state in one part of the program it has that state throughout. </p>

<p>So, I'm not sure that "harder to teach or grasp" is the right metric here, but what produces a better program. </p>

<p>Deeply nested selection structures are difficult to grasp because you can't simply point to a place in the code and know what is true and what is false. You have to mentally trace the code to understand what is going on. You can avoid that with immutables, though a few other things are needed for a full picture. </p>

<p>And note that assignment isn't <em>essential</em> for computation. I.e. The lambda calculus is Turing Complete without it. This is the basis of pure functional programming. But the same idea can be applied elsewhere, as well, so this isn't a call to only program in that paradigm. </p>

CC BY-SA 3.0
2017-07-21T00:35:04.147Z
I don't think that Turing completeness argument is valid. The [Single Instruction Computer](https://en.wikipedia.org/wiki/One_instruction_set_computer) is also Turing complete, but you don't really want to use it as a programming model.
user58697
CC BY-SA 3.0
2017-07-21T00:38:19.820Z
Nor would you use a TM itself for programming. It was a theoretical point. You don't need to push the idea to its end point for it to be useful.
Buffy
CC BY-SA 3.0
2017-07-21T09:08:23.653Z
Lambdas are the single most powerful feature, add the ability to add your own words (methods), a few primitives, and a bit of lexing, and you can build the rest of the language (any language).
ctrl-alt-delor
CC BY-SA 3.0
2017-07-21T23:34:51.890Z
I agree with @user58697; this isn't really a valid premise at all.  A program in assembly language with 1024 modifiable registers and 3 GB of read-only memory would have a "high percentage of immutable values" and would *not* be easy to reason about *or* modify.
Wildcard
CC BY-SA 3.0
2017-07-22T00:02:34.573Z
To quote Harry Potter: Riddikulus. Why take such an extreme example to try to make a point?
Buffy
CC BY-SA 4.0
2021-08-31T07:49:27.420Z
@Wildcard your argument is the same as "LED lights don't help you save electricity, because you can leave the electric toaster on all day."
ctrl-alt-delor
CC BY-SA 3.0
2017-07-21T00:10:10.990Z
2017-07-21T00:25:17.017Z
2017-07-21T00:25:17.017Z
Buffy
<p>The concept of a variable is not hard in and of itself, but it is the first conceptual hurdle for students.</p>

<p>The problem is that in common usage we use the same symbol for comparison and immutable facts as we use for assignment. By the time we start kids with computer programming they are steeped in algebra where "=" means "is the same as".</p>

<pre><code>1 + 1 = 2
5 - 3 = 2
(x+y)² = x² + 2xy + y²
</code></pre>

<p>Being steeped in algebra, when they see this construct:</p>

<pre><code>x = x + 10
</code></pre>

<p>They automatically want to reduce it algebraically and solve for x</p>

<pre><code>(x-x) = 10
</code></pre>

<p>which reduces to</p>

<pre><code>0 = 10
</code></pre>

<p>which is nonsense, and they realize that, and get confused.</p>

<p>When programming most languages use "=" as an assignment, where it should be read as "becomes equal to". Back when I started (in the 8 bit days before PC's), BASIC handled this by requiring the "LET" statement, so it read more like algebra, but the LET keyword was a cue that we were making an assignment.</p>

<pre><code>10 LET X = 10
15 LET X = X + 23
20 IF x = 33 THEN GOTO BLABLABLA
</code></pre>

<p>The LET notation was cumbersome, so most dialects of BASIC introduced the "implied let". If you started the statement with a variable, it was implicitly a "LET" statement.</p>

<p>Algol, Pascal, and some other language of the day introduced the ":=" operator (read as "becomes equal to") to keep a distinction between assignment and comparison.</p>

<pre><code>x := 10;
x := x + 23;
if x = 33 then writeln("Bla bla bla");
</code></pre>

<p>C and its descendents were created for brevity rather than easy reading. They distinguish assignment from comparison by having the most common operation require the fewest keystrokes. Once you started programming in C, you were already thinking like a programmer rather than like an algebra major.</p>

<pre><code>x = 10;
x += 23;
if (x == 33) fprintf(stdout, "Bla bla bla");
</code></pre>

<p>Spaghetti code is often the result of not understanding the problem, although an attempt to treat variables as immutables when it is not appropriate would certainly contribute. Even experienced programmers will create spaghetti code if they don't understand the problem, or if the problem changes sufficiently over time. If you don't believe me, walk into any enterprise shop with custom processes and start reading code.</p>

CC BY-SA 3.0
2017-07-21T04:49:34.973Z
I read your comment as that mutability itself isn't as much a conceptual difficulty, as that the common aliased notation for mutating a variable can be a source of confusion.
hotpaw2
CC BY-SA 3.0
2017-07-25T20:42:13.023Z
the  `var = expr` notation for assignment was used before Basic. It was explained in the preliminary report of Fortran << [J.W. Backus, H. Herrick and I. Ziller.] Preliminary Report : Specifications for the IBM Mathematical FORmula TRANSlating System, FORTRAN. Programming Research Group, Applied Science Division, International Business Machines Corporation, November 10, 1954, 29 pages. >> http://archive.computerhistory.org/resources/text/Fortran/102679231.05.01.acc.pdf
Michel Billaud
CC BY-SA 3.0
2017-07-25T20:51:22.267Z
Agreed. Basic implemented the LET operator to alleviate the confusion generated by the overloaded use of the = operator.
pojo-guy
CC BY-SA 4.0
2021-08-31T07:45:42.170Z
Some good ideas. However, your dismissal for immutable as it leads to one small problem, is a common fallacy when facing change. Yes, it will not fix all problems. Yes, it can introduce new problems (but fewer). My preference is immutable by default (Give me a `mutable` keyword, and I am happy. However, don't over use it).
ctrl-alt-delor
CC BY-SA 3.0
2017-07-21T04:30:29.557Z
2017-07-21T04:30:29.557Z
pojo-guy
<p>The fundamental element of a computer is a memory cell, which we often refer to as a variable. But what is most important about it is that it can instantly take a new value by being given an electrical input. This is the thing to know, and without knowing that, you know nothing about computers. This is the thing that is a unique feature, different from any other machine or natural object.</p>
<p>When we compare memory cells to math, we are making a huge mistake. The word 'variable' was a mistaken term. It distorts and hides the reality of this marvelous thing, a device which can take new values. The metaphor has led us all in to a ditch.</p>
<p>If you did not ask yourself when you first heard about a computer, &quot;<em>How could such a thing possibly work</em>?&quot; then you need to go back and ask yourself that question now. Without wondering about that and solving it for yourself, you don't really know why a computer is so singular and ultimately different from every other thing, and why it will be able to do the things the brain can do someday. Only a brain is a brain, in all the universe, and only a computer is a computer. This is wondrous.</p>
<p>Let's not hide that from students. Reveal it right away. It is not 'difficult' if you simply tell them the truth. But you have to know the truth first. If you are not still amazed, you have not understood.</p>

CC BY-SA 4.0
2020-09-15T19:01:59.370Z
Agreed. Traditional mathematics tends to conflate assignment with variable declaration (which also tends to follow a pattern of so-called "static single assignment"), and also to use the equals symbol to assert an equivalence. Meanwhile, on the computer science side, variables often are assigned separately from their declaration, and may be reassigned multiple times. To confound things further, the equals symbol is often used to test for equality, as well as to perform assignment, and the algebraic properties (such as commutativity) of each use are not the same. (1/2)
Steve
CC BY-SA 4.0
2020-09-15T19:12:19.620Z
I would refer to these two operations as the `CopyFrom` and the `SameAs` operators. A further interesting property of the `CopyFrom` operator, is that the left operand cannot be substituted with its value - rather, it represents the *target* of the value on the right, in a copying operation. Typically, this means that the *address* of the variable on the left is *implicitly* taken and then passed as the left operand value, whilst the variable or expression on the right is evaluated as normal. This is all utterly alien to traditional mathematics. (2/2).
Steve
CC BY-SA 4.0
2021-08-31T07:37:19.463Z
“Memory cells” is just (one) implementation. However, we are discussing teaching. Teaching research has shown that this model in not the best model for teaching. Outside of teaching, research has show that it is not the best model. It is what we do in assembler/machine-code, but we use compilers to abstract away from this miss, and toward the human.
ctrl-alt-delor
CC BY-SA 4.0
2021-09-02T01:17:19.730Z
@ctrl-alt-delor If we are abstracting, shouldn't we be very sure we understand the concrete reality of the system? Is this why we teach arithmetic first, then algebra, then geometry and graphs (functions) then calculus (applications)? Does anyone suggest just starting with calculus? I would like to see the teaching research that you refer to.
Scott Rowe
CC BY-SA 4.0
2021-09-02T05:38:42.757Z
@ScottRowe In Computer Science teaching, abstraction is often confused. Both Computer Science and teaching use the word abstraction. However, They are different. That is, they abstract different things. In teaching, we avoid abstracting away from the concrete: what is already known. Keep it human centered. In Computer Science, we abstract away from the hardware, **toward the human**. So an increase in abstraction in one is a decrease in abstraction in the other.
ctrl-alt-delor
CC BY-SA 4.0
2020-09-12T12:36:52.913Z
2020-09-12T12:36:52.913Z
Scott Rowe
<p>It is not assignment that is confusing, it is mutation. I too, grew up in the 1980s programming 8bit ZX-Spectrums, and 32bit Amigas (How far we have come).</p>
<p>But when I watched the Structure and Interpretation of Computer Programs videos. I realised that mutation was <strong>mostly</strong> bad, and should be avoided. While mutation is a bit confusing (Usually use of <code>=</code>, though a language could use <code>:=</code>), it does not stop there, it then leads to all sort of bugs, and hard to read code. Even for an expert.</p>
<p>Even though we can write programs with a lot of mutation, I know we can, I did. However, it is better, quicker, to write them with less mutation.</p>
<p>What ever we teach first, students will subconsciously believe is the most important.</p>
<hr />
<p>I also think that selection is overused, except we need it if we use recursion. And we need it latter to process inputs.</p>
<p>Once I realised that any program can be written without mutation, without selection (except to get out of recursion), and with only two unbounded loops (if you have lambdas and full multiple inheritance), my programs got better. A lot better, nearly bug free.</p>
<p>Alternatives to full-multiple-inheritance include: (I don't know all the names)</p>
<ul>
<li>Duck-typing</li>
<li>Prototype based OO</li>
<li>The one in kotlin, where you define interfaces. (it is like specifying the inheritance late)</li>
</ul>

CC BY-SA 4.0
2021-09-02T01:27:59.307Z
Few languages have full multiple inheritance. Would you please provide a reference that shows the technique you describe? It sounds like something I learned in a Lisp class over 35 years ago, and if I have overlooked it all this time I would like to improve.
Scott Rowe
CC BY-SA 4.0
2021-09-02T05:55:00.390Z
@ScottRowe Yes. Many languages are defective. You can do 90% without multiple inheritance. In a language where everything is first-class (e.g. lisp). You can implement foreach. foreach is a bounded loop, but its implementation uses an unbounded loop. The other loop is the super-loop (while user_has_not_chosen_to_exit:)
ctrl-alt-delor
CC BY-SA 4.0
2021-09-02T05:55:42.583Z
I added some alternatives (to the answer) to full-inheritance
ctrl-alt-delor
CC BY-SA 4.0
2021-09-02T09:58:34.373Z
I inherited a well-designed system about 30 years ago that is basically your 90% solution. It was written entirely in C, no OO. So, to me, languages are just a convenience, not essential. I decide what I want, and I build it, even if it's difficult. But making it easy doesn't change the design process. If teaching is about teaching design, then languages and approaches matter much less, because they will change, but objectives will not.
Scott Rowe
CC BY-SA 4.0
2021-09-02T15:54:33.110Z
@ScottRowe I agree. Unix is written in `C` and it is an OO design, with (reference-counted) garbage collection. And languages do only make it easier. We should make it easy to do the right thing, but not make it impossible to do the wrong thing: sometimes mutation is the best solution (e.g. implementing a random-number-generator). I think choice of language is important, but also agree that you can write good or bad code in any language.
ctrl-alt-delor
CC BY-SA 4.0
2017-07-21T09:19:35.743Z
2021-09-02T05:54:36.020Z
2021-09-02T05:54:36.020Z
ctrl-alt-delor
<p>Why do some instructors delay teaching mutation due to considering it to be a more difficult concept? (than functional or recursive concepts, etc.)</p>

<p>It is very likely that, back in the 8-bit PC days, many thousands of 8 to 12 year olds learned to code in Tiny Basic or other "street" BASIC implementations (where there weren't even local variables or other easy recursion or functional semantic support).  How could these kids do so if variable mutation was a difficult concept?</p>

<p>Or is the spaghetti code they often produce a result of not really understanding the concept itself?  (rather than just the software engineering downsides)</p>

CC BY-SA 3.0
2017-07-20T22:56:03.830Z
What types of answers are you hoping to get? Asking *"How could these kids do so if variable mutation was a difficult concept?"* is a bit like asking how kids learned about XYZ before approach ABC. It's not a yes-or-no thing.
Kevin Workman
CC BY-SA 3.0
2017-07-21T00:05:53.233Z
Are you asking about mutable v immutable "objects" (i.e. Lists v Strings in Java) or just the fact that a variable can refer to different values at different times (i.e. var v val in Scala, say)?
Buffy
CC BY-SA 4.0
2020-09-23T07:39:21.313Z
A rust-y look may help : https://medium.com/@vikram.fugro/mutable-reference-in-rust-995320366e22 (not so much in answering the question but in saying that some language (designers) take this question v seriously)
Rushi
<curriculum-design><variables>
Why would mutation be considered by some as a difficult concept to grasp?
# Why would mutation be considered by some as a difficult concept to grasp?

(Asked by: username_0 on 2017-07-20)

Why do some instructors delay teaching mutation due to considering it to be a more difficult concept? (than functional or recursive concepts, etc.)

It is very likely that, back in the 8-bit PC days, many thousands of 8 to 12 year olds learned to code in Tiny Basic or other "street" BASIC implementations (where there weren't even local variables or other easy recursion or functional semantic support). How could these kids do so if variable mutation was a difficult concept?

Or is the spaghetti code they often produce a result of not really understanding the concept itself? (rather than just the software engineering downsides)

**Tags:** curriculum-design, variables

> **Comments:**
> **username_1**: What types of answers are you hoping to get? Asking *"How could these kids do so if variable mutation was a difficult concept?"* is a bit like asking how kids learned about XYZ before approach ABC. It's not a yes-or-no thing.  
> **username_2**: Are you asking about mutable v immutable "objects" (i.e. Lists v Strings in Java) or just the fact that a variable can refer to different values at different times (i.e. var v val in Scala, say)?  
> **username_3**: A rust-y look may help : https://medium.com/@vikram.fugro/mutable-reference-in-rust-995320366e22 (not so much in answering the question but in saying that some language (designers) take this question v seriously)  

---

## 6 answers

### Answer by username_7 on 2017-07-21. Score: 6

I personally teach mutation almost immediately.  However, I agree with username_2 that more difficult is not really the metric people are using to decide to teach mutation later.  It is about giving certain key habits a chance to grow and develop before you get there.
Most people find recursion naturally more difficult than a loop.  There is no reason why this must be, and folks who learned recursion first will often find the difficult one to be the standard imperative loop.  If you begin a student in a programming world without mutability, what habits will grow?
Certainly recursion will come quite naturally.  So will linked lists and trees.  And certain sloppy habits will be naturally avoided, such as this balderdash:
System.out.println("You found " + hotdogs + "hotdogs!");
System.out.println("How many glasses of water will you drink?");
hotdogs = myScan.nextInt();

Ultimately, there is a deeper philosophical statement being made by the instructor about which habits they would like to inculcate and foster at the very root of their students' thinking.  These patterns of thought, it is presumed, will modify the initial ways that the students approach problems even later in life.  
I do not know of any research that backs this up, but, of course, much of what we try to impart to our students is not from research, but from intuition. And, who knows?  They might be right about this one.

> **Comments:**
> **username_4**: A lot of the ASP.Net web apps I have created lately don't have *any* loops in them. Most of the mutation is to update a database with SQL. So I have not seen a reason to use functional or OO approaches. Am I misunderstanding something?  
> **username_3**: @ScottRowe Your programming language is SQL; its used purely functionally when you write only `SELECT`; its mutable side goes under the `UPDATE` s. Loops are everywhere and nowhere! Nowhere because you dont see them (like pointers in Java/Python). Everywhere because everything is by default at the relation level. Programming analogies would be broadcasting in numpy or LINQ in .NET.The thing you think of as your programming language — I guess C# — is more like a glue like shell in traditional *nix usage. So what is the question?  Heck a + in C or ADD in assembly is a 32/64 bit hardware loop!  
> **username_4**: @Rusi If we think of SQL as a Domain Specific Language, and C# as basically a DSL also (you described it as being like a shell script, which I agree with) then it's already about as optimized as possible in terms of simple, direct code. So I don't see how making it more cryptic or how re-casting it as Functional or OO would add anything useful. It is already good. There is too little there to 'improve' it. What would you do with such a program to convert it to OO or Functional that wouldn't just add more boilerplate or render it incomprehensible? That's what I am asking. Isn't it good as is?  
> **username_3**: @ScottRowe Oh *I* did not wish to improve this configuration -- others may that's another matter. For me SQL is a damn neat functional language. And all the ORM malarkey comes from a misunderstanding viz. that OO is higher level than SQL.  In a sane world OO would be taken as lower-level than SQL! Perhaps the broader framing error in your question is the assumption : *Doing FP means using an FPL.* I suggest an alternative view: FP as a thinking-strategy not a technology -- like flowcharts were decades ago.  See http://blog.languager.org/2012/10/functional-programming-lost-booty.html for more  
> **username_3**: Analogous to my «SQL is a neat FPL» here is Simon Peyton Jones -- one of the biggest names in FP today -- saying Excel is the worlds most widely used FPL https://www.slideshare.net/kfrdbs/peyton-jones  
> **username_4**: @Rusi Ok, well as long as I have been thinking about it the right way, I don't much care what marketing term people use. Teach the thought process and forget about the bandwagon. It would sure cut down on all the discussion.  

---

### Answer by username_2 on 2017-07-21. Score: 4

I'll give a general answer that you need to think about before it really registers. It applies to both the OOP case and the more C-like case.

## A program with a high percentage of immutable values is easier to reason about and modify.

Once something gets a value/state in one part of the program it has that state throughout.

So, I'm not sure that "harder to teach or grasp" is the right metric here, but what produces a better program.

Deeply nested selection structures are difficult to grasp because you can't simply point to a place in the code and know what is true and what is false. You have to mentally trace the code to understand what is going on. You can avoid that with immutables, though a few other things are needed for a full picture.

And note that assignment isn't *essential* for computation. I.e. The lambda calculus is Turing Complete without it. This is the basis of pure functional programming. But the same idea can be applied elsewhere, as well, so this isn't a call to only program in that paradigm.

> **Comments:**
> **username_8**: I don't think that Turing completeness argument is valid. The [Single Instruction Computer](https://en.wikipedia.org/wiki/One_instruction_set_computer) is also Turing complete, but you don't really want to use it as a programming model.  
> **username_2**: Nor would you use a TM itself for programming. It was a theoretical point. You don't need to push the idea to its end point for it to be useful.  
> **username_6**: Lambdas are the single most powerful feature, add the ability to add your own words (methods), a few primitives, and a bit of lexing, and you can build the rest of the language (any language).  
> **username_9**: I agree with @username_8; this isn't really a valid premise at all.  A program in assembly language with 1024 modifiable registers and 3 GB of read-only memory would have a "high percentage of immutable values" and would *not* be easy to reason about *or* modify.  
> **username_2**: To quote Harry Potter: Riddikulus. Why take such an extreme example to try to make a point?  
> **username_6**: @username_9 your argument is the same as "LED lights don't help you save electricity, because you can leave the electric toaster on all day."  

---

### Answer by username_10 on 2017-07-21. Score: 4

The concept of a variable is not hard in and of itself, but it is the first conceptual hurdle for students.
The problem is that in common usage we use the same symbol for comparison and immutable facts as we use for assignment. By the time we start kids with computer programming they are steeped in algebra where "=" means "is the same as".
1 + 1 = 2
5 - 3 = 2
(x+y)² = x² + 2xy + y²

Being steeped in algebra, when they see this construct:
x = x + 10

They automatically want to reduce it algebraically and solve for x
(x-x) = 10

which reduces to
0 = 10

which is nonsense, and they realize that, and get confused.
When programming most languages use "=" as an assignment, where it should be read as "becomes equal to". Back when I started (in the 8 bit days before PC's), BASIC handled this by requiring the "LET" statement, so it read more like algebra, but the LET keyword was a cue that we were making an assignment.
10 LET X = 10
15 LET X = X + 23
20 IF x = 33 THEN GOTO BLABLABLA

The LET notation was cumbersome, so most dialects of BASIC introduced the "implied let". If you started the statement with a variable, it was implicitly a "LET" statement.
Algol, Pascal, and some other language of the day introduced the ":=" operator (read as "becomes equal to") to keep a distinction between assignment and comparison.
x := 10;
x := x + 23;
if x = 33 then writeln("Bla bla bla");

C and its descendents were created for brevity rather than easy reading. They distinguish assignment from comparison by having the most common operation require the fewest keystrokes. Once you started programming in C, you were already thinking like a programmer rather than like an algebra major.
x = 10;
x += 23;
if (x == 33) fprintf(stdout, "Bla bla bla");

Spaghetti code is often the result of not understanding the problem, although an attempt to treat variables as immutables when it is not appropriate would certainly contribute. Even experienced programmers will create spaghetti code if they don't understand the problem, or if the problem changes sufficiently over time. If you don't believe me, walk into any enterprise shop with custom processes and start reading code.

> **Comments:**
> **username_0**: I read your comment as that mutability itself isn't as much a conceptual difficulty, as that the common aliased notation for mutating a variable can be a source of confusion.  
> **username_11**: the  `var = expr` notation for assignment was used before Basic. It was explained in the preliminary report of Fortran << [J.W. Backus, H. Herrick and I. Ziller.] Preliminary Report : Specifications for the IBM Mathematical FORmula TRANSlating System, FORTRAN. Programming Research Group, Applied Science Division, International Business Machines Corporation, November 10, 1954, 29 pages. >> http://archive.computerhistory.org/resources/text/Fortran/102679231.05.01.acc.pdf  
> **username_10**: Agreed. Basic implemented the LET operator to alleviate the confusion generated by the overloaded use of the = operator.  
> **username_6**: Some good ideas. However, your dismissal for immutable as it leads to one small problem, is a common fallacy when facing change. Yes, it will not fix all problems. Yes, it can introduce new problems (but fewer). My preference is immutable by default (Give me a `mutable` keyword, and I am happy. However, don't over use it).  

---

### Answer by username_4 on 2020-09-12. Score: 4

The fundamental element of a computer is a memory cell, which we often refer to as a variable. But what is most important about it is that it can instantly take a new value by being given an electrical input. This is the thing to know, and without knowing that, you know nothing about computers. This is the thing that is a unique feature, different from any other machine or natural object.

When we compare memory cells to math, we are making a huge mistake. The word 'variable' was a mistaken term. It distorts and hides the reality of this marvelous thing, a device which can take new values. The metaphor has led us all in to a ditch.

If you did not ask yourself when you first heard about a computer, "*How could such a thing possibly work*?" then you need to go back and ask yourself that question now. Without wondering about that and solving it for yourself, you don't really know why a computer is so singular and ultimately different from every other thing, and why it will be able to do the things the brain can do someday. Only a brain is a brain, in all the universe, and only a computer is a computer. This is wondrous.

Let's not hide that from students. Reveal it right away. It is not 'difficult' if you simply tell them the truth. But you have to know the truth first. If you are not still amazed, you have not understood.

> **Comments:**
> **username_12**: Agreed. Traditional mathematics tends to conflate assignment with variable declaration (which also tends to follow a pattern of so-called "static single assignment"), and also to use the equals symbol to assert an equivalence. Meanwhile, on the computer science side, variables often are assigned separately from their declaration, and may be reassigned multiple times. To confound things further, the equals symbol is often used to test for equality, as well as to perform assignment, and the algebraic properties (such as commutativity) of each use are not the same. (1/2)  
> **username_12**: I would refer to these two operations as the `CopyFrom` and the `SameAs` operators. A further interesting property of the `CopyFrom` operator, is that the left operand cannot be substituted with its value - rather, it represents the *target* of the value on the right, in a copying operation. Typically, this means that the *address* of the variable on the left is *implicitly* taken and then passed as the left operand value, whilst the variable or expression on the right is evaluated as normal. This is all utterly alien to traditional mathematics. (2/2).  
> **username_6**: “Memory cells” is just (one) implementation. However, we are discussing teaching. Teaching research has shown that this model in not the best model for teaching. Outside of teaching, research has show that it is not the best model. It is what we do in assembler/machine-code, but we use compilers to abstract away from this miss, and toward the human.  
> **username_4**: @username_6 If we are abstracting, shouldn't we be very sure we understand the concrete reality of the system? Is this why we teach arithmetic first, then algebra, then geometry and graphs (functions) then calculus (applications)? Does anyone suggest just starting with calculus? I would like to see the teaching research that you refer to.  
> **username_6**: @ScottRowe In Computer Science teaching, abstraction is often confused. Both Computer Science and teaching use the word abstraction. However, They are different. That is, they abstract different things. In teaching, we avoid abstracting away from the concrete: what is already known. Keep it human centered. In Computer Science, we abstract away from the hardware, **toward the human**. So an increase in abstraction in one is a decrease in abstraction in the other.  

---

### Answer by username_6 on 2017-07-21. Score: 2

It is not assignment that is confusing, it is mutation. I too, grew up in the 1980s programming 8bit ZX-Spectrums, and 32bit Amigas (How far we have come).

But when I watched the Structure and Interpretation of Computer Programs videos. I realised that mutation was **mostly** bad, and should be avoided. While mutation is a bit confusing (Usually use of `=`, though a language could use `:=`), it does not stop there, it then leads to all sort of bugs, and hard to read code. Even for an expert.

Even though we can write programs with a lot of mutation, I know we can, I did. However, it is better, quicker, to write them with less mutation.

What ever we teach first, students will subconsciously believe is the most important.

---

I also think that selection is overused, except we need it if we use recursion. And we need it latter to process inputs.

Once I realised that any program can be written without mutation, without selection (except to get out of recursion), and with only two unbounded loops (if you have lambdas and full multiple inheritance), my programs got better. A lot better, nearly bug free.

Alternatives to full-multiple-inheritance include: (I don't know all the names)

* Duck-typing
* Prototype based OO
* The one in kotlin, where you define interfaces. (it is like specifying the inheritance late)

> **Comments:**
> **username_4**: Few languages have full multiple inheritance. Would you please provide a reference that shows the technique you describe? It sounds like something I learned in a Lisp class over 35 years ago, and if I have overlooked it all this time I would like to improve.  
> **username_6**: @ScottRowe Yes. Many languages are defective. You can do 90% without multiple inheritance. In a language where everything is first-class (e.g. lisp). You can implement foreach. foreach is a bounded loop, but its implementation uses an unbounded loop. The other loop is the super-loop (while user_has_not_chosen_to_exit:)  
> **username_6**: I added some alternatives (to the answer) to full-inheritance  
> **username_4**: I inherited a well-designed system about 30 years ago that is basically your 90% solution. It was written entirely in C, no OO. So, to me, languages are just a convenience, not essential. I decide what I want, and I build it, even if it's difficult. But making it easy doesn't change the design process. If teaching is about teaching design, then languages and approaches matter much less, because they will change, but objectives will not.  
> **username_6**: @ScottRowe I agree. Unix is written in `C` and it is an OO design, with (reference-counted) garbage collection. And languages do only make it easier. We should make it easy to do the right thing, but not make it impossible to do the wrong thing: sometimes mutation is the best solution (e.g. implementing a random-number-generator). I think choice of language is important, but also agree that you can write good or bad code in any language.  

---

### Answer by username_3 on 2020-09-27. Score: 1

Assignment is bad
This is basically the functional language position.
And much of Backus landmark Turing award
remains relevant nearly 50 years on.
We could rehash those arguments if we wish; but it's good to have something like the Backus TAL as a point of departure for that.
Mutation
Mutation often looks like assignment but is worse
A small Python session showing

no assignment
assignment,
mutating function
mutating assignment

Session
 # Functional behavior; no assignment/mutation no problems
>>> a = [1,2,3]
>>> c = [a,a]
>>> c
[[1, 2, 3], [1, 2, 3]]
>>> a+[4]
[1, 2, 3, 4]
>>> c
[[1, 2, 3], [1, 2, 3]] # unchanged

# Assignment; but still harmless
>>> a =[1,2,3]
>>> c = [a,a]
>>> c
[[1, 2, 3], [1, 2, 3]]
>>> a = a + [4]
>>> a
[1, 2, 3, 4] # changed as expected 
>>> c
[[1, 2, 3], [1, 2, 3]] #unchanged as expected 
>>>

#append looks like + but it actually mutates
>>> a = [1,2,3]
>>> c = [a,a]
>>> c
[[1, 2, 3], [1, 2, 3]]
>>> c[0].append(4)
>>> c
[[1, 2, 3, 4], [1, 2, 3, 4]]
# Note how changing c[0] changed c[1]
# ie the unholy alliance between aliasing&mutation

>>> d = [[1,2,3] for i in [1,2]]
>>> d
# A d which looks just like c
[[1, 2, 3], [1, 2, 3]]
>>> d[0].append(4)
>>> d
[[1, 2, 3, 4], [1, 2, 3]]
# But changing c[0] doesn't change c[1]
# ie different aliasing


>>> a = [1,2,3]
>>> c = [a,a]
>>> a[:] = [4,5] # mutation note the ':'
>>> c
[[4, 5], [4, 5]]  # WHAZZAT! 

What do I recommend
1st choice
Use a language like Haskell -- no assignment, no mutation.
Or at least Scheme/ML where these are mostly not used
2nd choice
Use a language like Python as a "functional assembly language".
ie Use it like a functional language; don't teach mention append/extend etc the mutating methods.
When some smart Alec comes up using these break his code in the above paradigm!
This is what I often end up doing.
3rd choice
Teach all the mess and confuse the students

> **Comments:**
> **username_4**: Programming is confusing and it is a big responsibility, like driving a car or dealing with finances. Someday, we will not have those things anymore, but for now we do. Hiding stuff from people does nothing to help them learn and grow. Teach the two hard things immediately and get them nailed down flat from the very beginning.  
> **username_3**: Well we'll have agree to disagree on that @Scottrowe We're in 2020. Quite apart from the fact that functional P is now no more ivory-tower : eg clojure, scala, erlang etc, even mainstream imperative/OO are changing course See this microsoft doc Note the "note" «Better to use immutable value types.» What is this other than «Try to program functionally when possible?» https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/value-types  
> **username_5**: Python portfolio of examples could be extended with `a += [4]` (mutation)  
> **username_3**: @aivaarpaalberg yeah sure: "a = a + [4]" assigns to a whereas "a += [4]" mutates a. There are zillions (OK dozens ) of such gotchas waiting the unwary. So what's the point you're making? I'm not sure. My point was (1) to answer why mutation is a problem (2) and worse than assignmentt. eg the well-known [mutable default args](https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments) is (from a pragmatic pov) v important. My point was more philosophic : with all these gotchas why are we teaching? And what exactly are we teaching?  
> **username_3**: @ScottRowe thinks these things important. I don't. Not sure where you (aivaarpaalberg) stand on this. And hey that's fine There's 7 billion of us on this spinning rock!  
> **username_5**: Programming languages are made by the people for the people. Programming languages tend to reflect it the same way as the spoken languages. One must know that 'cat has nine lives' shouldn't be taken literally and person saying that has not lost touch with reality :-). My native language has no future tense, no gender pronouns, no definite/indefinite articles etc, but I try to use them when I speak english, russian or spanish (unfortunately often forgetting to use them or using improperly). This is not the fault of these languages - this is my fault not knowing or practicing language enough.  
> **username_3**: @Aivarpaalberg Interesting comment. Isn't the opposite equally true, viz. There are things you can say in Estonian (I'm assuming that's your native language) which you cannot convey with the same nuance and finesse in any other?  
> **username_4**: @AivarPaalberg I like your comment on how languages vary. I simply think that we must teach the aspects of computers that do not vary, the aspects that are always true, independent of language. Otherwise, it would be like trying to teach about gender pronouns (as you mentioned), without ever knowing or saying what gender is. Let's begin teaching by stating what is. It really is not that complicated: there is assignment / mutation, and there is indirection. That is what makes a computer, a computer. Nothing more, nothing less than those 2 things.  
> **username_6**: I total agree, but find the terminology a bit confusing: What do you mean by assignment?  
> **username_4**: @username_6 Assignment means storing a new value in a variable (memory location). Computers can only do 5 things: fetch, store, arithmetic, compare, branch. Indirect Reference is the other major thing, which modifes the fetch and store operations. If you know of anything else that a CPU can do, please say.  
> **username_6**: @scottrowe I was asking the author. I know what I think it means, but when reading the answer, I wondered what the author meant.  
> **username_3**: @scottrowe "homonym" and "synonym" are not synonyms!! When you treat them as such you paint yourself into a corner. Math-variable and program-variable are similar sounding merely by happenstance. See the comments below https://cseducators.stackexchange.com/q/7037/8837 particularly Bob Harper's differentiation of "assignable" — the programming concept — from "variable" — the math one. Also SolomonSlow's comments are remarkably bullseye  
> **username_3**: There's more that needs be said here but as I told @username_6 cant do it now due to some challenges. Hope to return at some point.  

---

