[HN Gopher] Children's mental models of recursive LOGO programs ...
       ___________________________________________________________________
        
       Children's mental models of recursive LOGO programs (1985)
        
       Author : YuxiLiuWired
       Score  : 85 points
       Date   : 2024-07-08 04:48 UTC (3 days ago)
        
 (HTM) web link (telearn.hal.science)
 (TXT) w3m dump (telearn.hal.science)
        
       | YuxiLiuWired wrote:
       | Particularly interesting to me:
       | 
       | Embedded recursion is much harder than tail recursion. This
       | reminds me of the difficulty of central embedding vs tail
       | embedding in linguistics.
       | 
       | Level 3: tail recursion program (:SIDE = 80) TO SHAPEB :SIDE IF
       | :SIDE = 20 STOP REPEAT 4 [FORWARD :SIDE RIGHT 90] RIGHT 90
       | FORWARD :SIDE LEFT 90 SHAPEB :SIDE/2 END Level 4: embedded
       | recursion program (:SIDE = 80) TO SHAPEC :SIDE IF :SIDE = 10 STOP
       | SHAPEC :SIDE/2 REPEAT 4 [FORWARD :SIDE RIGHT 90] RIGHT 90 FORWARD
       | :SIDE LEFT 90 END
       | 
       | > Mental model of embedded recursion as looping - The children
       | were fundamentally misled by thinking of recursion as looping.
       | While this mental model is adequate for active tail recursion, it
       | will not do for embedded recursion.
       | 
       | > programming constructs often do not allow mapping between
       | meanings of natural language terms and programming language uses
       | of those terms. Neither STOP or END stop or end, but pass control
       | back. The reason that this is important for the Logo novice is
       | that when their mental model of recursion as looping fails, they
       | have no way of inferring from the syntax of recursion in Logo how
       | flow of control does work. So they keep their inadequate looping
       | theory, based on their successful experience with it for tail
       | recursion, or blame discrepancies between their predictions and
       | the program's outcomes on mysterious entities such as numbers, or
       | the "demon" inside the language itself.
       | 
       | > Beyond mistaken mental models about recursion, we have found
       | these to involve atomistic thinking about how programs work,
       | assigning intentionality and negotiability of meaning as in the
       | case of human conversations to lines of programming code, and
       | application of natural language semantics to programming
       | commands.
        
         | antonvs wrote:
         | It's not clear whether these results would generalize much
         | beyond Logo. Reading the part which starts with "To understand
         | how recursive procedures work in Logo one must know:" makes
         | Logo recursive procedures sound pretty terrible - typical ad-
         | hoc language design.
        
           | andybak wrote:
           | What part? It's confusingly explained but this sounds like
           | how nearly every other language behaves.
        
             | antonvs wrote:
             | This:
             | 
             | > this acts to insert all lines of the named procedure into
             | the executing program at the point where the call occurred
             | 
             | ...is quite dubious, perhaps it works in Logo, but in many
             | languages it would raise scoping issues at the very least.
             | Procedures calls are not in general the equivalent of
             | textually cutting and pasting the procedure's code. Given
             | that Logo has dynamic scoping, perhaps it works - but
             | that's an issue in itself, dynamic scoping is hard to
             | reason about in general.
        
               | Jensson wrote:
               | In a brace language you paste the bracers as well and it
               | works, as long as all names are fully qualified and you
               | ignore visibility restrictions.
        
               | trealira wrote:
               | Most programming languages today don't have dynamic
               | scoping. Here's something you could do in a language that
               | had it.                 print_x() {           print(x);
               | }            foo(msg) {           let x = msg;
               | print_x();       }            main() {           let x =
               | "Hello!";           print_x();           foo("Goodbye!");
               | print_x();       }
               | 
               | In a language with dynamic scoping, this would print:
               | Hello!       Goodbye!       Hello!
               | 
               | With lexical scoping, most dynamically scoped code would
               | either be a compilation error, or it wouldn't work. In
               | this case, the language would complain that x wasn't
               | defined in the scope of "print_x()". With lexical scope,
               | you'd have to make x a global variable, and then the
               | function foo() would just be equivalent to calling
               | print_x().
        
           | hnlmorg wrote:
           | Logo is ostensibly a LISP, so the syntax might seem a bit
           | alien to modern developers used to C-style braces or ALGOL-
           | style declarations.
        
         | unconed wrote:
         | It seems the children's model is BASIC-like in that a function
         | call is just equivalent to "GOTO <#LINE>", and that the program
         | state is just the line number currently being executed.
         | 
         | The part that is missing is the stack. So I wonder what would
         | happen if you let them step through while showing the stack
         | state at every point. This would clue them in immediately that
         | there is nested control flow.
         | 
         | The part about alternative explanations is funny but just
         | reflects the fact that there is an element of the language not
         | reflected in the code, that they can't just reify visually
         | (unlike the instruction counter).
         | 
         | That is, the kid who inferred that there was an invisible
         | "demon"... was right.
        
           | Jensson wrote:
           | Old programming languages worked like that. Obviously less
           | useful, but easier to understand.
        
           | mark_undoio wrote:
           | Debuggers, though "one more thing to think about" whilst
           | learning do actually make things easier to understand for a
           | beginner.
           | 
           | I try not to introduce them too early because lots of
           | concepts at once gets frustrating - but eventually you get to
           | a point where it clearly would save stress to be able to step
           | and inspect state.
        
           | empressplay wrote:
           | Our version of Logo has both a step execution mode and a way
           | to follow execution in the editor, but I admit there
           | currently isn't a built-in way of showing how far down the
           | recursion rabbit hole an execution path has gone (I've put it
           | in the backlog)
           | 
           | https://turtlespaces.org/weblogo
        
           | _dain_ wrote:
           | _It seems the children 's model is BASIC-like in that a
           | function call is just equivalent to "GOTO <#LINE>"_
           | 
           |  _> The part that is missing is the stack._
           | 
           | Bingo. Function-call-as-GOTO and not knowing about the stack
           | are the root cause of so many confused questions on beginner
           | programming forums. You can spot it a mile away because they
           | tend to write functions without any parameters or return
           | values. Instead, they pass information around by mutating
           | global state everywhere. It's difficult to fit the idea of
           | parameters and return values into a mental world that doesn't
           | include a call stack, so their absence in novice code isn't
           | surprising.
        
             | Izkata wrote:
             | Beginners of any age.
             | 
             | A friend in college (Aerospace major) took an intro to
             | programming course in C, and was calling main() to get back
             | to the menu at the start of his program instead of using
             | any sort of loop. Was so confused why he had to choose
             | "quit" from the menu a whole bunch of times before it would
             | actually exit.
        
         | taneq wrote:
         | > Embedded recursion is much harder than tail recursion.
         | 
         | Tail-end recursion is just a way to express a loop. Yes, true
         | recursion is much harder to get your head around than a loop.
         | The fact that the loop is _expressed_ as tail-end recursion
         | doesn 't change the basic fact that loops=easy,
         | recursion=headache.
        
           | jrochkind1 wrote:
           | I mean it's a non-obvious-to-me interesting finding though
           | that people understood "loop expressed as tail-end recursion"
           | as easily loop expressed as loop though! Like it's not
           | obvious to me that their semantic equivalence would be
           | obvious to a beginner!
           | 
           | I don't remember finding tail-recursion easier to learn than
           | embedded recursion -- I do recall it being very confusing for
           | me to learn at first either way, but I can't recall exactly
           | what was in my head then, or how it was taught to me! It was
           | a long time ago. But I remember finding it tough to
           | understand.
        
             | sitkack wrote:
             | I think recursion in the tail position makes sense because
             | "you have to go somewhere", it is just another place to go.
             | Recursion in the middle is like starting over, so they
             | might think of it as a weird jump.
             | 
             | I'd love to teach kids to program, so many minds to run
             | (ethical) metacognitive experiments on! Once you understand
             | recursion, you never go back (and with tail recursion you
             | don't have to). :)
        
       ___________________________________________________________________
       (page generated 2024-07-11 23:01 UTC)