[HN Gopher] Why is Tcl syntax so weird (2013)
___________________________________________________________________
Why is Tcl syntax so weird (2013)
Author : blacksqr
Score : 138 points
Date : 2021-11-07 20:44 UTC (2 days ago)
(HTM) web link (wiki.tcl-lang.org)
(TXT) w3m dump (wiki.tcl-lang.org)
| AnonC wrote:
| I've seen Tcl used to write testing systems a long time ago, but
| never really worked with it.
|
| Tangentially, I found that the primary author of SQLite and
| Fossil SCM, D Richard Hipp, was also a core team member of Tcl.
| The server side of Fossil uses a minimal dialect of Tcl and the
| build/test system is built with Tcl. [1]
|
| [1]: https://fossil-scm.org/home/doc/trunk/www/fossil-v-git.wiki
| [deleted]
| bschwindHN wrote:
| My most miserable programming experience was with Tcl. It was
| used as a plugin language for a heat transfer application.
|
| Maybe it allows for some "clever" code or "powerful" concepts but
| for its use in that application, it was just not straightforward.
| It was used among a pretty large team and it just felt so messy
| and chaotic. At that scale I would want type checking and the
| ability to not have to think "okay is this a variable or is it
| getting interpolated in some other code, or what?"
| lmm wrote:
| As embeddable scripting languages go it's pretty
| straightforward IME? I agree that you probably want a safer
| language for building large systems (Tcl is significantly older
| than OCaml, which I'd argue is the language that popularised
| non-cumbersome type systems), but considered as a language in
| the Perl/Python/Ruby/Lua kind of space, Tcl is reasonably clean
| IMO.
| johnisgood wrote:
| Do any of you use tclsh as your shell?
| cmacleod4 wrote:
| Tclsh is not really suitable for use directly as a general-
| purpose shell. TkCon gets a bit closer - https://wiki.tcl-
| lang.org/page/Tkcon - but still not great, e.g. if you start a
| long-running program you will only see its output when it
| terminates.
|
| I wrote a semi-graphical general-purpose shell in Tcl/Tk for my
| own use - https://wiki.tcl-lang.org/page/gush . I used this as
| my main shell at work for 12 years, and only stopped because I
| retired last year.
| tracnar wrote:
| The Tcl wiki is quite strange, it has interesting content but
| most pages are discussions like this one and it's hard to find
| what's relevant or even correct.
|
| What's weird about the Tcl syntax is that there is barely any.
| It's very dynamic so only the top-level of a file is parseable as
| a list of commands, anything else like a procedure depends on the
| implementation of the command which can be overridden at any
| time.
|
| It's even used by built-in commands like expr and if which
| essentially implement a mini expression language which is
| different from Tcl.
| rodgerd wrote:
| It's an accessible Lisp with square brackets.
| mek6800d2 wrote:
| Really. It's been a couple of decades, but when I used to do
| a lot of Tcl programming, I too noticed that coding in Tcl
| had a certain Lispish quality to it.
| int_19h wrote:
| Not really. References are pretty fundamental to Lisp, but
| are (at best) bolted on in Tcl.
| natrys wrote:
| I have been writing some Tcl for the last couple of years,
| mostly in place of shell scripts. Going to Tcl wiki is always a
| surreal experience. I think this old comment captured it
| perfectly:
|
| https://news.ycombinator.com/item?id=9098859
| blacksqr wrote:
| Equal time:
|
| https://news.ycombinator.com/item?id=9102916
| kevin_thibedeau wrote:
| That's what wikis originally were. Wikipedia's curated ontology
| is an exception that only looks like the rule because most OG
| wikis have died off.
| lifthrasiir wrote:
| That is true but doesn't fully explain the OP's "what's
| relevant or even correct" bit. The truth is that OG wikis
| needed a special kind of moderators---affectionally called
| WikiGardener or even WikiMaster---who clean up things and
| deal with conflicts without removing values provided by prior
| authors but possibly removing the contents themselves. If
| this sounds absurd that's because it does; it is waaay harder
| to maintain than typical forums and even encyclopedic wikis
| popularized by Wikipedia. And without those kind of hard and
| thankless moderation non-encyclopedic wikis generally end up
| with being a dump of uncurated informations.
| emodendroket wrote:
| Emacswiki is one active one still like that and the effort to
| replace it with MediaWiki was ultimately abortive. C2 is also
| big but I think mostly dead.
| ljm wrote:
| for {set sum 0; set counter 0} {$counter < 10} {incr
| sum $counter; incr counter} {}
|
| It's amusing how that pattern was adopted in Javascript (well,
| C/Java really I guess) as an optimisation. for
| (var sum = 0, counter = 0; counter < 10; sum = counter++) {}
| Koshkin wrote:
| But your JS code has a bug in it while the Tcl code does not.
| Animats wrote:
| Tcl is too much like shell script programming. It's one of those
| "take one basic concept and use it for everything" systems.
|
| Could be worse. Could be Forth.
| dmux wrote:
| >Tcl is too much like shell script programming.
|
| How so? Tcl has namespaces, a standard lib, runtime
| introspection, an OO system, threads, asynchronous programming
| capabilities via event loop, a GUI framework and is cross
| platform. Have you actually used it?
| johnisgood wrote:
| Who remembers Eggdrop, the IRC bot?
|
| https://en.wikipedia.org/wiki/Eggdrop
|
| https://www.eggheads.org
|
| https://www.tclarchive.org (Blast from the past!)
|
| I was surprised to see that it is still under development.
|
| After Eggdrop, it was Supybot that got really popular, although
| it is written in Python.
| lilyball wrote:
| I've always loved Tcl because of its absolute purity and
| simplicity at the language level. I love how you can implement
| your own control flow operators that look like built-in ones. I
| love how easily you can make DSLs.
|
| I just wish there was a Tcl that was redesigned from a modern
| perspective. Give me first-class lambdas. Give me unnamed objects
| that get destroyed automatically (with a callback) when out of
| scope[1] so I don't have to use a weird namespace hack to make
| the object and rely on the caller to invoke the destroy method.
| Give me a stdlib that offers more functional stuff. Heck, give me
| async/await. And more too.
|
| But even without all of that, Tcl is still a wonderful language
| and I often lament how it's mostly died out.
|
| [1] There's at least one library I've used that actually does
| this, but AFAIK there's no way to do this in pure Tcl so it must
| be a feature of the C API. Also I'm not sure if it actually
| tracks the object or just the variable it's assigned to.
| CornCobs wrote:
| I believe a lot of what makes Tcl the way it is is precisely
| because it does things different from most other languages with
| regards to closures, lambdas, scoping etc.
|
| If Tcl had the other stuff, would it need upvar/uplevel or its
| funny braces and substitution rules? I'm no expert at Tcl but
| when I learnt it (mainly to use tkinter) I really had to rewire
| my brain to think about something as simple as _variables_ so
| differently
| valenterry wrote:
| Checkout Scala. It allows you to do pretty much the same, i.e.
| the syntax is so flexible that you can even make 'puts "Hello
| World!"' work and implement your own "if" that looks like the
| builtin one. It also has first-class lambdas and the other
| stuff that you asked for, but obviously there are also
| differences.
| lilyball wrote:
| Scala runs on the JVM, which makes it not at all suited for
| scripting. Scala also seems to have something of a
| racism/white supremacy/misogyny problem.
| Koshkin wrote:
| Why do you say that the JVM is not suitable for scripting?
| valenterry wrote:
| > Scala runs on the JVM, which makes it not at all suited
| for scripting
|
| The JVM is one target. You can also generate and run
| javascript code or create a native binary. But it will not
| be as smooth as e.g. python, so I can't really recommend
| that.
|
| > Scala also seems to have something of a racism/white
| supremacy/misogyny problem.
|
| I'm a member of that community for a long time and I really
| don't think so. I always thought the Scala community was a
| rather welcoming one. There certainly have been incidents
| in this community, just like they have been in other
| communities, but I don't think "Scala" has more of a
| problem here than any other language.
| mrbukkake wrote:
| >Scala also seems to have something of a racism/white
| supremacy/misogyny problem.
|
| lol what
| J-Kuhn wrote:
| Just [trace add variable unset]. Can be done from a script.
| tverbeure wrote:
| Tcl has been used for decades as the language of choice in the
| electronic design automation world.
|
| I often lament how it has _not_ died out. It 's demise is long
| overdue...
| nomel wrote:
| > as the language of choice
|
| I'm not sure that's an appropriate phrasing. The word
| "choice" implies that alternatives are available, and there a
| decision was part of the selection. I think "Has been used
| for the language that momentum has demanded" might be more
| accurate. ;)
| kevin_thibedeau wrote:
| Synopsys used to have their own scripting language that was
| so limited you couldn't define functions. You had to resort
| to setting variables as pretend arguments and continually
| including another script for any code you needed to invoke
| multiple times without duplication.
| pjmlp wrote:
| I love the language as well, we did lots of cool stuff with Tcl
| in 1998 - 2003, we were already doing our own Rails, but a tiny
| startup in Lisbon does not rock the world the same way.
|
| However that experience lived on and gave birth to OutSystems.
| int_19h wrote:
| You can't really get full-fledged closures without ditching the
| fundamental concept of Tcl, which is that "everything is a
| string". It's the same problem as OOP, or rather, object
| lifetime management - you can have that in Tcl, but only as
| long as you manage the lifetimes manually. For closures, this
| negates most of the benefits they provide.
| lilyball wrote:
| It would work if they basically copy the current value of the
| identifiers (i.e. by-value, not by-reference). Or by
| capturing the procedure context. You can synthesize the
| variable capture by hand but that would indeed force
| everything into a string, which is a potential performance
| issue and would also break any sort of automatic lifetime
| management.
|
| Even just making it easier to have lambdas reference
| variables from their creation scope while the creation scope
| is still on the stack would be an improvement. Today you can
| use [info level] and then construct a lambda body that uses
| [upvar #$level ...] to reference variables from the original
| scope, but it's a PITA. Or you could cram the level into a
| temporary namespace variable to avoid having to manually
| construct a body string, but it's still a PITA.
| pooryorick wrote:
| [list apply {args body} $value1 $value2 ...] can be used to
| capture values without actually generating a string because
| even though conceptually a list is a string, it's actually
| stored internally as a list.
| int_19h wrote:
| The basic problem is, how do you even know that something
| is a variable reference? Remember, _everything_ is a
| string. This means that the body of the lambda is also a
| string. Now you can require that it 's an eval'able string
| at the point of creation, and parse it to identify any $var
| references. But you can only do that for the topmost level
| of the lambda, because it can contain nested strings - and
| you don't know which of those strings are code, and which
| aren't (since it's really the command to which the string
| is passed that decides to treat something as code or not).
|
| Furthermore, if you process $ like that, this won't work
| for any other command that takes a variable name as an
| argument, and does something to it.
| rightbyte wrote:
| > The basic problem is, how do you even know that
| something is a variable reference?
|
| Isn't that by convention? Like there is a "upvar" to grab
| values of the prior stack.
| int_19h wrote:
| "upvar" is explicit, there's no guesswork involved there.
| But how would you handle a lambda with a body like this?
| if {$foo == 1} { puts $bar } else { puts $baz }
|
| given that all the {}s are just non-expanded string
| literals, and what makes them be interpreted as code is
| the implementation of "if"? Sure, you can hardcode "if";
| but the whole point of Tcl is that syntax constructs like
| that can be easily implemented as a library, which breaks
| if you have to special-case them in lambdas for them to
| work.
|
| Now if you used upvar, this kinda sorta works, but only
| so long as the lambda is immediately invoked by the
| function that it was passed to. If you want to pass it
| on, you'd have to wrap it in another lambda. And, of
| course, this only works for lambdas that don't escape.
| verifex wrote:
| It's not dead yet. There's still AOL Server [1] and there's at
| least one game [2] that uses TCL that is online. :)
|
| 1. http://www.aolserver.org/ 2. http://www.carnageblender.com/
| doublerabbit wrote:
| Long live aolserver, Naviserver [1] is the fork that's still
| in very active development.
|
| 1. https://wiki.tcl-lang.org/page/NaviServer
| Animats wrote:
| _I've always loved Tcl because of its absolute purity and
| simplicity at the language level. I love how you can implement
| your own control flow operators that look like built-in ones._
|
| Have you ever had to debug code written by someone who
| implemented their own control flow operators? Not fun. I've
| seen it done with C macros. Don't do that.
| anyfoo wrote:
| A poor choice in C indeed, but languages like Haskell or (it
| seems, don't know much about it myself) TCL are practically
| made for it. Debugging "own control flow operators" is
| nothing very special there, mostly because control flow
| operators themselves aren't very special in those languages.
|
| From another way to look at it, nobody seems to bat an eye
| when using things like items.forEach() in, say, Node.js, even
| if this sort of thing is arguably much uglier to do in
| JavaScript vs. a "first class" functional language where
| common control flow operators are often just plain functions
| themselves.
| rectang wrote:
| Dynamic scoping (`local $foo`) is nothing special in Perl.
| It's also a construct which, like novel flow control
| operators, by its nature leads to code which is complicated
| to reason about and difficult to debug.
|
| There are many programming language concepts which may be
| innovative and beautiful, but whose popularity wanes
| because of practical flaws. (EIAS is another.)
| fiddlerwoaroof wrote:
| Dynamic scoping, combined with variable naming
| conventions, is a beautiful way to achieve "dependency
| injection" with a minimal amount of complexity.
|
| Like any feature, it can be abused, but it can be very
| elegant.
| RHSeeger wrote:
| There is a world of difference between writing a control
| structure in C using macros... and Tcl. And even more so when
| you look at a proper Lisp. Being able to construct new
| control structures is amazing; I miss it when in other
| languages.
| johnisgood wrote:
| I re-implemented the wheel in Forth, too, before! :)
| arthurcolle wrote:
| That sounds hilarious though
| Kosirich wrote:
| I totally got turned around on TCL. I hated it when I started
| as I was mostly programming in c#, but now after year of
| sporadic use I absolutely love it for it's simplicity when
| manipulating text files and strings.
| specialist wrote:
| Imagine the timeline where Tcl, Scheme, xlisp, or any of the
| dozen other existing, mature, available, non-turrible
| programming languages was chosen for DHTML.
|
| Versus the poorly conceived, poorly implemented, from scratch
| rush job based on a fundamental misunderstanding of Self.
|
| In fact, we could have ended up with Self. Imagine that
| timeline.
|
| Worst is better.
| pcwalton wrote:
| The Web would definitely not be better had Tcl been the
| language of the Web instead of JavaScript. At least JS has
| working closures.
| [deleted]
| teleforce wrote:
| Tcl is one of the most underrated programming languages. I have
| a friend who is working at Intel as tool development engineer
| (equivalent to software engineer), and Tcl is being used
| extensively at Intel for chip tooling and design since a very
| long time.
|
| The modern version of Tcl will be great and a seamless
| integration with the OS shell will probably the killer niche
| application. Hopefully Oil Shell can modernize Tcl to some
| extent and incorporate the best features of Tcl with excellent
| OS shell integration capabilities.
| enygmata wrote:
| Tcl is also at the heart of some F5 Networks products
| tictic wrote:
| My team and I write TCL based iRules for F5 devices. We do
| it a couple of times a week. They are a very nice tool.
|
| Sometimes we've had to use it like an emergency super power
| to patch http applications on the wire.
|
| The reason why some financial institutions are working
| right now is because of some iRules we wrote a couple for
| years ago.
|
| If your company uses F5 boxes, you should befriend your F5
| admins.
| tverbeure wrote:
| As a tool development engineer, it's only normal that your
| friend is using Tcl extensively: there is no other option.
|
| The real question is: would they still be using it when given
| the choice?
|
| For me, Tcl is a cancer that just doesn't want to die.
| evancox100 wrote:
| I feel like there is an opening for an EDA company or
| startup to really embrace Python and provide a Python
| interface / command line to their tooling.
| kimmeld wrote:
| Replace one cancerous language with another one. Please
| no.
| anyfoo wrote:
| python never seemed like a good fit for me, because it's
| just not suited for DSLs. It's too imperative and has too
| much built in syntax, you'll end up in callback hell as
| soon as you need an actually descriptive DSL.
| synergy20 wrote:
| Tcl is deeply rooted in EDA and chip design industry, too
| many code were written with it. It's like C++, no matter
| how fancy/modern rust is, there is no way it's going to
| replace C++ for the next few decades.
|
| One way is to provide Python(python stdlib might be
| enough for simplicity) gradually, e.g. providing a Python
| binding for Tcl so for the future, you can write all new
| piece in Python, and it is either used directly or
| converted to Tcl behind-the-scene.
| tverbeure wrote:
| I don't think that opening is there. Tcl may be a
| terrible scripting language, its usage is not a factor in
| the value of this or that EDA tool.
|
| If a startup wants to displace an entrenched tool from
| Synopsys or Cadence, the underlying algorithms (millions
| of lines of C++ code) must be better. (And once that
| happens, they'll be acquired by one of these 2.)
| evancox100 wrote:
| I think you are probably right, it is not a make or break
| factor. Especially when it comes to back-end flows,
| PPA/TAT/capacity/design closure are the key metrics and
| the big 2.5 have large moats in these areas.
|
| On the front-end side though, areas like verification,
| debug, and various lint checks, I think there is more
| opportunity for smaller players to introduce point tools
| with better customizability & scripting interfaces.
|
| Ultimately I think the industry is stuck in a local
| maximum, where the frictional costs of rethinking overall
| methodology, e.g. from SystemVerilog to Chisel, is too
| high to justify the change, even if the end result would
| be marginally (or greatly) better. (Not an endorsement of
| Chisel, just an example.)
| _ph_ wrote:
| There is Python support in some EDA frameworks, but
| especially in the digital domain, Tcl is still the gold
| standard. On the one side this means there are tons of
| Tcl code around and any experienced engineer is well
| versed in Tcl. Also, electrical engineers are usually
| very focussed on electric engineering. While being being
| very intelligent, they are often not into programming, so
| keeping things very simple is an advantage to them.
| tails4e wrote:
| May be true of analog EEs, but more than half of EEs I
| work with, and all the good ones, can script well. They
| use perl/python for day to day, and tcl to interact with
| tools. The number who can use tcl well is a lot lower
| than those who can script in general though
| tails4e wrote:
| All EDA uses tcl, so no surprise Intel would too. A while
| back I saw some vendors tried to make perl or python an
| option, but tcl is the de facto language in this space those
| vendors often abandoned the having multiple scripting
| interfaces and fell back on tcl. It's quirky, but functional.
| I like the one line composability
| BeetleB wrote:
| Tcl's usage at Intel is not particularly special. Perl/Tcl
| were the workhorses of most (hardware) engineering companies.
| Back in 2010, a close friend who was working for one such
| company said that putting Python on your resume won't help
| you as none of the managers had heard of it. When I joined
| work around that time, I discovered he wasn't exaggerating
| much.
|
| While Tcl may be a particularly good language for somethings,
| well over 90% of the teams I've found using it do so for
| legacy reasons, and they correlate very highly with poor SW
| engineers with even poorer SW practices. When I interview for
| jobs, I steer clear of any that lists Tcl. Not because of the
| language, but because it's a fairly useful signal about the
| quality of the team.
| lilyball wrote:
| I haven't gotten around to looking into Oil Shell. Is it
| actually drawing any inspiration from Tcl? The "A Tour of the
| Oil Language" page[1] references Ruby and Python but not Tcl.
|
| [1] http://www.oilshell.org/release/latest/doc/oil-language-
| tour...
| teleforce wrote:
| Not yet but I've mentioned to Andy (Oil Shell author)
| regarding the importance of adding command features into
| Oil Shell and he is actually looking into it [1]. Hopefully
| he will draw some inspirations from Tcl. Imagine a Cisco
| like networking command wrapper on top of Linux OS with
| eBPF backend. It will turn Linux into a ready-made
| formiddable open source networking OS without the need for
| NX-OS [2].
|
| If you are looking into a modern version of Tcl, there is
| TIL [3]. It's a Tcl inspired new scripting language on top
| of D language. By having D language as the foundation it
| can perform all the features that you've requested
| including lambdas, async and then some more [4].
|
| [1]https://news.ycombinator.com/item?id=28552998
|
| [2]https://en.wikipedia.org/wiki/Cisco_NX-OS
|
| [3]https://news.ycombinator.com/item?id=27167762
|
| [4]https://dlang.org/spec/expression.html
| lilyball wrote:
| TIL looks interesting, but also both too simple and too
| complicated. What's the difference between a SubList and
| a SimpleList? Why does it require SimpleLists instead of
| using variadic arguments (e.g. why [math ($a + $b)]
| instead of [math $a + $b])? And why does the author
| explicitly disallow multiple spaces in a row outside of
| indentation when this is a purely artificial limitation
| and does not simplify anything?[1]
|
| But also, why can't I write modules in TIL? It's based on
| D, sure, but I shouldn't need to write and compile
| something in D just to be able to have some means of
| namespacing things. This very much feels like "I want to
| write most of my stuff in D but I just want to be able to
| whip up short scripts that for whatever reason I don't
| want to write in D".
|
| And of course it seems to be ditching the pure simplicity
| of Tcl. It's like Tcl in that it's a command language and
| borrows syntax from Tcl, but it seems to be missing the
| fundamental concepts of Tcl.
|
| [1] The author seems to hate the idea of people lining up
| equals signs in code or things like that. Ok sure, you
| can have a style preference. But that's what a code
| formatter is for, not an artificial and unprecedented
| level of whitespace significance.
| zamadatix wrote:
| I used a lot of TCL for stuff in the legacy networking space
| and while the language always seemed to be easy to reason
| about I seem to remember my main frustration was tracking
| down syntax errors as runtime problems. Dunno if I was just
| using the tooling wrong though.
| blacksqr wrote:
| Re [1]: the libraries that delete an object when it goes out of
| scope use Tcl's built-in "trace" command, which lets you
| execute code when a command terminates or when a variable is
| deleted, among other events. So no, it's all done in pure Tcl.
| lilyball wrote:
| Oh it looks like I misremembered. I thought the API I had
| used was something like `set doc [foo parse $input]` and the
| document would go away when the variable does. I found it,
| it's the tDOM library, and it was actually `dom parse $xml
| doc` that does the automatic freeing, whereas `set doc [dom
| parse $xml]` requires manual deletion. So it probably is
| using trace.
| rkeene2 wrote:
| This is how the "defer" [0] command (from tcllib) in Tcl
| works.
|
| [0] https://core.tcl-
| lang.org/tcllib/doc/tcllib-1-19/embedded/ww...
| coldtea wrote:
| > _I've always loved Tcl because of its absolute purity and
| simplicity at the language level. I love how you can implement
| your own control flow operators that look like built-in ones._
|
| Then you will like Lisp, Smalltalk and Forth!
| isr wrote:
| > I just wish there was a Tcl that was redesigned from a modern
| perspective. Give me first-class lambdas. Give me unnamed
| objects that get destroyed automatically (with a callback) when
| out of scope[1] so I don't have to use a weird namespace hack
| to make the object and rely on the caller to invoke the destroy
| method.
|
| If you take a look at jimtcl (minimalistic reimplementation of
| tcl, started by antirez - he of redis fame), it did take some
| steps towards the above.
|
| - unified arrays with dicts
|
| - proper lambdas
|
| - (sort of) closures
|
| In many ways, I personally feel its a shame that jimtcl has
| felt the need to tie itself down to tcl-compatibility as much
| as it has. A few more warts could have been fixed along the
| way.
|
| Anyway, check it out. It's manpage is quite comprehensive
| sigzero wrote:
| I love Tcl. The community is awesome as well.
| int_19h wrote:
| While we're at it - Tcl-like languages make for pretty decent
| embedded scripting solutions if performance is not a major
| requirement. There's one called LIL that's literally just a
| single .c file (and the accompanying header) for ease of
| embedding:
|
| http://runtimeterror.com/tech/lil/
| pmarin wrote:
| My favorite implementations are partcl[1] (600 lines) and
| Picol[2] (500 lines by Salvatore Sanfilippo).
|
| [1] https://github.com/zserge/partcl
|
| [2] http://oldblog.antirez.com/post/picol.html
| int_19h wrote:
| So far as I can tell, the reason why they're so small is
| because they implement "everything is a string" literally -
| so e.g. appending to a list is basically concat. This is good
| enough as a proof of concept, and neatly showcases just how
| simple the language itself really is; but perf would be
| abysmal even by Tcl standards as soon as you get more than a
| few dozen items per list.
|
| LIL tries to be a minimalist but _practical_ embeddable
| implementation, so it has basic optimizations like
| representing lists more efficiently internally. The price, of
| course, is code size, but also C API complexity.
| juxtapose wrote:
| Tcl is a better shell scripting language. Tcl's escaping is
| simple and consistent, while bash is almost impossible to grok --
| just too many implicit rules to fit in my head.
| [deleted]
| cmacleod4 wrote:
| I wrote a blog post last year trying to explain the under-
| appreciated radical minimalism of Tcl, and in particular the
| decoupling of syntax and semantics - https://colin-
| macleod.blogspot.com/2020/10/why-im-tcl-ish.ht...
| marttt wrote:
| Great read, thanks! It also received 100+ comments on HN:
| https://news.ycombinator.com/item?id=24897326
| maybe_pablo wrote:
| I find this Tcl quine quite amazing: join {{} \{
| \}} {join {{} \{ \}} }
|
| I think it tells a lot about the weirdness and awesomeness of the
| language at the same time.
| celeritascelery wrote:
| > Tcl is a macro language, it derives from macro-assemblers, the
| C preprocessor, and older, text-oriented languages like TRAC
|
| Then why doesn't it have macros? This is one of my biggest
| complaints with tcl, the other being that you have to escape
| newlines in forms. This makes much less pleasant then lisp.
|
| For example if I have this Tcl code
|
| [set foo [foofn bar [barfn baz [bazfn quz 1]]]]
|
| I would love to write it like this
|
| [set foo
|
| [foofn bar
|
| [barfn baz
|
| [bazfn quz 1]]]]
|
| But I can't without escaping every newline (you better hope you
| didn't forget one). If tcl had macros I could write it like this
|
| [set foo [thread-last 1
| [bazfn quz] [barfn baz] [foofn bar]]
|
| But instead I end up create a bunch of temporary variables so
| that my lines don't get super long. It just feels less elegant
| then it could have been.
| theamk wrote:
| TCL does not need macros because every function can be a macro.
| Here is an answer to your question: proc
| multiline {expr} {uplevel [regsub "\n" $expr " "]}
|
| Use it as following: multiline {
| set foo [ foofn bar [ barfn baz
| [ bazfn quz 1 ]]] }
|
| try it in action: https://jdoodle.com/ia/jka
|
| The hardest part to understand when writing TCL "macros", is
| that it's all strings. You might be used to "inputs are
| s-expressions" from lisp, or "inputs are closure objects with
| pointers to code and local variables", but not in TCL. {}
| produces a string parameter. It is interpreted as an expression
| to be evaluated in parent context when passed to "uplevel". So
| "proc" takes 3 strings as arguments, and syntactically no
| different from "regexp".
| celeritascelery wrote:
| But that won't work if I am using variables correct? because
| {} does not interpolate.
| blacksqr wrote:
| It will work because the value passed to proc multiline
| within the curly braces is treated as a string without
| substitutions, that value is then passed to the regsub
| command which replaces all newlines in the string with
| spaces, then the result is passed to uplevel, which is
| basically "eval this string in the scope context where
| multiline was called". It's uplevel that does all the
| variable substitution, using any values defined in the
| scope where multiline was executed.
| theamk wrote:
| sure it will, "uplevel" will interpolate for you.
|
| There is a link to online playground, I encourage you to
| visit it and try various changes. No installation or signin
| required.
| celeritascelery wrote:
| I stand corrected, it works just as you describe.
| jjnoakes wrote:
| This is not quite right...
|
| First off I think you want "regsub -all ...".
|
| Second, since your regsub isn't really replacing newlines
| (except the first), the example isn't so good - your "set foo
| ..." works without the multiline proc because the opening
| square brackets are on the same line as the commands. So this
| also works: jdoodle.com/ia/jnc
|
| Third, if you do change the example so that square brackets
| are on their own lines, as in the original request, then your
| version would work (with "regsub -all") but it might strip
| too much - like newlines inside nested quoting. See, for
| example: jdoodle.com/ia/jne
| blacksqr wrote:
| In Tcl newlines only have special meaning at the end of a
| command -- at the beginning of a command they're just
| whitespace. So you can break up a long line as follows:
|
| set foo [
|
| foofn bar [ barfn baz [ bazfn quz 1
| ] ]
|
| ]
|
| Elegant!
| mjevans wrote:
| I dislike that too about most of the languages which are in
| some way white-space sensitive. (Python as the go-to worst
| example, but other modern languages where ; or a statement
| termination value is optional also fit.)
|
| Newlines only can work, but then the question revolves around
| implicit newline escapes (if there's an unclosed statement)
| versus a required escape and things can quickly get out of hand
| and readability if really long strings need to be passed
| around; like with nightmare long SQL queries or default /
| example config file blocks.
| tyingq wrote:
| It's a bit odd, because you can skip newlines in many cases.
|
| This works: #!/usr/bin/tclsh set foo [
| lindex [ expr 2 * 3 ] 0 ] puts
| $foo
| ahartmetz wrote:
| The CMake language has the same absence of syntax, and everything
| is a command as well - like assignments with set(). Oh, and all
| variables are strings, too like in Tcl. (In CMake, even lists of
| strings are strings. Don't ask.)
|
| The CMake language was created in a haphazard way as well, with
| some other important problems that Tcl probably doesn't have.
| bch wrote:
| > The CMake language has the same absence of syntax
|
| Ironically, if I recall correctly, cmake came about from a
| Kitware medical imaging project that was heavily leaning on
| Tcl, yet when their build system needed a DSL they decided to
| hack something up from scratch :/
| Y_Y wrote:
| CMake is the modern MUMPS.
| denton-scratch wrote:
| Article doesn't do a good job of explaining why Tcl syntax isn't
| weird.
|
| I had to code in it once, can't remember what, something trivial;
| but I had to learn Tcl. It was basically an obstacle to my work.
| I never needed to use it again, so I've forgotten it, so I wasted
| my time learning that language.
___________________________________________________________________
(page generated 2021-11-09 23:02 UTC)