I've been made miserable by tcl for the past year and a half. Even after this long I still have to constantly refer to the manual because of what an inconsistent mess it is. There are people at the office who have been dealing with this crap for 20 years and still can't tell me off the top of their head the order of parameters to basic functionality functions. Tcl can burn in hell. I've learnt javascript recently and after a week I didn't need to refer to the manual. I think javascript is horrible but it's super easy to learn and use. Tcl should die and will die within my lifetime - all it's got is existing scripts forcing its continued use. Not a single person here would choose it over python or anything else if they were making the decision today.
Tcl is not elegant, it's simplistic. Just look at the ugly workarounds for language shortcomings like upvar. I'm not saying javascript is elegant (is anyone?) but it's less unwieldy, quicker to learn and immediately understandable to a c coder.
Paul_S prefers a language which is "immediately understandable to a c coder" - I think this gets to the heart of the disagreement here. Tcl is different. Anyone who expects it look like and work like C-family languages will always be frustrated and disappointed.
But people who are willing to take a less conventional approach may find that it opens up cleaner and more elegant ways of doing things. For example, upvar is not just a workaround - it can support meta-programming techniques which are not even possible in e.g. Python.
The "Tcl way" is to have a minimal core which just supports running commands and connecting them together. Everything else is implemented as commands, including the control constructs, and any command can be redefined. This flexibility does of course allow things to go wrong in ways that could not happen in a more restrictive language. But it also provides an adaptability that is hard to give up once you get used to it.
Tcl is great as an extension language for applications. There are several reasons for this. The most obvious one is the syntax. A Tcl function call looks how a normal command typed on the shell would look like. You quote variables, not values. So any Tcl function can invoked by the user as easily as you would have in a command interpreter. Consequently, Tcl is used in many applications for command input/scripting. Especially in chip design, which Tcl was created for (Tool Control Language). Tcl is also easy to link into your executable.
Finally, and RMS won't like that, Tcl being BSD-licensed means, that there are no challenging license terms for including it in closed-source projects, as most commercial applications.
"For these reasons, the GNU project is not going to use Tcl in GNU software. Instead we want to provide two languages, similar in semantics but with different syntaxes. One will be Lisp-like, and one will have a more traditional algebraic syntax."
The Lisp-like language is Guile, an implementation of Scheme. Was the "more traditional" language ever defined or implemented?
GtkBuilder and its schema doesn't have anything to do with scripting in GNU applications or Guile.
Vala is also not relevant.
What the GNU's statement above is about is an embedded scripting language for GUI application extensibility (to write things like editor plugins in, to provide scripting for a GUI app like GIMP, etc.).
GtkBuilder is a UI builder for Gtk apps with a XML-based serialization format. It solves a totally different problem.
Vala was an attempt to replace C and have a "modern-ish" language with first class GObject support. Again, solving a totally different problem.
FWIW, while in Tcl "everything is a string", that doesn't actually mean using things like numbers is slow. AIUI Tcl implementations actually use other datatypes behind the scenes as well, it just matches the semantics of "everything is a string". So if you take the string "1" and treat it as a number, Tcl will basically turn it into a number behind the scenes so it doesn't have to re-parse that number every time it's used.
Actually the "everything is (virtually) a string" approach has some beneficial effects. Keeping the underlying data structures compatible with this leads to using immutable values with copy-on-write, giving a very clean predictable semantics. I remember being shocked to discover that this did not apply in Python, where a value (not a variable) being used in one place can be modified by code elsewhere.
Perl does the same, by the way. A scalar variable can contain both a string and an integer representation.
But as always, Perl takes the joke too far, by allowing variables to have incompatible string and integer representations simultaneously ("dual variables" in Perlspeak). For example, the variable $! is equivalent to C's `errno` when evaluated as an integer, but equivalent to `strerror(errno)` when evaluated as a string.
I have reluctantly accepted that my colleagues are unlikely to ever "grok" Tcl. So they they wont accept me using Tcl for production code that someone else might need to maintain in future. However they are happy to use various development utilities that I can hack together in Tcl much more productively than with anything else :-)
RMS actually looked into Python after someone said to him that it's an accetable Lisp. Turns out he didn't concur - as do I. I did some years of professional Python development and it's a very nice language compared to most - but I do prefer Lisp as does RMS. Building an adaptable application container like Emacs in Python would be very hard to do.
Well, since "eq" is explicitly a string comparison operator in Tcl, use of it forces each argument to be evaluated as a string. Given that, what result would make more sense to you?
Python 2.7.12 (default, Nov 19 2016, 06:48:10)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for
more information.
>>> "1"==1
False
I don't even notice so many script language has "1"==1, that's interesting.
Stallman was criticising the lack of arrays etc in Tcl which stops it from being used for building complex applications. Tcl author John Ousterhout responded[1] to this by saying that Tcl is a mere glue language and not a replacement for C/C++ and we need both type of languages.
If you look at today's language landscape, you have langauges like C, C++, Java etc occupying the "serious" niche and languages like Python etc occupying the "glue" niche ( although sometimes these languages do exchange roles ). The "glue" languages that succeeded did have support for arrays etc.
I think both parties have been proven right, at least partially.
Ousterhout's response is awesome. More interesting and accurately predictive, I think, than RMS' (partly because he makes fewer predictions and merely suggests trusting developers to pick what they like).
I like RMS for what he's done for Free Software, but I rarely find myself agreeing with him wholeheartedly on technical questions.
> The "glue" languages that succeeded did have support for arrays etc.
For what it's worth, Tcl has had support for O(1) array indexing since 8.0 in 1997. That's because starting with 8.0, Tcl values had both an efficient internal representation and an external string representation. It's not a perfect solution, because it's not always transparent when (inefficient) transformations between representations take place, but it's definitely possible.
Think about JavaScript, which was added to browsers the following year, explicitly with the intent of being "just a tiny little scripting language." I'm not generally that much a fan of RMS but his counsel here seems pretty solid. As odd as JavaScript is, imagine trying to write the client-side code for gmail in Tcl.
He is correct in that Tcl's niche is too narrow to serve as a universal scripting language (though that, as John Ousterhout pointed out, wasn't really Tcl's goal to begin with).
But he was also mistaken (I think) in thinking that a universal scripting language would be both possible and a good idea.
In practice, needs and preferences are too diverse for one scripting language to serve them all equally well; also, language competition is a good idea.
The biggest problem that people had with Stallman's argument, I think, was that he was pushing the immature GEL/Guile as a replacement (and it would remain immature for years to come), while Tcl at the very least did its job well.
It's interesting to look back on things like this with the lens of history.
Tcl has arguably been as successful as Guile, but neither has exhibited longevity; both have been in decline for many years. Emacs has switched to Guile (maybe?), and Guile has gotten a major overhaul this decade (lots of smart people with a lot of experience like Scheme, so not a big surprise), but the other "high profile" projects using it are really not very high profile at all (Guix, Gnucash, GDB, all pretty niche projects with limited user bases).
Tcl got a lot of effort put into it by pretty big companies for a while, and it's actually a pretty good language, IMHO. It has significant limits, sure, but so did Guile for a long time. And real software has been built with both.
It almost feels like a personal vendetta rather than any significant technical reason, even though it's written as though, "Obviously, we should choose the technically superior extension language that, by the way, does not yet exist in a fully usable form."
Was there a licensing beef with Tcl, as well, or is it purely that RMS just really wanted everything to use Scheme?
I am not aware of any major application using Guile - even Emacs has not switched to it. Tcl might not be in the news every day, but it is very widely used. Tcl/Tk is still a very efficient way to make a cross-platform GUI application, and it is used for scripting in applications a lot. While the syntax of Tcl can be considered "funny", still most people seem to prefer it to Lisp. (Disclaimer: I am a professional Lisp programmer)
Yeah, I think Guile has basically been a failure on that front. I didn't want to be harsh, as it seems to be a well-maintained project by smart people...but, as extension languages go, it sure isn't doing much extending in the real world.
Sadly it is probably your only choice if you want a multithreaded extension language playing nice with a multithreaded main application. For all other extension languages I know, this is a huge hack that never works well in practice.
Well Tcl expects you to use an interpreter for each thread and pass messages between them, which is fairly easy. In Tcl 8.6 you also have the option to use multiple coroutines within one interpreter.
This avoids the Global Interpreter Lock problem that plagues Python. How does Guile handle that?
Guile doesn't. You'd use one interpreter and isolate whatever you need to isolate in it's own module and if you need things in parallel, you can just use pthreads (guile has proper threading support and no GIL).
If you don't cross the C barrier again from your scheme code you can even use something like guile-fibers for Concurrent ML-like parallelism.
How is Lua so popular in gaming if it can't do this? (I don't know much about Lua except it has a pretty solid niche in some industries, and gaming is one of them.)
I was reading the docs for Guile in this regard (https://www.gnu.org/software/guile/manual/html_node/Multi_00...), and even with language support, it seems like you still need to jump through some hoops to do the Right Thing in a multi-threaded program.
Seems like in any case, if I were using any of them in a threaded program, I'd want to isolate them from threads as much as possible. One of these days, in my Copious Free Time(tm), I'll take the time to actually look at an implementation to see how people have handled this problem. I wonder if any reasonably complete game engines use Guile, for comparison...
The only hoops I can see there is the regular caveats that apply to all parallel programming (don't introduce deadlocks, be careful: other threads might mutate the data you are currently using).
That applies only if you are executing guile code in parallel in the same interpreter and environment (or asynchronously accessing interpreter data) which is impossible in insert_other_embeddable_language_here.
You don't have to use embedded guile like that.
From my experience: if you want to embed a language and only need it in a single thread, it is just as easy to use lua. If you want several interpreters in isolated threads without any communication Lua is easily the simplest solution.
But if you need communication between multiple embedded language threads or interpreters you are better of with guile or TCL depending on what threading model you prefer.
I've been made miserable by tcl for the past year and a half. Even after this long I still have to constantly refer to the manual because of what an inconsistent mess it is. There are people at the office who have been dealing with this crap for 20 years and still can't tell me off the top of their head the order of parameters to basic functionality functions. Tcl can burn in hell. I've learnt javascript recently and after a week I didn't need to refer to the manual. I think javascript is horrible but it's super easy to learn and use. Tcl should die and will die within my lifetime - all it's got is existing scripts forcing its continued use. Not a single person here would choose it over python or anything else if they were making the decision today.
Not even remotely sure what you're talking about -- apart that you don't Tcl but are forced to maintain some project written in it.
TCL is an excellent language, and compared to the wildness that is the JS ecosystem, it's much more concise and elegant.
>Not a single person here would choose it over python or anything else if they were making the decision today.
You'd be surprised. I would like to be able to use it more.
By "here" I meant my office.
Tcl is not elegant, it's simplistic. Just look at the ugly workarounds for language shortcomings like upvar. I'm not saying javascript is elegant (is anyone?) but it's less unwieldy, quicker to learn and immediately understandable to a c coder.
Paul_S prefers a language which is "immediately understandable to a c coder" - I think this gets to the heart of the disagreement here. Tcl is different. Anyone who expects it look like and work like C-family languages will always be frustrated and disappointed.
But people who are willing to take a less conventional approach may find that it opens up cleaner and more elegant ways of doing things. For example, upvar is not just a workaround - it can support meta-programming techniques which are not even possible in e.g. Python.
The "Tcl way" is to have a minimal core which just supports running commands and connecting them together. Everything else is implemented as commands, including the control constructs, and any command can be redefined. This flexibility does of course allow things to go wrong in ways that could not happen in a more restrictive language. But it also provides an adaptability that is hard to give up once you get used to it.
Tcl is great as an extension language for applications. There are several reasons for this. The most obvious one is the syntax. A Tcl function call looks how a normal command typed on the shell would look like. You quote variables, not values. So any Tcl function can invoked by the user as easily as you would have in a command interpreter. Consequently, Tcl is used in many applications for command input/scripting. Especially in chip design, which Tcl was created for (Tool Control Language). Tcl is also easy to link into your executable. Finally, and RMS won't like that, Tcl being BSD-licensed means, that there are no challenging license terms for including it in closed-source projects, as most commercial applications.
"For these reasons, the GNU project is not going to use Tcl in GNU software. Instead we want to provide two languages, similar in semantics but with different syntaxes. One will be Lisp-like, and one will have a more traditional algebraic syntax."
The Lisp-like language is Guile, an implementation of Scheme. Was the "more traditional" language ever defined or implemented?
No, they went with an XML schema. GtkBuilder. Albeit Vala could be construed as a solution it does not handle UI directly.
XML didn't exist when Stallman wrote that. (guile did)
GtkBuilder and its schema doesn't have anything to do with scripting in GNU applications or Guile.
Vala is also not relevant.
What the GNU's statement above is about is an embedded scripting language for GUI application extensibility (to write things like editor plugins in, to provide scripting for a GUI app like GIMP, etc.).
GtkBuilder is a UI builder for Gtk apps with a XML-based serialization format. It solves a totally different problem.
Vala was an attempt to replace C and have a "modern-ish" language with first class GObject support. Again, solving a totally different problem.
Early Guile releases shipped with something called "ctax", but I can't find any example of what it looked like.
FWIW, while in Tcl "everything is a string", that doesn't actually mean using things like numbers is slow. AIUI Tcl implementations actually use other datatypes behind the scenes as well, it just matches the semantics of "everything is a string". So if you take the string "1" and treat it as a number, Tcl will basically turn it into a number behind the scenes so it doesn't have to re-parse that number every time it's used.
Actually the "everything is (virtually) a string" approach has some beneficial effects. Keeping the underlying data structures compatible with this leads to using immutable values with copy-on-write, giving a very clean predictable semantics. I remember being shocked to discover that this did not apply in Python, where a value (not a variable) being used in one place can be modified by code elsewhere.
Perl does the same, by the way. A scalar variable can contain both a string and an integer representation.
But as always, Perl takes the joke too far, by allowing variables to have incompatible string and integer representations simultaneously ("dual variables" in Perlspeak). For example, the variable $! is equivalent to C's `errno` when evaluated as an integer, but equivalent to `strerror(errno)` when evaluated as a string.
I have reluctantly accepted that my colleagues are unlikely to ever "grok" Tcl. So they they wont accept me using Tcl for production code that someone else might need to maintain in future. However they are happy to use various development utilities that I can hack together in Tcl much more productively than with anything else :-)
In the first reply in the thread, Barry Merriman asks a good question:
> Doesn't Python essentially provide what RMS wants? Why doesn't GNU just adopt Python as its defacto language?
Does anyone have an answer to this? (I scanned the first dozen or so messages, but did not find one.)
RMS actually looked into Python after someone said to him that it's an accetable Lisp. Turns out he didn't concur - as do I. I did some years of professional Python development and it's a very nice language compared to most - but I do prefer Lisp as does RMS. Building an adaptable application container like Emacs in Python would be very hard to do.
Then they could have added it as the language with the more traditional algebraic syntax.
I don't like "1" equal to 1 in Tcl :-/
Everything is a string in TCL. It's "scripting languages, the early years."
Well, since "eq" is explicitly a string comparison operator in Tcl, use of it forces each argument to be evaluated as a string. Given that, what result would make more sense to you?
It's not problem of 'eq':
Playing around a bit with tio.run--
Javascript:
Perl:
What's your preferred language?
PHP:
Most of my work use Python right now
I don't even notice so many script language has "1"==1, that's interesting.
I also find that in Javascript:
PHP:
Can distinguish this two type, but AFAIK, I can't do this in Tcl?
A major reason Java programs are generally quite robust IMO...
It's not dead yet :-) - Tcl/Tk 8.6.7 was just released - https://sourceforge.net/projects/tcl/files/Tcl/8.6.7/tcltk-r...
From Richard Stallman in 1994.
Timeless wisdom though.
Is it? Has he been proven right in this case?
Stallman was criticising the lack of arrays etc in Tcl which stops it from being used for building complex applications. Tcl author John Ousterhout responded[1] to this by saying that Tcl is a mere glue language and not a replacement for C/C++ and we need both type of languages.
If you look at today's language landscape, you have langauges like C, C++, Java etc occupying the "serious" niche and languages like Python etc occupying the "glue" niche ( although sometimes these languages do exchange roles ). The "glue" languages that succeeded did have support for arrays etc.
I think both parties have been proven right, at least partially.
[1] http://vanderburg.org/old_pages/Tcl/war/0009.html
Ousterhout's response is awesome. More interesting and accurately predictive, I think, than RMS' (partly because he makes fewer predictions and merely suggests trusting developers to pick what they like).
I like RMS for what he's done for Free Software, but I rarely find myself agreeing with him wholeheartedly on technical questions.
> The "glue" languages that succeeded did have support for arrays etc.
For what it's worth, Tcl has had support for O(1) array indexing since 8.0 in 1997. That's because starting with 8.0, Tcl values had both an efficient internal representation and an external string representation. It's not a perfect solution, because it's not always transparent when (inefficient) transformations between representations take place, but it's definitely possible.
Think about JavaScript, which was added to browsers the following year, explicitly with the intent of being "just a tiny little scripting language." I'm not generally that much a fan of RMS but his counsel here seems pretty solid. As odd as JavaScript is, imagine trying to write the client-side code for gmail in Tcl.
I don't see what feature JavaScrip has which would prevent implementing the same thing in Tcl
>As odd as JavaScript is, imagine trying to write the client-side code for gmail in Tcl.
OK, I imagine it. What would be the problem?
He has both good and bad points.
He is correct in that Tcl's niche is too narrow to serve as a universal scripting language (though that, as John Ousterhout pointed out, wasn't really Tcl's goal to begin with).
But he was also mistaken (I think) in thinking that a universal scripting language would be both possible and a good idea.
In practice, needs and preferences are too diverse for one scripting language to serve them all equally well; also, language competition is a good idea.
The biggest problem that people had with Stallman's argument, I think, was that he was pushing the immature GEL/Guile as a replacement (and it would remain immature for years to come), while Tcl at the very least did its job well.
Too bad Netscape didn't apply this philosophy when developing Javascript.
It's interesting to look back on things like this with the lens of history.
Tcl has arguably been as successful as Guile, but neither has exhibited longevity; both have been in decline for many years. Emacs has switched to Guile (maybe?), and Guile has gotten a major overhaul this decade (lots of smart people with a lot of experience like Scheme, so not a big surprise), but the other "high profile" projects using it are really not very high profile at all (Guix, Gnucash, GDB, all pretty niche projects with limited user bases).
Tcl got a lot of effort put into it by pretty big companies for a while, and it's actually a pretty good language, IMHO. It has significant limits, sure, but so did Guile for a long time. And real software has been built with both.
It almost feels like a personal vendetta rather than any significant technical reason, even though it's written as though, "Obviously, we should choose the technically superior extension language that, by the way, does not yet exist in a fully usable form."
Was there a licensing beef with Tcl, as well, or is it purely that RMS just really wanted everything to use Scheme?
I am not aware of any major application using Guile - even Emacs has not switched to it. Tcl might not be in the news every day, but it is very widely used. Tcl/Tk is still a very efficient way to make a cross-platform GUI application, and it is used for scripting in applications a lot. While the syntax of Tcl can be considered "funny", still most people seem to prefer it to Lisp. (Disclaimer: I am a professional Lisp programmer)
Yeah, I think Guile has basically been a failure on that front. I didn't want to be harsh, as it seems to be a well-maintained project by smart people...but, as extension languages go, it sure isn't doing much extending in the real world.
Sadly it is probably your only choice if you want a multithreaded extension language playing nice with a multithreaded main application. For all other extension languages I know, this is a huge hack that never works well in practice.
Tcl has also fully supported this use case since about 1998.
Not really. TCL didn't allow you to use one interpreter over several threads four years ago, and iirc TCL still isn't thread safe in that regard.
Guile does this with bravura.
Well Tcl expects you to use an interpreter for each thread and pass messages between them, which is fairly easy. In Tcl 8.6 you also have the option to use multiple coroutines within one interpreter.
This avoids the Global Interpreter Lock problem that plagues Python. How does Guile handle that?
Guile doesn't. You'd use one interpreter and isolate whatever you need to isolate in it's own module and if you need things in parallel, you can just use pthreads (guile has proper threading support and no GIL).
If you don't cross the C barrier again from your scheme code you can even use something like guile-fibers for Concurrent ML-like parallelism.
How is Lua so popular in gaming if it can't do this? (I don't know much about Lua except it has a pretty solid niche in some industries, and gaming is one of them.)
Lua extensions use coroutines instead of preemptive multithreading which is usually good enough.
Lua fully supports scripting in multiple threads i.e. multiple threads can each have a Lua context that runs scripts independent of the other threads.
Within a context you can run multiple coroutines but these are all run on the same thread and are cooperative.
It doesn't natively support sharing across multiple OS threads.
I was reading the docs for Guile in this regard (https://www.gnu.org/software/guile/manual/html_node/Multi_00...), and even with language support, it seems like you still need to jump through some hoops to do the Right Thing in a multi-threaded program.
Seems like in any case, if I were using any of them in a threaded program, I'd want to isolate them from threads as much as possible. One of these days, in my Copious Free Time(tm), I'll take the time to actually look at an implementation to see how people have handled this problem. I wonder if any reasonably complete game engines use Guile, for comparison...
The only hoops I can see there is the regular caveats that apply to all parallel programming (don't introduce deadlocks, be careful: other threads might mutate the data you are currently using).
That applies only if you are executing guile code in parallel in the same interpreter and environment (or asynchronously accessing interpreter data) which is impossible in insert_other_embeddable_language_here.
You don't have to use embedded guile like that.
From my experience: if you want to embed a language and only need it in a single thread, it is just as easy to use lua. If you want several interpreters in isolated threads without any communication Lua is easily the simplest solution.
But if you need communication between multiple embedded language threads or interpreters you are better of with guile or TCL depending on what threading model you prefer.
Some major applications using Guile include: Lilypond, Gnucash, GDB, Guix.
Those are large programs, and well done in my experience with the ones I've used, but not particularly mainstream (OK, GDB is widely used).