[Arjen Markus] (5 june 2003) The idea grew over breakfast in the hotel in Nuremberg, where [Clif Flynt], [Pascal Scheffers], [Richard Suchenwirth] and I stayed for the Fourth European Tclers' Meeting ([Andreas Kupries] stayed at the same hotel, but we were earlier to rise): let us develop a program that allows young children to learn how to program in a playful way. The basic principle is simple: * It is a drawing program where you type in commands * The graphics cursor is for instance a puppy dog * The commands can be simple or composite, so that the child will learn to think in structures Of course, over breakfast the thing grew into an intelligent life-form: as the child uses the program longer, the puppy would grow, increasing in size and showing different behaviour. Or what about ways to draw the actual lines and so on: wagging tail, sniffing on the ground, dropping droppings ... Basic (Tcl) commands are: * lines $thickn - set the line thickness * colour $name - set the colour for drawing * start line - record the current position of the graphics cursor * draw line - draw a line from the last stored position to the current one and store the current position * move $dist - move a certain distance * turn left|right - turn the direction over 90 degrees * draw circle - draw a circle * fill circle - draw and fill a circle The commands as shown above are a bit abbreviated and serve merely for the discussion (see below). A user will type in something like (in this case, a Dutch kid :): teken heel groot rondje This gets translated (using a very straightforward word-by-word approach) into: draw very big circle Which is in turn analysed as: command=draw object=circle attribute=big qualifier=very names={} numbers={} And run as the command: $command $object $attribute $qualifier $names $numbers (each actual Tcl command will have this signature) This way, our kid user can type: I want to draw a very big circle or: teken hier een grote cirkel (draw a very big circle here) This allows rather casual use of the commands with the possibility of ambiguity and misinterpretation... ''Question:'' should we try to repair typos? If so, what is a convenient way of doing this? ''Question:'' can we use [[msgcat]] for the translations? It is in some way going the other way around when compared to the usual use. ---- The code below translates Dutch sentences into Tcl commands like decribed above # kid.tcl -- # Some experimental code to translate sentences to commands # namespace eval translations { namespace export mc translate variable dictionary { {line obj lijn} {big attr grote groot} {small attr klein kleine} {circle obj cirkel rondje} {square obj vierkant} {draw cmd teken} {fill cmd vul} } proc mc {word} { variable dictionary foreach d $dictionary { if { [lsearch $d $word] > -1 } { return [lrange $d 0 1] } } return [list $word ?] } proc translate {line} { set words [split $line] set names [list] set numbers [list] foreach v {cmd obj attr qual} { set $v "" } foreach word $words { if { [string is double $word] } { lappend numbers $word } else { foreach {translated type} [mc $word] {break} if { $type != "?" } { set $type $translated } else { lappend names $word } } } if { $cmd != "" } { puts "$cmd $obj $attr $qual $names $numbers" } else { puts "$cmd $obj $attr $qual $names $numbers" puts "[mc "Unknown command:"] $line" } } } ;# End of namespace # # Test the above code namespace import translations::* puts [mc "teken"] translate "ik teken een grote cirkel" translate "vul klein vierkant" ---- Here are some basic drawing commands - nothing fancy yet and not hooked up to the translation procs ---- namespace eval drawcommands { namespace export colour thickness move turn draw start stop lines variable colour "black" variable thickness 1 variable posx 200 variable posy 200 variable dirx 1 variable diry 0 variable anchorx {} variable anchory {} variable prevx $posx variable prevy $posy proc colour { obj attr qual names numbers } { variable colour set colour $obj .draw itemconfigure "cursor-centre" -fill $colour } proc lines { obj attr qual names numbers } { variable thickness set fullword "$qual$attr" switch -- $fullword { "verythin" { set thickness 1 } "thin" { set thickness 3 } "thick" { set thickness 6 } "verythick" { set thickness 12 } default {puts $fullword} } } proc move { obj attr qual names numbers } { variable posx variable posy variable dirx variable diry variable prevx variable prevy set dist [lindex $numbers 0] set delx [expr {$dirx*$dist}] set dely [expr {$diry*$dist}] set posx [expr {$posx+$delx}] set posy [expr {$posy+$dely}] .draw move "cursor" $delx $dely .draw coords "anchor-line" $prevx $prevy $posx $posy } proc turn { obj attr qual names numbers } { variable posx variable posy variable dirx variable diry set oldx $dirx set oldy $diry if { $obj == "left" } { set dirx [expr {$oldy}] set diry [expr {-$oldx}] } else { set dirx [expr {-$oldy}] set diry [expr {$oldx}] } # TODO: rotate cursor } proc start { obj attr qual names numbers } { variable anchorx variable anchory variable posx variable posy variable prevx variable prevy if { $obj == "line" } { if { $anchorx == {} } { .draw create line $posx $posy $posx $posy -tags "anchor-line" .draw raise "cursor" } set anchorx $posx set anchory $posy set prevx $posx set prevy $posy } } proc stop { obj attr qual names numbers } { variable anchorx variable anchory variable prevx variable prevy variable posx variable posy if { $obj == "line" } { .draw delete "anchor-line" set anchorx {} set anchory {} set prevx $posx set prevy $posy } } proc draw { obj attr qual names numbers } { variable anchorx variable anchory variable posx variable posy variable dirx variable diry variable prevx variable prevy variable colour variable thickness if { $obj == "line" } { .draw create line $prevx $prevy $posx $posy \ -fill $colour -width $thickness .draw raise "cursor" set prevx $posx set prevy $posy set anchorx $posx set anchory $posy } } };#End of namespace # # Auxiliary proc to delay execution of the commands # proc delayed {delay body} { set time 0 foreach cmd [split $body "\n"] { after $time $cmd incr time $delay } } canvas .draw -width 400 -height 400 -background white pack .draw -fill both .draw create oval 195 195 205 205 -fill black -tags {"cursor-centre" "cursor"} .draw create oval 195 195 205 205 -outline black -tags "cursor" namespace import drawcommands::* delayed 250 { start line {} {} {} {} lines {} thick very {} {} colour green {} {} {} {} move {} {} {} {} 100 draw line {} {} {} {} turn left {} {} {} {} move {} {} {} {} 100 draw line {} {} {} {} turn left {} {} {} {} move {} {} {} {} 100 turn left {} {} {} {} move {} {} {} {} 100 draw line {} {} {} {} stop line {} {} {} {} move {} {} {} {} 100 start line {} {} {} {} colour red {} {} {} {} lines {} thick {} {} {} move {} {} {} {} 100 turn right {} {} {} {} move {} {} {} {} 100 draw line {} {} {} {} } ---- [Lars H] (6 Jun 2003): The idea that one should use [Tcl]/[Tk] for teaching programming to children has been on my mind for quite a while now. Many aspects of Tcl that seem strange to adult programmers are quite natural to a child: * Children shouldn't find [expr] prolix to use, because they spend several hours a week doing sums and know from recent experience that these aren't as easy as many other languages would make us believe. * Basic string operations ([split], [join], [string], etc.), on the other hand are rather easy to explain to a child, but prolix in more traditional computer languages. * The idea that [Everything is a string], in the sense that there isn't any information that is hidden from the string representation, is also something that should appeal to children. Magic might be fun to look at, but there is also the desire to get to know how the tricks are done. (Sometimes I even feel conspiratorial about the whole idea. If Tcl can be thought to the world's youth today, then in ten years time it will dominate the world!) I am however unsure whether the approach sketched above will be of much use. It is creating a sandbox language built up around a collection of features that are expected to suit the focus group, but there isn't all that much one can do with them. There is a definite risk that the command language (full sentences in the child's mother tounge) is considered too prolix in comparison with the effects one can get out of the thing controlled. One language which very much went that way is AppleScript (which can provide a surprising amount of control of one's Macintosh), but we haven't seen that used to teach children programming, have we? Thinking back to my own childhood, I didn't have any trouble with using Basic commands such as RESTORE even though I didn't understand it as an English word. Using full sentences in text based adventure games was OTOH not a goal; most commands followed a simple pattern, and more complicated constructions such as KILL TROLL USING SWORD felt overly complicated. A problem with basing command languages on natural language is that children will quickly be disappointed when the computer fails to understand perfectly valid natural language commands because the words aren't in the expected order or something like that. If they continue, they will discover that most of the details in the natural language are unnecessary and therefore stop including them, after a while arriving at the actual command language. However for the sake of imitating natural languge, the command language has probably sacrificed a lot of its power (control structures, variables, etc.) and then there isn't much point in having it. ---- [Setok]: "Me too". For quite some time I have been thinking about using Tcl to teach children to program. The way I see it, a language should be simple enough for children to program. If it's not, something needs to be done about it. I also don't believe in inventing an artificial language for children. Perhaps providing easy procs to make some things simpler (but then again, I also believe these procs should enter general use if they really are simpler). In fact, I usually hate tools which are made for educational purposes. I learnt a version of BASIC when I was 8. Sometime later I found the tortoise programming thing a waste of time. I'm sure other children could be the same. ----- I Thought that this was called [Logo] -- [JBR] [AM] I should read more about [Logo], I guess, but my intention is not so much a drawing language (isn't that what Logo is all about?) as well as a simple programming "language" that is more suitable for children than ____ (fill in any language you want). It is also my first - hm, no, second - attempt to use natural language in a programming context. (My first was an unsuccessful entry to the Obfuscated C Contest) ---- [Setok] Byt why? If the language is simple, and useful, why design it just for children? I'm not into pain and torture (much), so I want things as simple and easy as possible, child or not. I think some also underestimate the intelligence of children here. I doubt they will have any problems whatsoever in learning a command-oriented language. I didn't so why should today's children be any different? ---- [WHD] A couple of comments. First, regarding natural language--I think this would be a '''big''' mistake. Your "draw very big circle" seems nice and simple, but it's really very sophisticated. It's easy to use if someone tells you to type "draw very big circle", but you need a complicated mental model to know what other commands are valid. In other words, many commands that seem like they should be valid won't be, and many commands that are valid will be non-obvious. This doesn't aid understanding in the long run, however enchanting it might be in the short run. Instead, provide some basic primitives and a simple way to compose them, and the kids will eat it up. Second, regarding graphics a la logo--I'm with [Setok], defining a simplified language seems counter-productive to me. Tcl is already as simple as it needs to be for the job. On the other hand, a kid's not going to want to just play with a programming language; he's going to want it to do something neat. That means we need to provide a problem domain. I can think of several: * "Teletype"-like computer games, like the old BASIC Star Trek games, where the user interface is provided via INPUT and PRINT. This is a nice simple I/O model for kids to master. It's also so dated as to be refreshingly new. Tcl doesn't support this directly as nicely as you'd think. (I've done some work along these lines.) * A graphics world, a la Logo. Kids can use Tcl commands directly to draw things, and they can write new commands. A Turtle Graphics kind of system would be appropriate. (There are examples of this on the Wiki already, I believe). * Some other interesting simulation world, possibly with really fancy graphics, this is controllable by Tcl commands and amenable to scripting. A railroad train layout, for example, with lots of moving parts in addition to the trains. And then, when the kids want to do something else, they can use plain Tcl.