We’re having quite an interesting discussion on the Hecl mailing list about the semantics and syntax of the language (since it’s in its early days, we get to do that!). I have some questions for those of you reading this, if you have time to comment.
Hecl inherits a lot of things from Tcl, which is both a simple, and amazingly flexible language. One of the things that Tcl lets you do is modify the value of a variable. For instance, set x [list 1 2 3] ; lappend x 4;
. However, what is at times confusing for people is that to get the value of a variable, you place a dollar sign in front of the variable: lindex $x 0
would return 1
for instance. To some people this is all quite intuitive, because commands that modify the variable take its name, which is then looked up in a hash table and fiddled with as needs be. So we have constructs like if { $n == 10 } { incr n }
. To other people, especially those who come from the Perl and PHP worlds, variables always have a $
in front of them, so the Tcl way of doing things doesn’t make as much sense. Even for experienced programmers, it can at times require a moment to recall how a particular command works. lappend foo ; lrange $foo ; lset foo ; lindex $foo
and so on. On the plus side, this is all very easy to implement, and really isn’t that difficult to figure out.
One avenue I’ve pursued with Hecl is to be able to pass references around, instead of variable names, so that all commands just take “a variable”: lappend $foo x
instead of Tcl’s lappend foo x
, and so on. For the moment, I’ve also enabled proc’s (user defined commands/functions) to receive references to variables passed to them, so they can modify them. This is both powerful, and dangerous:
set x 1
proc foo {v} {
set v [* $v 10]
}
foo $x
puts "foo is $x" ;# $x is now 10
(Well, not exactly, but that’s the general idea). We are considering ideas like marking the variables that may be modified in the proc definition to reduce the danger of people shooting themselves in the foot. In any case, it increases consistency, because commands that modify values always take a $variable. That still leaves commands like set foo 10
(others are proc
, foreach
, and catch
) that take variable names to be created, rather than $variable $references, so perhaps to someone who comes from the world of PHP, it’s still not as clear as it could be.
We’re also considering some radical changes, for the sake of not excluding any particular direction: taking a more lisp/ruby/python like approach, and not using dollar signs for variables (except perhaps in string interpolations). This has some slight disadvantages in terms of requiring quotes around more things (in Tcl, you don’t need to quote single world strings). This might result in code that looks something like this:
proc test {name code result} {
catch code res
if { eq res result } {
ok name
} else {
fail name res result
}
}
proc testfiles {files} {
global ok
global failed
# clear success/error list
set ok [list]
set failed [list]
foreach f files {
puts "Running $f"
source f
}
}
Which isn’t bad, although in some places, I think the added syntax of $ helps to make it clearer, at a glance, what’s what. eq $res $result is just that much quicker to pick out. This is especially true if you stash a command name in a variable.
In other words, set p puts ; $p "hello world"
might be a bit a bit clearer than set p "puts"; p "hello world"
, but… it’s definitely “eye of the beholder” territory, and depends on what you’re used to!
In any case, it’s been a very interesting process, and I’ve greatly enjoyed the company of Alexandre Ferrieux and Wolfgang Kechel on the list, as well as my friend Salvatore Sanfilippo. They’re all very bright guys with good ideas, which makes for lots of thought-provoking discussions.
Where you come in, if you’ve made it this far… is what kind of syntax and semantics you prefer, and why? Call by name? By reference? Modifiable values? Tell me what you think!