Answers.Body: <p>"Analogous" could mean different things, depending on which analogy you choose to make. To me, the key thing about learning multiplication tables is that you are memorising the answers to some simple questions which will appear as subproblems to many other things you have to do; so that you don't have to derive the answers again each time those subproblems occur. @Buffy's answer describes some of the fundamental abstract concepts which programmers certainly need a solid understanding of, but I would not count things like "sequence" and "alternation" as problems for which we apply solutions from memory; so I infer that @Buffy sees a different analogy to the one I do.</p>
  
  <p>For the analogy as I see it, there are some commonly-occurring subproblems in imperative programming which we do use memorised solutions to. I would think of @Buffy's fundamental ideas as analogous to the ability to do multiplication, and the understanding of when/why to multiply; they should be learned before it makes sense to memorise the answers to multiplication questions. Likewise, understanding what sequential, conditional and iterative statements are and when/why to use them in a program should precede memorising how to apply them to solve particular problems.</p>
  
  <p>To give some idea of the kind of subproblems and memorised-solutions I mean, the below list is not at all complete, but should help to illustrate by example:</p>
  
  <ul>
  <li>Q: <em>How to iterate over just some elements of a collection?</em> A: Write a loop over the collection, and an <code>if</code> statement inside the loop to "filter" for just the elements you want to iterate over. The code for processing each element should go inside the <code>if</code> statement.</li>
  <li>Q: <em>How to find the sum of a collection of numbers?</em> A: Initialise a variable <code>sum = 0</code>, and use a loop to do <code>sum += x</code> for each <code>x</code> from the collection.</li>
  <li>Q: <em>How to count the number of occurrences of something in a collection?</em> A: Initialise a variable <code>count = 0</code>, and write <code>count += 1</code> each time that thing is detected to have occurred.</li>
  <li>Q: <em>How to find the "best" (maximum, minimum, etc.) thing in a collection?</em> A: Initialise a variable <code>best</code> to be the first thing from the collection, and write a loop over the remaining elements. Each time a new element <code>x</code> is observed, check if <code>x</code> is "better" than the current <code>best</code>, and if it is, update <code>best = x</code>.</li>
  </ul>
  
  <p>These memorised solutions to commonly-occurring subproblems are closely related to the ideas of "roles of variables" as described by <a href="http://www.cs.joensuu.fi/~saja/var_roles/role_intro.html" rel="noreferrer">Sajaniemi</a> and "plans" as described by <a href="https://www.ics.uci.edu/~redmiles/inf233-FQ07/oldpapers/SollowayEhrlich.pdf" rel="noreferrer">Soloway &amp; Ehrlich</a>; I use the word "plans" to describe them. I'm not aware of any comprehensive list of them; I was able to think of some, which I've <a href="https://dsaa.werp.site/post/algorithmic-plans/" rel="noreferrer">written about in Python</a> and used for teaching undergraduate students (with limited success - perhaps we didn't spend long enough for the students to memorise the plans by repeated practice). I have written a similar document for Java which I don't have to hand immediately, but I can post it later if there is interest.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-01-16T19:14:28.727Z
Answers.Text: This is a really nice answer.  I've been building such a resource myself, though I never thought about it in quite this distilled of a manner before.
Answers.UserDisplayName: Ben I.
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-01-16T19:37:23.490Z
Answers.Text: @BenI. I'd be very interested to see what you have, if it's intended for public consumption.
Answers.UserDisplayName: kaya3
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-01-17T21:07:48.800Z
Answers.Text: I would love to see the equivalent for functional programmers :) (i know it’s map/filter, reduce, count or length/filter, etc., but what im *more* interested now is: are there fundamentals beneath the paradigms? Multiplication tables don’t favor one kind of math over others, excepting perhaps algebra and geometry.)
Answers.UserDisplayName: D. Ben Knoble
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-01-17T21:17:15.060Z
Answers.Text: @D.BenKnoble You are right - this is specific to the imperative paradigm, despite the question saying "regardless of paradigm". I do think every developer *ought* to learn these things in the imperative paradigm, though, even if they use another paradigm professionally; other language paradigms are ultimately implemented by machines running imperative machine instructions, and it's rather useful to know how your code will end up being implemented imperatively, for example so you can estimate how efficient it will be.
Answers.UserDisplayName: kaya3
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-01-17T21:18:28.440Z
Answers.Text: @kaya3 very true! Not discounting their usefulness at all
Answers.UserDisplayName: D. Ben Knoble
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-01-17T21:23:06.530Z
Answers.Text: That said, the OO paradigm also has common subproblems and standard solutions which programmers do learn and apply from memory; design patterns, for example. And other paradigms like FP surely have their own common subproblems and standard solutions which programmers learn and apply from memory, though I don't use those paradigms often enough to add to the discussion about them. I would certainly be interested to see a comparable list of "plans" for FP if anyone has written one.
Answers.UserDisplayName: kaya3
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-01-17T22:38:51.413Z
Answers.Text: And the anwsers: filter -> map; reduce; filter -> reduce; reduce. Don't role your own loops.
Answers.UserDisplayName: ctrl-alt-delor
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-01-17T22:44:30.907Z
Answers.Text: @ctrl-alt-delor I was more thinking that FP has its own common subproblems for which programmers have solutions they apply from memory. Problems tend to be decomposed in different ways for different paradigms, so there must be a plenty of common subproblems specific to FP, not just the same subproblems solved by different plans. One that comes to mind is converting a recursive function into a tail-recursive form, where the memorised solution is to add an accumulator variable as an extra parameter, and a helper function which provides the initial value for the accumulator.
Answers.UserDisplayName: kaya3
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-01-17T22:51:51.923Z
Answers.Text: Functional Programming, does not have to be a separate thing. You can do it in any language. All the modern OO languages, that I use, have filter / map / reduce.
Answers.UserDisplayName: ctrl-alt-delor
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-02-07T21:19:46.503Z
Answers.Text: I did see an academic paper on teaching junior devs and I distinctly recall something in the paper about avoiding OO concepts--or at least leaving them for much later in the training.  For all that OO advocates blather on about OO being more natural it does a lot to muddy the water for junior devs just trying to learn. (Note: I believe [this](https://www.tandfonline.com/doi/abs/10.1080/08993408.2019.1565235) is the paper I was thinking of)
Answers.UserDisplayName: Onorio Catenacci
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-02-07T21:50:58.057Z
Answers.Text: @OnorioCatenacci Ah, that's a debate which this comment thread is too small to contain.
Answers.UserDisplayName: kaya3
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-02-07T22:13:13.423Z
Answers.Text: Very fair @kaya3!
Answers.UserDisplayName: Onorio Catenacci
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-01-16T11:09:03.020Z
Answers.LastActivityDate: 2020-01-16T11:09:03.020Z
Answers.UserDisplayName: kaya3
Answers.Body: <p>@kaya3 answer is wonderful. I view the questions listed as things that I must be able to do by rote. When I see a particular problem, I can write the skeleton of the code without thought. The pattern is so ingrained that its use is mechanical.</p>
  
  <p>In the current environment we have access to all kinds of libraries for different data structures. We no longer need to be able to build them from scratch, but we still need to understand which data structure matches our needs the best and the implications in choosing that particular implementation.</p>
  
  <p>Thirty years ago (longer ?) I would have said the ability to produce the basic data structures (array based, linked list - single/double/circular, trees - and how to traverse them, hash tables - handling collisions, ...) should all be rote code patterns. Now the rote knowledge is knowing which to pick, and the implications of the choice.</p>
  
  <p>These are a few more that came to mind:</p>
  
  <ul>
  <li><p>Q: How to swap the values of two variables? A: Use a temp variable</p></li>
  <li><p>Q: How to find the unique elements of a collection? A: Start with an empty collection answer and add elements only when the value is not present. How do you make this efficient?</p></li>
  <li><p>Q: How to implement findFirst()/findLast() and handling "not found"? A: Understand which data structure(s) might make this easy/hard and select a "not found" strategy.</p></li>
  <li><p>Q: How do you do X? A: Learn to construct good Google queries and when you find something that provides useful information, and include the link in your work so you can find it again!</p></li>
  <li><p>Q: I've found something that may help me do what I need to do. How do I incorporate it in my code? A: Write a <strong>small</strong> test program containing the code, test it and really understand what it does. <strong>Then</strong> merge it into your code.</p></li>
  </ul>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-02-07T21:16:26.707Z
Answers.Text: Those are excellent suggestions for "things a developer should know by rote"!
Answers.UserDisplayName: Onorio Catenacci
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-02-07T19:28:12.517Z
Answers.LastActivityDate: 2020-02-07T20:33:24.330Z
Answers.LastEditDate: 2020-02-07T20:33:24.330Z
Answers.UserDisplayName: Fritz Sieker
Answers.Body: <p>There are three ideas that are fundamental. The first is "sequential" action. One item and then the next. The second is "alternation" one thing or another, but not both. The third is repetition. A thing repeated some number of times. </p>
  
  <p>The last is a bit more complicated because of the two cases, definite repetition and indefinite (until something happens) repetition. </p>
  
  <p>If you have these you have a basis. And notice I didn't say "if statements" and "loops". Those are just ways of doing things in different paradigms. </p>
  
  <p>But recursion is a special case of repetition. </p>
  
  <p>At the next level are values and expressions. Again, not variables, but values. </p>
  
  <p>And then, the biggest idea: abstraction. We can name things. We can name values or operations or ...</p>
  
  <hr>
  
  <p>I left out concurrency, even though it is pretty fundamental. But it is seldom studied by novices. </p>
  
  <hr>
  
  <p>And note, of course, that the "three big ideas" are themselves abstractions over more concrete representations that might occur in various languages. </p>
  
  <hr>
  
  <p>Also, in some ways the things I mention here are more fundamental to computing than the multiplication tables are to math. For example, I can't imagine a CS graduate without a firm grounding in these. But I earned a PhD in math before I learned my multiplication tables.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-01-17T22:42:15.797Z
Answers.Text: Concurrency is easy, so long as you don't have mutation. And mutation is easy to avoid.
Answers.UserDisplayName: ctrl-alt-delor
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-01-18T15:42:46.763Z
Answers.Text: I was surprise your first one was not *Boolean logic*, then *conditional*. From that you get all *branching* and *looping*.  If you think in terms of the **ALU** in a processor and then add on parts of the processor such as memory and the bus it is easy to build up the fundamental concepts.
Answers.UserDisplayName: Guy Coder
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-01-15T18:02:31.573Z
Answers.LastActivityDate: 2020-01-15T19:47:01.730Z
Answers.LastEditDate: 2020-01-15T19:47:01.730Z
Answers.UserDisplayName: Buffy
Body: <p>I apologize; I know this question is sort of open-ended and if I could think of a way to make it more specific, I would.</p>
  
  <p>What would you consider a piece of CS so fundamental that it would be analogous to an elementary student learning his/her multiplication tables?  </p>
  
  <p>I think maybe looping code, maybe data types, and/or conditional statements.  I'm looking for pointers to any scientific literature on this topic and any input anyone cares to share.   </p>
  
  <p>What are the absolute fundamentals that every developer must master regardless of paradigm (OOP, FP etc) or language? </p>
  
  <p>Feel free to close this if it's too broad but if you do vote to close please suggest how I can narrow the question as well. </p>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-01-17T22:25:11.557Z
Comments.Text: Learning multiplication tables, while still common, is redundant. We have calculators. What we need is understanding of what multiplication is, how to use a calculator, and enough mental arithmetic to calculate change when shopping and estimation.If tables are taught they should be taught much latter.
Comments.UserDisplayName: ctrl-alt-delor
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-01-17T22:27:02.217Z
Comments.Text: This may be of some relevance: https://en.wikipedia.org/wiki/Transformation_Priority_Premise
Comments.UserDisplayName: ctrl-alt-delor
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-01-17T22:48:24.970Z
Comments.Text: Patterns may be an analogy. Not just the GOF stuff (and not the anti-pattern singleton), but the wider sense. Which ones out of the thousands I don't know. I suspect that functional programming is the best place to start.
Comments.UserDisplayName: ctrl-alt-delor
Tags: <programming><introductory-lesson>
Title: What is the CS Analog To Learning One's Multiplication Tables?
ThreadText: # What is the CS Analog To Learning One's Multiplication Tables?
  
  (Asked by: username_0 on 2020-01-15)
  
  I apologize; I know this question is sort of open-ended and if I could think of a way to make it more specific, I would.
  
  What would you consider a piece of CS so fundamental that it would be analogous to an elementary student learning his/her multiplication tables?
  
  I think maybe looping code, maybe data types, and/or conditional statements. I'm looking for pointers to any scientific literature on this topic and any input anyone cares to share.
  
  What are the absolute fundamentals that every developer must master regardless of paradigm (OOP, FP etc) or language?
  
  Feel free to close this if it's too broad but if you do vote to close please suggest how I can narrow the question as well.
  
  **Tags:** programming, introductory-lesson
  
  > **Comments:**
  > **username_1**: Learning multiplication tables, while still common, is redundant. We have calculators. What we need is understanding of what multiplication is, how to use a calculator, and enough mental arithmetic to calculate change when shopping and estimation.If tables are taught they should be taught much latter.  
  > **username_1**: This may be of some relevance: https://en.wikipedia.org/wiki/Transformation_Priority_Premise  
  > **username_1**: Patterns may be an analogy. Not just the GOF stuff (and not the anti-pattern singleton), but the wider sense. Which ones out of the thousands I don't know. I suspect that functional programming is the best place to start.  
  
  ---
  
  ## 3 answers
  
  ### Answer by username_2 on 2020-01-16. Score: 6 | Accepted answer
  
  "Analogous" could mean different things, depending on which analogy you choose to make. To me, the key thing about learning multiplication tables is that you are memorising the answers to some simple questions which will appear as subproblems to many other things you have to do; so that you don't have to derive the answers again each time those subproblems occur. @username_6's answer describes some of the fundamental abstract concepts which programmers certainly need a solid understanding of, but I would not count things like "sequence" and "alternation" as problems for which we apply solutions from memory; so I infer that @username_6 sees a different analogy to the one I do.
  
  For the analogy as I see it, there are some commonly-occurring subproblems in imperative programming which we do use memorised solutions to. I would think of @username_6's fundamental ideas as analogous to the ability to do multiplication, and the understanding of when/why to multiply; they should be learned before it makes sense to memorise the answers to multiplication questions. Likewise, understanding what sequential, conditional and iterative statements are and when/why to use them in a program should precede memorising how to apply them to solve particular problems.
  
  To give some idea of the kind of subproblems and memorised-solutions I mean, the below list is not at all complete, but should help to illustrate by example:
  
  * Q: *How to iterate over just some elements of a collection?* A: Write a loop over the collection, and an `if` statement inside the loop to "filter" for just the elements you want to iterate over. The code for processing each element should go inside the `if` statement.
  * Q: *How to find the sum of a collection of numbers?* A: Initialise a variable `sum = 0`, and use a loop to do `sum += x` for each `x` from the collection.
  * Q: *How to count the number of occurrences of something in a collection?* A: Initialise a variable `count = 0`, and write `count += 1` each time that thing is detected to have occurred.
  * Q: *How to find the "best" (maximum, minimum, etc.) thing in a collection?* A: Initialise a variable `best` to be the first thing from the collection, and write a loop over the remaining elements. Each time a new element `x` is observed, check if `x` is "better" than the current `best`, and if it is, update `best = x`.
  
  These memorised solutions to commonly-occurring subproblems are closely related to the ideas of "roles of variables" as described by [Sajaniemi](http://www.cs.joensuu.fi/~saja/var_roles/role_intro.html) and "plans" as described by [Soloway & Ehrlich](https://www.ics.uci.edu/~redmiles/inf233-FQ07/oldpapers/SollowayEhrlich.pdf); I use the word "plans" to describe them. I'm not aware of any comprehensive list of them; I was able to think of some, which I've [written about in Python](https://dsaa.werp.site/post/algorithmic-plans/) and used for teaching undergraduate students (with limited success - perhaps we didn't spend long enough for the students to memorise the plans by repeated practice). I have written a similar document for Java which I don't have to hand immediately, but I can post it later if there is interest.
  
  > **Comments:**
  > **username_3**: This is a really nice answer.  I've been building such a resource myself, though I never thought about it in quite this distilled of a manner before.  
  > **username_2**: @BenI. I'd be very interested to see what you have, if it's intended for public consumption.  
  > **username_4**: I would love to see the equivalent for functional programmers :) (i know it’s map/filter, reduce, count or length/filter, etc., but what im *more* interested now is: are there fundamentals beneath the paradigms? Multiplication tables don’t favor one kind of math over others, excepting perhaps algebra and geometry.)  
  > **username_2**: @username_4 You are right - this is specific to the imperative paradigm, despite the question saying "regardless of paradigm". I do think every developer *ought* to learn these things in the imperative paradigm, though, even if they use another paradigm professionally; other language paradigms are ultimately implemented by machines running imperative machine instructions, and it's rather useful to know how your code will end up being implemented imperatively, for example so you can estimate how efficient it will be.  
  > **username_4**: @username_2 very true! Not discounting their usefulness at all  
  > **username_2**: That said, the OO paradigm also has common subproblems and standard solutions which programmers do learn and apply from memory; design patterns, for example. And other paradigms like FP surely have their own common subproblems and standard solutions which programmers learn and apply from memory, though I don't use those paradigms often enough to add to the discussion about them. I would certainly be interested to see a comparable list of "plans" for FP if anyone has written one.  
  > **username_1**: And the anwsers: filter -> map; reduce; filter -> reduce; reduce. Don't role your own loops.  
  > **username_2**: @username_1 I was more thinking that FP has its own common subproblems for which programmers have solutions they apply from memory. Problems tend to be decomposed in different ways for different paradigms, so there must be a plenty of common subproblems specific to FP, not just the same subproblems solved by different plans. One that comes to mind is converting a recursive function into a tail-recursive form, where the memorised solution is to add an accumulator variable as an extra parameter, and a helper function which provides the initial value for the accumulator.  
  > **username_1**: Functional Programming, does not have to be a separate thing. You can do it in any language. All the modern OO languages, that I use, have filter / map / reduce.  
  > **username_0**: I did see an academic paper on teaching junior devs and I distinctly recall something in the paper about avoiding OO concepts--or at least leaving them for much later in the training.  For all that OO advocates blather on about OO being more natural it does a lot to muddy the water for junior devs just trying to learn. (Note: I believe [this](https://www.tandfonline.com/doi/abs/10.1080/08993408.2019.1565235) is the paper I was thinking of)  
  > **username_2**: @username_0 Ah, that's a debate which this comment thread is too small to contain.  
  > **username_0**: Very fair @username_2!  
  
  ---
  
  ### Answer by username_5 on 2020-02-07. Score: 3
  
  @username_2 answer is wonderful. I view the questions listed as things that I must be able to do by rote. When I see a particular problem, I can write the skeleton of the code without thought. The pattern is so ingrained that its use is mechanical.
  
  In the current environment we have access to all kinds of libraries for different data structures. We no longer need to be able to build them from scratch, but we still need to understand which data structure matches our needs the best and the implications in choosing that particular implementation.
  
  Thirty years ago (longer ?) I would have said the ability to produce the basic data structures (array based, linked list - single/double/circular, trees - and how to traverse them, hash tables - handling collisions, ...) should all be rote code patterns. Now the rote knowledge is knowing which to pick, and the implications of the choice.
  
  These are a few more that came to mind:
  
  * Q: How to swap the values of two variables? A: Use a temp variable
  * Q: How to find the unique elements of a collection? A: Start with an empty collection answer and add elements only when the value is not present. How do you make this efficient?
  * Q: How to implement findFirst()/findLast() and handling "not found"? A: Understand which data structure(s) might make this easy/hard and select a "not found" strategy.
  * Q: How do you do X? A: Learn to construct good Google queries and when you find something that provides useful information, and include the link in your work so you can find it again!
  * Q: I've found something that may help me do what I need to do. How do I incorporate it in my code? A: Write a **small** test program containing the code, test it and really understand what it does. **Then** merge it into your code.
  
  > **Comments:**
  > **username_0**: Those are excellent suggestions for "things a developer should know by rote"!  
  
  ---
  
  ### Answer by username_6 on 2020-01-15. Score: 3
  
  There are three ideas that are fundamental. The first is "sequential" action. One item and then the next. The second is "alternation" one thing or another, but not both. The third is repetition. A thing repeated some number of times.
  
  The last is a bit more complicated because of the two cases, definite repetition and indefinite (until something happens) repetition.
  
  If you have these you have a basis. And notice I didn't say "if statements" and "loops". Those are just ways of doing things in different paradigms.
  
  But recursion is a special case of repetition.
  
  At the next level are values and expressions. Again, not variables, but values.
  
  And then, the biggest idea: abstraction. We can name things. We can name values or operations or ...
  
  ---
  
  I left out concurrency, even though it is pretty fundamental. But it is seldom studied by novices.
  
  ---
  
  And note, of course, that the "three big ideas" are themselves abstractions over more concrete representations that might occur in various languages.
  
  ---
  
  Also, in some ways the things I mention here are more fundamental to computing than the multiplication tables are to math. For example, I can't imagine a CS graduate without a firm grounding in these. But I earned a PhD in math before I learned my multiplication tables.
  
  > **Comments:**
  > **username_1**: Concurrency is easy, so long as you don't have mutation. And mutation is easy to avoid.  
  > **username_7**: I was surprise your first one was not *Boolean logic*, then *conditional*. From that you get all *branching* and *looping*.  If you think in terms of the **ALU** in a processor and then add on parts of the processor such as memory and the bus it is easy to build up the fundamental concepts.  
  
  ---
  
  