4 ms·
Hm ... I keep hearing about tcl and I'm aware Rebol and Tcl have some similarities, but I've never really looked that deep into it. Now I looked at the first ex
by middayc 2y ago
Hm ... I keep hearing about tcl and I'm aware Rebol and Tcl have some similarities, but I've never really looked that deep into it. Now I looked at the first example that I found (https://wiki.tcl-lang.org/page/A+little+stopwatch https://wiki.tcl-lang.org/page/A+little+stopwatch) and visually there really are many similarities. We also seem to use the same word-formatting combinations. I see ".word" "::word" { } and [ ] blocks. They are all probably used for different things, but it is funny. I really need to look at Tcl at some point.
I was a little discouraged by "everything is a string" idea so far, but I keep hearing that it is conceptually very interesting language.
- kragen 2y ago'everything is a string' is a fatal flaw in tcl, both in terms of bugproneness and performance. it does have some real advantages, though: serialization for storage, configuration, debugging, or networking is trivial, and it eliminates aliasing bugs, especially important for end-user programming independent of 'everything is a string', tcl also works much better as a command language than 'real programming languages' do; contrast ifup eth0 -ip 192.168.2.53 with ifup('eth0', ip='192.168.2.53') which is a real pain to type when you're in a hurry. but you could get that benefit by only making things strings by default; requiring [] or $ to get expression evaluation is conceptually independent of tcl's type system or lack thereof the rebol family seems like an improvement over conventional programming languages there, but at the cost of conceptual simplicity wrt guis in particular the ability to edit the gui without restarting it is pretty great. but this is a suboptimal way to edit it: .qd.ipentry configure -textvariable ip on the other hand, the ability to trigger code when a variable changes is pretty awesome (edited to clarify)
- amelius 2y ago> 'everything is a string' is a fatal flaw in tcl, both in terms of bugproneness and performance Also security I suppose. I'm thinking of injection attacks.
- kragen 2y agotcl's string interpolation semantics are much, much better than unix shell semantics, and i don't remember having seen a tcl string interpolation vulnerability along the lines of shell injection attacks and sql injection attacks and xss. still, it does seem like something to watch out for
- middayc 2y agoInteresting example. Now I maybe understand a little what is meant with everything being a string. Before, I didn't quite know the catch. Rebol went the opposite way for somewhat similar effect. It famously had (I think) 37 datatypes and a lot of them were also syntax types, like email, url, IP also I think. So your example could be something like this in Rebol: ifup/ip 'eth0 192.168.2.53 In Rye it's similar.
- wduquette 2y ago"everything is a string" hasn't been a serious performance issue since the release of Tcl 8.0 decades ago. I've written large, successful applications in Tcl/Tk. Granted, programming in the large in Tcl requires discipline and a good set of tools. (I used the Snit object framework, with SQLite as a data store.) As for command languages: yes, this is where Tcl really shines; nothing else is as good.
- kragen 2y agotcl 8.6.13 still has serious performance problems, although indeed 8.0 did improve the situation dramatically; it's on the order of 64× slower than native code in simple microbenchmarks like http://canonical.org/~kragen/sw/dev3/dumbfib.tcl http://canonical.org/~kragen/sw/dev3/dumbfib.tcl, which also means about 2× slower than cpython. its type system is a big part of the reason why compare†: : ~; time tclsh <<<'proc fib {n} { if {$n < 2} {return 1} else {return [expr {[fib [expr {$n - 1}]] + [fib [expr {$n - 2}]]}]}}; puts [fib 35]' 14930352 real 0m8.351s user 0m8.346s sys 0m0.004s : ~; time luajit -e 'function fib(n) if n < 2 then return 1 else return fib(n-1) + fib(n-2) end end print(fib(35))' 14930352 real 0m0.127s user 0m0.122s sys 0m0.004s even with the huge performance hacks added in tcl 8.0, it's only about 64 times faster than bash : ~; time bash -c 'fib() { if [[ $1 -lt 2 ]]; then result=1; else local arg=$1; fib $(($arg - 1)); local tmp=$result; fib $(($arg - 2)); result=$(($tmp + $result)); fi; }; fib 35; echo "$result"' 14930352 real 8m24.591s user 8m24.412s sys 0m0.028s which puts it about halfway in between shell scripts and native code that doesn't mean you can't write large, successful applications in tcl, even without any c extensions! a core i7 is about 17000 dhrystone vax mips http://www.roylongbottom.org.uk/dhrystone%20results.htm http://www.roylongbottom.org.uk/dhrystone%20results.htm while a pentium 166 was about 270 mips. so anything you could do with usable performance on a pentium you can do, with enough discipline, in pure tcl. it'll probably be a lot quicker to write than pentium assembly, too. and things like arrays (hash tables), regular expressions, sqlite, tk, etc., are of course enormously faster on a current computer, and you have a thousand times as much ram to play with and probably an ssd but you probably don't want to write your fractal renderer or real-time raytracer in tcl. by contrast, i've done both of those successfully in lua with luajit: https://gitlab.com/kragen/bubbleos/blob/master/yeso/mand.lua https://gitlab.com/kragen/bubbleos/blob/master/yeso/mand.lua https://gitlab.com/kragen/bubbleos/-/blob/master/yeso/sdf.lua https://gitlab.com/kragen/bubbleos/-/blob/master/yeso/sdf.lu... in terms of command languages, what do you recommend for getting good tab-completion in tcl? i don't know of any good options but that doesn't mean there aren't any; it probably just means i'm ignorant ______ †before wduquette's very helpful correction, I had: : ~; time tclsh <<<'proc fib {n} { if {$n < 2} {return 1} else {return [expr [fib [expr $n - 1]] + [fib [expr $n - 2]]]}}; puts [fib 35]' 14930352 real 0m59.757s user 0m59.736s sys 0m0.004s and while, in some sense, maybe my additional 8× slowdown here was kind of a performance effect of the everything-is-a-string type system, it's not an unavoidable one