Arc Forumnew | comments | leaders | submitlogin
2 points by akkartik 4369 days ago | link | parent

Thanks for posting this! I look forward to playing with an english version at some point.

Also, I'd love to hear more evidence/elaboration for the idea that Basic is easier to learn than Python or Scheme or Javascript.



2 points by mohamedsa 4369 days ago | link

Glad you seemed to like the post!

I don't have empirical evidence, but I think that the advantage of 80s basic for learning is that there are no hidden semantics that need to be known -- what you see is exactly what you get. No parameter passing, no local variables, no call/return (except in gosub, which is presented later), no blocks...Basic is - in a sense - like assembly language with math expressions and graphics.

More modern languages for teaching are usually very high level and focus on how to make cool things with the computer, but IMO they make the computer seem mysterious and complex, since the child knows that if they write that code so and so will happen, but don't understand how it happens. I think a language more resembling the computer's execution model is better to demystify programming.

-----

3 points by rocketnia 4368 days ago | link

"No parameter passing, no local variables, no call/return (except in gosub, which is presented later), no blocks...Basic is - in a sense - like assembly language with math expressions and graphics."

I think this kind of technical simplicity can also be found in concatenative programming (no parameter passing, no local variables, no blocks, no math expressions) or point-free functional programming (no local variables, no blocks, nothing but math expressions).

On the other hand, people who want to try teaching those styles can probably fashion their own library in Factor or Haskell that sets up the foundation they want to teach from. Those languages don't impose a lot of syntactic cruft.

---

"...they make the computer seem mysterious and complex, since the child knows that if they write that code so and so will happen, but don't understand how it happens."

I'd say real understanding isn't so easy to find among programmers.[1] Between JIT, predictive branching, optimizing compilers, and other such supercharging platform features, application programmers have long been willing to sacrifice an easy-to-understand code-to-mechanism mapping in favor of performance, even for imperative code.

Most of our high-level languages do leave things mysterious at some point, and in doing so, they save the programmer from peering into the insanity-inducing complexity underneath. :-p

Imperative languages have mystery as much as other languages, but sometimes their mystery matches up with the "how" questions we raise: "How does the computer begin to show a graphic on the screen" might be taken care of a single "begin to show a graphic on the screen" statement.

I think the "how" questions could be less imperative and more reactive: "How is the computer showing a graphic on the screen?" "How does the system know where the mouse is pointing?" In a reactive programming model, these questions could have corresponding mysterious primitives: "Sustain a graphic on the screen." "Watch where the mouse is pointing." When a programmer builds compound demands in terms of these, what else could it mean but to hold more than one demand at the same time? Concurrency is the intuitive default.

I think a programmer who can't say "how" a program works... simply hasn't built up a significant enough program to be worth explaining. They're still using mainly the primitives, whose "how" is mysteriously unanswered by the language.

Don't get me wrong, I'm happy you're making a language to help people teach programming, and I even think you're on a fine path sticking with the more mainstream and classic kinds of programming. I'm just hoping to debunk some assumptions and expand your horizons, either so you can change your direction or be even more confident where you are. :)

[1] Despite my know-it-all tone, I'm not volunteering myself as a counterexample, lol.

-----

2 points by mohamedsa 4368 days ago | link

I appreciate the horizon expansion attempt :)

When I was talking about "less mysterious and complex" I wasn't thinking about how a real CPU works, but how a programmable machine works.

My idea is that a language too high-level would make the child think of a computer as something having human-like behavior, that the computer just "knows" what to do when you talk to it. On the other hand a programming language with a well-known execution model and few assumptions would mean the child can know early how to map a language's syntax to its semantics.

Let's compare two programming languages for children, Logo and Kalimat. To print "hello" ten times in Logo:

repeat 10 [print "hello]

Here the child has to either assume the computer 'just knows'/be told "you'll understand later", or otherwise has to take some conceptual leaps in order to understand what's really happening:

* The stuff between [] is code not to be executed yet, a description of a future action to be applied

* This code is given to 'repeat'

* 'repeat' would apply this code as many times as needed

Now in Kalimat:

label top

x = 0

print "hello"

x = x + 1

if x<10 : goto top

Assuming the child already knows assignment 'if', and 'goto', the code here can be analyzed, traced, and adapted, without having to know little more than what is already known.

When the student becomes more confident, they can learn about 'for' and 'while', while being told that under the hood, those high-level constructs are pretty much the same as the previous version.

As for the many other points in your comment, I'll happily be re-reading them and pondering :)

-----

2 points by rocketnia 4367 days ago | link

  label top
  x = 0
I think these lines should be reversed. :)

(By the way, here are some terse formatting instructions: http://arclanguage.org/formatdoc. You can edit a post for about an hour after making it if you need to experiment.)

---

"When I was talking about "less mysterious and complex" I wasn't thinking about how a real CPU works, but how a programmable machine works."

Where do you make the distinction? These days I like to think of a machine as being any tool at all, and programming as being a way to control that tool by writing specification documents of what it should do.

If someone begins with no understanding of how a computer could work, maybe it makes things plausible to think there's an underlying mechanical device like a player piano reading a sequence of triggers off of a tape. But rather than focusing on that tape, I'd like to think it's also plausible to ground understanding in terms of writing the blueprints to that machine (parts of which may be tapes if necessary).

http://en.wikipedia.org/wiki/Analogue_computer

http://en.wikipedia.org/wiki/Fluidics

http://en.wikipedia.org/wiki/Electronic_circuit

I won't claim my own intuition works this way, but obviously some people work with this stuff. :-p

---

"Let's compare two programming languages for children, Logo and Kalimat."

I actually think you have apples and apples there and you're not comparing them as such. In Logo, if you want to solve 'repeat 10 [print "hello]' in a more complicated way, you can:

  to greet :numberoftimes
    if :numberoftimes > 0 [
      print "hello
      greet difference :numberoftimes 1
    ]
  end
  
  greet 10
(I just tested this code at http://www.calormen.com/logo/. It's my first Logo code. ^_^ )

I think both this and your Kalimat example involve more conceptual leaps than the "repeat" version. Here are just a few of them:

* The stuff after Kalimat's : or inside Logo's [] is code not to be executed yet.

* This code is given to "if".

* "if" applies this code if appropriate.

Beyond this, the student is challenged to understand user-defined names, arithmetic simplification, operator precedence, sequential execution, and bounded scope (in Kalimat's case, the kind of dynamic scope that arises from variable assignment).

On the plus side, it probably pays off best to choose an appropriate level of challenge for the student, and this is a good milestone (if not starting point), since the concepts are used together to solve a problem in a way that may help clarify all of them at once.

-----

3 points by mohamedsa 4365 days ago | link

In essence, my argument was

* How many concepts must be taught to the child before writing useful programs?

* How many of those concepts are right there, and how many are hidden?

I intuitively feel that Kalimat's example is just more simple and direct than the Logo equivalent, but "intuitively feel" and "just more simple..." are not very scientific; perhaps when Kalimat is more experimented with, we could have more empirical results.

But at least I can try to justify my feelings a little:

* The Logo example seems more nested while the Kalimat one is flatter. "Do this task, then that one" seems easier to keep inside one's head than do this task, which is made out of so and so.

* The Kalimat example completely avoids the need to teach function definition and invocation.

* The Logo code needs a discussion about variable scope and function activations; how :numberoftimes has a value in this greet different from that greet.

Yes, in Kalimat we'd have a related discussion about mutable variables, but a variable is an isolated concept that doesn't need to be explained alongside invocation and scope (at this level).

But again, you've made me look again at my assumptions and those of the Logo creators, and ask myself again and again about those assumptions; and that's definitely a good thing :)

-----

2 points by rocketnia 4364 days ago | link

"The Logo example seems more nested while the Kalimat one is flatter. "Do this task, then that one" seems easier to keep inside one's head than do this task, which is made out of so and so."

Surprisingly, I actually see your point. :-p For languages where "stepping" even makes sense, you can focus on explaining a very narrow window of the program, and then explaining another very narrow window of the program, following those steps. If the language is based on GOTO and simple variables, then the state of the program at any window is of a constant size, rather than structured into a stack or a tree.

Concatenative programming would pretty much lead to a stack-like growing and shrinking state right away (regardless of whether it takes shape as an actual stack).

The kind of programming I guess I'd call combinatoric programming (point-free functional, such as arithmetic expressions) would lead to a tree of partial results.

These systems could probably be broken down into even simpler subsets to limit the complexity, but probably not in a way that feels as open-ended as GOTO.

---

"The Kalimat example completely avoids the need to teach function definition and invocation."

The Logo example avoids the need to teach label definition and jumping. :-p

There's a little hiccup in understanding functions when GOTO's around. When I studied C after Applesoft BASIC, I remember being confused and curious about what would happen if I did a goto from one function to another. That's just an erroneous use of C's goto, and I think when I found that out, I got a little frustrated that anyone would program in a language with such arbitrary limitations. :-p

---

"Yes, in Kalimat we'd have a related discussion about mutable variables, but a variable is an isolated concept that doesn't need to be explained alongside invocation and scope (at this level)."

In case you missed it, the converse is also true: Invocation and scope could be introduced without introducing mutability. I can't say it's easier to do that, but it's at least independent.

Once again, I think there's some negative interplay between concepts here. Classmates from my intro programming classes found it nontrivial to grasp that passing a value to a function wasn't just the same thing as assignment to its parameter. That flawed interpretation worked pretty well until recursion came along. Even then, it was easy to repair the understanding by assuming it's a temporary assignment that reset itself after the function ended. Then they'd run into trouble when lexical scope came along, but... you know, that never came along. XD

Once I was out of the intro programming classes, they switched the intro curriculum from Java to Python. That means lexical scope might actually become relevant to the students before they learn another language... so I'm actually very glad in hindsight.

Eep, I'm not sounding like a history lesson of some sort, so for reference, my college days were 2005-2009. >.>; Pretty recent... but not as recent as I'd like, lol.

---

"But again, you've made me look again at my assumptions and those of the Logo creators, and ask myself again and again about those assumptions; and that's definitely a good thing :)"

Yeah, hopefully you feel justified in whatever you settle on. ^_^ Nothing's without downsides to me, so I don't tend to do value judgments, just a stream of personalized suggestions.

-----

3 points by jsgrahamus 4368 days ago | link

I liked the fact that you included easy graphics in your language. That is a way to immediately involve the student in a medium that they presumably already like and are acquainted with.

It reminds me of Logo, which was also targeted at youth, and included graphics primitives. I used it myself to create some drawings to help us hang pictures :=)

I wonder about some of your choices. The Goto in 1 example reminds me of spaghetti coding, and probably some of the early programs I wrote. Logo, on the other hand (http://en.wikipedia.org/wiki/Logo_%28programming_language%29), included other branching commands which lend to better programming practices. It also included parameter passing, etc. Might be good to take a look. Children are capable of amazing things.

-----

2 points by mohamedsa 4368 days ago | link

I decided when writing Kalimat to enable a teacher - if they so choose - to remove all sorts of abstraction and write code that resembles how it's going to run. When dealing with a child I think learning to code is more important than learning to code well, and removing all obstacles for that is a good design choice.

This way, the student can go directly into writing interesting programs using only if/goto/expressions. Later they can learn more disciplined forms like procedures or OOP, also included.

But I don't want to impose my ideas on users; if the teacher disagrees with me, they can completely ignore goto and use other control structures!

-----