What Languages Fix

dbohdan 2014-06-16: What Languages Fix is an essay by Lisp hacker Paul Graham that gives various programming languages ha-ha-only-serious one-sentence summaries in terms of what they fix that was seen as wrong with previous programming languages.

The essay doesn't mention Tcl. How would you summarise Tcl, its alternative implementations, improvement projects and the like according to this format?

arjen - 2014-06-16 13:20:02

How about: Tcl: Because any way you look at it, everything is a string, so why not treat it that way?

PYK rewords arjen's submission:

There's really only one type of data

SEH: Since the aim of the original article was to highlight the immediate problem the language was designed to fix, how about: "It's too hard to write macros for repetitive tasks in C."

AMG, perhaps self-deprecatingly, perhaps seriously. On my Brush project: "Because Tcl is too simple to understand."

PYK: "Too simple to understand" hits the nail on the head regarding many of the misconceptions that are encountered on the Tcl learning curve. The trick is to tame the mind so that it is as simple as the language.

AMG: Brush retains the design of Tcl while moving towards the conventions and (high-level) data models taken for granted by users of more popular scripting languages. Naturally, this makes its design more complex. For example, Brush has rules for naming not only variables but also list and dict elements of their values. Paradoxically, this increase in design complexity should result in a decrease in usage complexity because (1) it's more in line with the user's existing mental model, and (2) there's no longer a need for separate commands for working on dicts versus lists versus arrays versus scalars.

Some comparison:

Tcl Brush
set a hello set &a hello
unset a unset &a
lappend a hello set &a{end+1} hello
lappend a hi there set &a{end:} (hi there)
lset a 5 hello set &a{5} hello
set a [lindex $a 5] set &a $a{5}
set a [linsert $a 5 hi there] set &a{:5} (hi there)
set a [list $b $c] set &a ($b $c)
set a [lrange $a 2 4] set &a $a{2:4}
set a [lreplace $a 5 5] unset &a{5}
set a [lreplace $a 5 7] unset &a{5:7}
set a [lreplace $a 5 7 hi there]set &a{5:7} (hi there)
set a [lreverse $a] set &a $a{end:0:-1}
dict append a b hello append &a(b) hello
dict incr a b incr &a(b)
dict set a b hello set &a(b) hello
dict unset a b unset &a(b)
dict lappend a b hello set &a(b){end+1} hello
dict lappend a b hi there set &a(b){end:} (hi there)
set a [dict keys $a] set &a $a{0:end:2}
set a [dict values $a] set &a $a{1:end:2}
set a [dict create a b c d] set &a (a b c d)
set a [dict get $a b] set &a $a(b)

Usage of the two languages diverges even further when doing more complicated compound operations like inserting an element into a list contained inside a dictionary key.

Tcl Brush
dict set a b [linsert [dict get $a b] 5 hi there]set &a(b){:5} (hi there)
lset a end [expr {[lindex $a end] + 1}] incr &a{end}

I'm not sure how appropriate it would be to discuss Brush further on this page. I just wanted to demonstrate Brush's thesis that simple isn't always simple, that adding complexity to the language can make it simpler to use. Many other examples are possible, for instance in the way Brush handles math, indexes, procedures, comments, and object lifetimes.