135 pointsby drudru2 days ago18 comments
  • foobarian2 days ago
    Another excellent aspect of Tcl I found is extensibility of JO's C implementation. At some point I needed to write some native code for speed and making this visible to the Tcl interpreter was a pleasure. Plus the codebase is so clean and well written.
    • f1shy2 days ago
      I've not seen the code, but the author has written a book [1] which has the advice I've ever seen. Much better than "Clean code" and other books in that direction. So it does not surprise me that the code is so well written.

      [1] https://milkov.tech/assets/psd.pdf

    • davidw2 days ago
      Yes! Tcl's C code is a real pleasure to work with and extend.

      I got to write some of the updates in this 2nd edition regarding the C interface:

      https://www.oreilly.com/library/view/tcl-and-the/97803216017...

      • pjmlp2 days ago
        While I agree, it was what eventually made us move into .NET, and the founders of the startup I started in 1999, eventually went on to create OutSystems.

        Too much code being rewriten from Tcl into C for performance and scalabity reasons, and it still doesn't have a proper JIT.

        Now as a way to script C code, it is even easier than CPython.

      • musicale2 days ago
        I also recall appreciating Tcl's C code.
    • 0823498723498722 days ago
      I'm pretty sure Ousterhout intended for people to write a few deep modules in C and only use Tcl to glue everything together/provide extensibility.

      (we did exactly this for networking code about 30 years ago: C for the data plane and Tcl for the control plane. That architecture remained in service for decades.)

    • johnisgood13 hours ago
      I agree, I have modified Tcl's codebase, too, to suit some of my needs (I wanted to use Tcl as my shell).
  • js22 days ago
    Previous discussions:

    31 points|pmarin|16 years ago|17 comments

    https://news.ycombinator.com/item?id=389107

    181 points|zeitg3ist|12 years ago|110 comments

    https://news.ycombinator.com/item?id=4920831

    131 points|throwaway344|11 years ago|45 comments

    https://news.ycombinator.com/item?id=7069642

    182 points|goranmoomin|2 years ago|79 comments

    https://news.ycombinator.com/item?id=31129936

  • bsder2 days ago
    The biggest problem with Tcl is the fact that C won.

    This means that "" and {} are expected to work a certain way from C and when you hit Tcl you are HORRIBLY confused.

    It's especially confusing as {} is simply quoting and has nothing to do with scope. The fact that Tcl is written such that {} is used with indentation in if-statements muddies the issue even further.

    I suspect that a choice of ` (backtick) for Tcl " and " instead of Tcl {} would have made Tcl way less confusing to the vast majority of programmers.

    I understand why things weren't done that way--having the ability to know that your quote has different characters for open vs close is very valuable for efficient parsing.

    Nevertheless, the Tcl choices were unfortunate given the way history played out.

    • mhalle2 days ago
      The use of {} for strings without substitutions and effectively for scope are actually interrelated, remarkably.

      Scopes are special syntactic forms that delegate variable substitution to the associated procedures. For example, a "for" statement evaluates the body of the function after substituting the loop variable. In a string based language, that's basically the same as expressing the scope in a string form where the string content is passed verbatim as an argument without variable substitution or function invocation.

      Having used Tcl extensively back in the day, I am not sure that this syntactic cleverness really was a major impediment to adoption. It was just something to learn. Same was true with [] meaning lisp-like function calling rather than array definition.

      Baseline Tcl's biggest challenge, in my opinion, was providing mechanisms to write modular code for larger programs and data encapsulation. Core Tcl put off decisions about the appropriate mechanisms to do so by only providing "namespaces" as a building block for higher level third-party syntax. That led to fragmentation at a time when other languages were gaining popularity.

      • jancsika2 days ago
        > Baseline Tcl's biggest challenge, in my opinion, was providing mechanisms to write modular code for larger programs and data encapsulation.

        I don't know if something about tcl's design precluded lexical scoping and a normal "var" keyword. But "upvar" definitely seems like a smell.

    • boomlinde2 days ago
      Sure, the "biggest problem with TCL" is some minor syntactical annoyance that you'd get over within the first hour of using it.
    • lilyball2 days ago
      In Tcl, "quoting" and "scope" are the same thing.
  • ilrwbwrkhv2 days ago
    This is fascinating. I have emailed Tcl's "father" (John Ousterhout) at length and he is one of the few to have actually tried to test what coding patterns make for better code and is the only book I recommend anyone when they want to get better.

    Unfortunately most fall for the more popular Clean Code and it's derivatives.

    Edit: The book is "A Philosophy of Software Design"

  • lilyball2 days ago
    I've long wished to have the free time to write a Tcl-derived language, because it really is so elegant in many ways, it just needs a bit of modernization in some areas. It's been years since I really thought much about this but I recall one of the things it's missing is closures (it does have lambdas at least).

    Reading through this article, the memoize implementation does have an issue which is if the memoized command wants to call uplevel or upvar it'll get the wrong stack frame. If I were writing this I'd structure it so it's used like

      proc myMemoizingProcedure { ... } {
        memoize {
          ... the rest of the code ...
        }
      }
    
    such that it can just `uplevel` the code. Or better yet I'd make `memoize` replace the `proc` keyword (or perhaps `memoize proc myMemoizingProcedure …`).

    EDIT: I suppose memoizing makes no sense in a procedure that wants to use upvar or uplevel though, because memoizing only works for pure functions.

    • monetus2 days ago
      There are these pages on the wiki regarding closures, and a reference to needing to change the internals of tcl_ObjType in order to implement them.

      https://wiki.tcl-lang.org/page/Closures

      https://wiki.tcl-lang.org/page/Emulating+closures+in+Tcl

      TCL 9 has surely fiddled with tcl_ObjType I hope, but it doesn't seem like it from a glance.

    • ufo2 days ago
      Closures are not easy to fit with "everything is a string", which favors dynamic scoping over lexical scope. I wonder what you'd change to make tcl more amenable to modernization.
      • rollcat2 days ago
        I've been toying with building a Tcl-inspired language that basically does away with "{ ... } is just a fancy way to make a string" and treats blocks similarly to how a Lisp treats s-exps - so you could write things like:

            type Point struct {
                X int
                Y lnt
            }
        
        Where "struct" maybe could just be a basic macro, but maybe it could also be smart enough to tell the compiler that "lnt" around "Y lnt" is not a type and suggest that maybe you meant "int".

        I think a lot of this ground was treaded with modern JS compilers (that had to infer a lot of this kind of information from very little context), or efforts like Python type annotations. Dynamic languages are still cool, and even cooler when the compiler can still somehow actively help you.

      • BoingBoomTschak2 days ago
        Tcl totally has lexical scoping, through proc and apply that create a new frame and thus new local bindings. Closures with explicit bindings (as opposed to tree-walking to find free variables to match with [info locals] which is something Tcl really can't do due to its "list == atom" thing) are easy to do through apply and a way to store the environment.

        The last implementation in https://wiki.tcl-lang.org/page/Closures is pretty nice.

        • lilyball9 hours ago
          That last implementation is interesting, although it requires using the `applyc` command to invoke the closure because it has to take it by name instead of by value, which is an unfortunate limitation. The thing you can't do is make a closure that can be invoked just with `apply`. Offhand the only way I can think of to try that is to store the closure data globally under a unique name, but then there's no way to clean up that data when the closure goes away since Tcl doesn't have finalizers (you can run code when a variable goes out of scope, but you can't do it for the value itself).
    • isr2 days ago
      jimtcl, an alternative, simpler, much smaller implementation of tcl DOES have proper closures, along with other nicities like unifying arrays & dicts.
      • cmacleod42 days ago
        jimtcl was originally created by the same Antirez who wrote the linked article.
  • andrelaszlo2 days ago
    A lot of the power of expect seems to come from the fact that it's (normally) configured/scripted in Tcl

    https://linux.die.net/man/1/expect

    I really like that it, like the article mentions, just looks like config for basic scripts but also scales to whatever you need it to do.

    • pjmlpa day ago
      In our application server written in Tcl/C, the configuration files were a Tcl DSL, the server would search for specific extensions and source the files, done.
    • AceJohnny22 days ago
      indeed, and other ports of Expect (Perl Pexpect, Python PyExpect) feel awkward as the constructs don't map quite as well to those languages.
  • sshine2 days ago
    My favorite obscure line of TCL:

    https://github.com/athas/EggsML/blob/master/concieggs/hooks/...

    A line that contains a regex pattern for matching regex patterns.

    TCL was chosen here because its regex engine isn't too powerful.

    • stackghost2 days ago
      >TCL was chosen here because its regex engine isn't too powerful.

      Uh, not sure I see the significance but wouldn't that make Tcl less apt for this than something else? Why would you purposely choose a less powerful regex engine?

      • sshine2 days ago
        When you feed the engine regexes supplied by users, you don’t want arbitrary code execution or exponential or infinite running times caused by obscure features.
  • magicalhippo2 days ago
    Wish I had this page when messing around with Eggdrop[1] back in the late 90s.

    As a self-taught novice programmer that started with QBasic and had moved on to Turbo Pascal, I found Tcl to be very confusing and it left a rather negative impression.

    Reading this page now though, it seems a lot more logical and reasonable than it appeared at the time.

    [1]: https://docs.eggheads.org/tutorials/firstscript.html

    • isr2 days ago
      Don't blame you. If you treat tcl as a c-like scripting language, it's a mess. If you treat it as a "shell & lisp" combo, then you get to see it's power & flexibility.
  • generalizations2 days ago
    The biggest weakness IMHO is the inability to comment out elements of an array. Even bash lets you do this and it makes testing and dev so much easier. Really wanted to love it, but that got in the way too many times.
    • lilyball2 days ago
      By arrays you mean something like this?

        array set foo {
          a 1
          b 2
          c 3
        }
      
      If the inability to comment out entries here is a problem, that's also something you can fix, you can write something like

        proc decomment body {
          …
        }
      
      such that you can then write the following and it will remove commented lines:

        array set foo [decomment {
          a 1
          # b 2
          c 3
        }]
    • cmacleod42 days ago
      TIP 401 proposed a fix for this but has not progressed so far - https://core.tcl-lang.org/tips/doc/trunk/tip/401.md .
  • WillAdams2 days ago
    One thing which I've always not understood about Tcl/TK is why there isn't a standard graphical tool for laying out a GUI program.

    For a long while, when I might have used Tcl/TK, I instead used Runtime Revolution/Livecode (a cross-platform HyperCard clone) which had a very nice system for interactively drawing programs.

    I'd really like for there to be an agreed-upon standard option for graphical program development which was interactive and cross-platform.

    • ofalkaed2 days ago
      I don't think it is needed. I am a hobby programmer and not even remotely competent but I can whip up GUIs in Tk with little effort and I find it quicker and easier than the graphical UI designers.
      • WillAdams14 hours ago
        I am a visual person (at least that's what I told myself when I chose to get a graphic design degree rather than do computer science (but was one 300-level course short of a CS minor)), and I find the disconnect between the visual appearance and the obtuse code a quite difficult stumbling block --- the one tool I was successful doing using Python and TK never had a visual appearance I was satisfied with.
        • ofalkaed9 hours ago
          If I am not sure how things should be laid out I just sketch it on graph paper or on my tablet, I consider each square of the graph to be 10 pixels or what ever suits and have at it. 10 or 15 minutes will generally be enough to go through many revisions and leave me with map to follow, 5 or 10 minutes of typing and it is done. After that tweaks are just changing a few numbers and the results are essentially instant since no compile time and you can see the results with a command from your editor.

          Wish also has an interactive mode, not point and click but results are instant, great for learning Tk. No idea if it can work with tkinter though.

    • musicale2 days ago
      > why there isn't a standard graphical tool for laying out a GUI program

      It is a bit surprising since it seems like you could use Tcl/Tk to write it.

      The Tk canvas makes writing simple drawing programs fairly easy, and a GUI editor seems like it wouldn't be terribly difficult.

    • rmu092 days ago
      Once upon a time (Tcl??/Tk3.6) there was XF by Sven Delmas. It had some issues and really would have needed something like namespaces. AFAIR it took forever to get a stable version for Tk4.0.
    • musicale2 days ago
      > a cross-platform HyperCard clone

      I wish there were more of these, preferably open source (and, since I'm dreaming, native and web versions.) ;-)

      • Decker is FOSS, and available in both a web version and native builds for MacOS, BSD, Linux, and Windows: http://beyondloom.com/decker/

        If you've seen Decker previously you might find it useful to know that it has recently acquired several "escape hatches" for interoperating with software and APIs outside its usual sandbox: http://beyondloom.com/decker/decker.html#thedangerzone

        • musicalea day ago
          Thanks for reminding me of Decker, which I think has been featured on HN a few times.

          I live in a HiDPI, color world but the 1-bit vintage Mac-style GUI and fonts look nice to me.

          https://hypercard.org also has some interesting links.

          I think the sandbox/doesn't play well with others issue has affected the use cases of environments from HyperCard to Lisp to Smalltalk. Tcl/Tk seems designed for connecting to other software.

          • RodgerTheGreat14 hours ago
            There are basically two parts to Decker's stance on sandboxing:

            To maintain fidelity between the capabilities of web-decker and native-decker, the constraints of web browsers need to be treated as a common denominator. Some of the ways that conventional webapps circumvent these constraints are not an option for web-decker, because it's designed to function without a server-side component; this avoids dependencies on centralized infrastructure. (There are also some features intentionally left out because they would be inaccessible on e.g. touch-based devices which lack a physical keyboard or the ability to register "hover" events from a pointing device.)

            To center user-empowerment, Decker should be "safe by default" and require affirmative consent for things like sending information to remote servers or accessing the local filesystem. If a user understands the risks, they can deliberately shift Decker into a more permissive mode of operation which lets it interoperate directly with local resources, raw browser APIs, etc. By default, Decker can safely run applications written by untrusted third parties, and in "dangerous" mode it is more comparable to a conventional automation tool or scripting environment. This approach may not please everyone, but it is a carefully-considered compromise.

            Decker does have paletted color support; many decks produced by users apply this to great artistic effect: https://itch.io/games/tag-decker

      • WillAdams2 days ago
        Livecode going opensource and targeting HTML5 was a big part of why I chose it (and funded it on Kickstarter).

        Still annoyed about their changing course and removing the Community Edition.

        • a day ago
          undefined
      • [dead]
  • import_awesome2 days ago
    Another great feature of Tcl for writing servers it that you can reload the code while it is running and keep all the state and connections open. Code up/bootstrap your server while it is running the whole time. Sure this is a security nightmare, but it is fun to code.
    • rwmj2 days ago
      Nice! Did AOLServer (now Naviserver) do that? That was the major Tcl webserver that I remember.
  • leoh2 days ago
    Fun fact: SQLite’s test suite is written in TCL https://github.com/sqlite/sqlite/blob/master/test/strict1.te...
  • allknowingfrog2 days ago
    Does anyone know of a good tutorial for getting starting with Tcl/Tk that still makes sense in 2024? I'm really intrigued by the idea of building and shipping simple, cross-platform GUIs, but I'm completely overwhelmed by all of the installation and configuration options. It seems like tclkit is supposed to be the go-tool tool for self-contained executables, but I honestly can't even figure out which site is the source-of-truth for downloading it, let alone installing it.
    • ofalkaed9 hours ago
      John Ousterhout's Tcl and the Tk Toolkit is great and has been updated to Tcl/Tk 8.5 which is recent enough to not cause headaches. Don't think it goes into self contained executable but covers everything else very well.

      Edit: Just remembered that Tcl/Tk: A Developer's Guide by Flynt has a chapter on self contained executables and the various tools for making them. Have not looked into this book much so can't comment on it.

    • cmacleod42 days ago
      I recommend https://wiki.tcl-lang.org/page/LUCK as a very easy way to build self-contained executables which bundle Tcl, a large choice of extensions, and your own code.

      There is a tutorial on the Tcl wiki which should be reasonably up-to-date - https://wiki.tcl-lang.org/page/Tcl+Tutorial+Lesson+0 .

  • mseepgood2 days ago
    This language seems like a security nightmare to me regarding code injection attacks through untrusted inputs.
    • cmacleod42 days ago
      No more so than any other dynamic language. Of course if you execute untrusted input you are asking for trouble. But Tcl has very well-defined rules for how and when substitutions and evaluations will be performed - https://www.tcl-lang.org/man/tcl/TclCmd/Tcl.htm#M4 - so the programmer has full control.
    • rwmj2 days ago
      One genuine problem was the you could send snippets of code to any Tcl/Tk program running on the same X server and it would execute them. Obviously X isn't the most secure of systems and you should trust your X clients, but this made it very easy if you could persuade someone to run a "command line" program. I wonder if that was fixed?
    • isr2 days ago
      Have a look at tcl's ability to run multiple iterations of itself (nested interpreters) within the same process, and how those interpreters can be sandboxed & limited to run just what you allow, & nothing more.

      If you were going to handle "untrusted input", that's how you would do it in tcl.

      Note: this is separate from tcl's multithreading capability, where it can also run individual interpreters per thread , with thread safe channels between them. (btw, you can mix & match both approaches - multithreading & nested interpreters)

  • zombot2 days ago
    > Concept 9: Eval and Uplevel

    That's where it gets really criminal: Dynamic scoping rules. There is no lexical scoping and hence no closures. If you use `uplevel`, your procedure works or doesn't, depending on the caller. There is a reason Tcl is the last language that uses this braindead mechanism.

  • 77pt772 days ago
    Tcl is basically a sloppier Perl with a GUI.
    • TCL fits on microcontrollers. If I'm looking at anything other than Python or bash(for trivial logicless scripting) it's probably because I'm in a constrained environment.
    • kqr2 days ago
      I came into this comment thread thinking "why should I bother with Tcl if I know Perl" but your comment nearly sold me. When I do Perl it's because I can afford to be sloppy, and coming with a GUI sounds like a good deal!
    • tlavoie2 days ago
      Well, and a GUI that people see fit to implement within many other languages as well.
    • bcha day ago
      > Tcl is basically a sloppier Perl

      That’s a hot take for one language with basically a sheet to describe it[0], and another whose “rules” are best described by “whatever this implementation does.”

      [0] https://wiki.tcl-lang.org/page/Dodekalogue

    • BoingBoomTschak2 days ago
      But you can look at it without barfing, at least. And have fun doing wacky metaprogramming instead of wacky code golfing aka obfuscation.
  • 2 days ago
    undefined
  • 2 days ago
    undefined