[HN Gopher] Why Tcl?
___________________________________________________________________
Why Tcl?
Author : elvis70
Score : 167 points
Date : 2023-06-20 13:01 UTC (10 hours ago)
(HTM) web link (gist.github.com)
(TXT) w3m dump (gist.github.com)
| gilbetron wrote:
| I've managed to work on two TCL codebases in my career, one in
| 1992ish, and one in 2011ish. I was very surprised to be working
| on it the second time! I've said it before, but working on TCL is
| interesting, kinda fun, and ultimately a lesson in frustration
| once you get to a certain sized codebase. It really hammered home
| the need for static typing as your repo gets over 50k lines
| because it is so "type free". However, it is a cool thought
| experiment for it's premise, which is more-or-less, "what if
| everything is a string". It has a lot of benefits, and a lot of
| nasty side effects. I'm glad I spent time doing it, and I think
| the use case for which it was made ("Tool Control" roughly
| speaking) it has good ideas. TK was fun, as well, I miss it in
| some ways. But ultimately, I find TCL is a dead end for a
| programming language - the negatives accumulate too quickly.
| keithalewis wrote:
| You can have any type you want, as long as it's a string. :-)
| Don't forget about https://core.tcl-lang.org/expect/index.
| Comes in very handy sometimes.
| cpeterso wrote:
| Tcl may not be strongly typed, but it is "stringly typed". :)
| kevin_thibedeau wrote:
| Tcl hasn't been string based for over 20 years. It's time for
| this myth to die.
| tyingq wrote:
| If it's a myth, the myth seems driven by the TCL team
| itself.
|
| https://wiki.tcl-lang.org/page/everything+is+a+string
|
| Yes, there is some detail about internal dual
| representation.
| kevin_thibedeau wrote:
| That wiki page has been around since before Tcl 8. Nobody
| says lisp is hampered because everything is an S-expr.
| tyingq wrote:
| > That wiki page has been around since before Tcl 8
|
| Maybe, but it's clearly been updated after Tcl 8. And
| while the page itself isn't calling it something that
| hampers tcl, it does cover that it's somewhat unusual,
| that is has implications, and so on.
| zylent wrote:
| after using expect and TCL heavily for years, I can firmly
| say they suck at scale.
|
| Ruby https://github.com/ytti/oxidized/blob/master/lib/oxidize
| d/mo... or TextFSM https://github.com/google/textfsm
|
| are much better options if you need to do a /lot/ of parsing
| 7thaccount wrote:
| I never understand people's frustrations until I hear 50k loc
| base lol. That sounds hard in any language. I'd guess Tcl is
| pretty awesome if you keep things around 1000 loc or below
| (i.e. scripting).
| girishso wrote:
| > That sounds hard in any language.
|
| Yes, it is hard in many languages, having experienced it
| first hand. Just wanted to point out my experience with Elm
| (I know) 200k loc, I can refactor the codebase fearlessly,
| knowing that once it compiles it will "mostly" just work.
|
| I fondly remember porting Elm 0.18 to 0.19, which was a big
| change in the language itself and the libs, me and my co-
| worker working across time zones almost 24/7 for over a week
| to make the damn thing compile, it was like struggling in the
| darkness, unable to see "anything" in the browser for like 7
| days and when it finally compiled.. it mostly just worked!
|
| It's sad that to see Elm getting so much negative publicity,
| but I do enjoy working every day on it.
| westernpopular wrote:
| Last I checked Elm was getting negative publicity not
| because of the language itself (heard a lot of good things
| about that) but because of the leadership?
| charukiewicz wrote:
| Correct. Elm's publicity issues stem from how closed off
| the leadership is. There's Evan (creator) and a handful
| of trusted others that have a huge amount of sway over
| how the language and, arguably more importantly, the core
| libraries develop. They also get special access to write
| libraries that rely on native JS code (something you
| can't do as of 0.19 even locally in your own projects).
|
| Elm is a great language and I've written extensively[1]
| about how nice it is to use in production. But if you
| want to get involved in the community, it feels like
| there's not much to get involved in. The fact that even
| on the Elm Discourse[2], posts auto-lock after 10 days
| means that the forum is now pretty dead compared to what
| it used to be in 2018-2019.
|
| [1] https://charukiewi.cz/posts/elm/
|
| [2] https://discourse.elm-lang.org/
| 999900000999 wrote:
| In something like C# or Java with a good ide I imagine it's
| not too bad.
|
| Interpreted languages like Python and JavaScript do suffer
| when code bases reach a certain size.
| ElectricalUnion wrote:
| Even adding half-baked, not compile/runtime checked types
| such as "Python's Type annotations", "Python's Type Stubs",
| "Javascript @type-infused-jsdocs" and "Javascript with
| Typescript Declaration Files" manages to make those modern
| IDEs a lot smarter for things like checking if you're doing
| really obvious bad things until you go really ham into
| metaprogramming.
| tmcb wrote:
| Tcl is a little gem of programming lore, an ugly duckling story
| where the ducklings are LISPs instead.
|
| One of the most mind-blowing things to me as a (perpetual) Tcl
| noob is that when you look at proc my_function
| {x} { puts $x }
|
| You are lead to believe it is an ordinary C-inspired language
| with an odd syntax. It took me an embarrassingly long amount of
| time to realize that proc my_other_function "x"
| "puts \$x"
|
| Is equivalent to the former. Other little oddities like `upvar`
| are beautiful once you understand them. It has some warts but Tcl
| has never had the luxury of under the scrutiny that languages
| like Python or Ruby have had. This is one of the reasons I would
| really like to see a "modern" version of Tcl more suitable for
| programming in the large---something that happened to Python 3
| almost as an accident, imho.
| monetus wrote:
| The command-argument based workflow is so easy to grok as a
| model that it is intensely loveable. Generating arguments at
| runtime without messing up your substitutions can trip people
| up occasionally, but the straightforward nature of how the
| compiler understands the function is relatively wonderful IMO.
| phamilton wrote:
| > a "modern" version of Tcl more suitable for programming in
| the large
|
| Would lua fit that definition? Between game engines, redis,
| openresty (nginx w/ lua) and others I feel like it fits a
| similar need (adding code to existing applications).
| tmcb wrote:
| I've done a fair amount of programming in Lua in the past but
| it still feels different from Tcl. Back in 2010 I would
| probably compare Lua to (a better) JavaScript due to its
| prototype-based nature. JavaScript evolved in a different
| direction afterwards.
| arp242 wrote:
| The language itself is very different, but Lua is a
| replacement for Tcl in the sense that it's a fairly simple
| and small language that can easily be embedded. i.e. it's
| about use cases rather than the language design.
| tmcb wrote:
| I understand what you mean, but this is not the point I
| was trying to get across with my original comment. Maybe
| that's the reason why I haven't touched this subject.
| Although both languages can be easily embedded, the
| programming experience is still different, and there are
| still lots of "freestanding" systems in both languages,
| so the language design comparison still applies.
| treis wrote:
| foreach line [split $file \n] { incr count($line)
| } foreach {line n} [array get count] {
| if {$n > 1} { puts "$n\t$line"
| } }
|
| ......
|
| IMHO that's hard to grok. count shows up in the middle of a loop
| and it's not clear to me what it is. Could be a function, an
| integer, a map, or an array.
|
| Same problem with this:
|
| >foreach {line n} [array get count]
|
| Not really obvious what any of this does. Guessing it's taking a
| map, converting it to key/value array, and iterating.
| msla wrote:
| for dish, price := range menu { fmt.Println(dish,
| price) } for key, value in menu.items():
| print(key, ' is ', value) for (key, value) in
| hashmap { println!("{} {}", key, value); }
|
| Really, it seems like that's a common syntax for languages with
| first-class dictionaries.
| treis wrote:
| Those have an "in" keyword that makes it much more obvious
| what's going on. And none of them have the "count" variable
| that pops up in a loop but is somehow accessible outside it.
| aidenn0 wrote:
| In python variables introduced in a loop are definitely
| accessible outside of it...
| BeetleB wrote:
| > IMHO that's hard to grok.
|
| Keep in mind that the default way C does for loops is the most
| un-intuitive way of doing a for loop. This Tcl example is less
| alien than the C for loop is for someone who has programmed in
| non-C like languages.
|
| You learn it, and you get used to it.
| pwg wrote:
| > Could be a function, an integer, a map, or an array.
|
| It is an array. 'incr' is a built in function that "increments"
| a variable by one.
|
| Variable names followed by parenthesis () are Tcl arrays. So
| count(...) is "array syntax".
|
| > Same problem with this:
|
| > >foreach {line n} [array get count]
|
| This is roughly equivalent to Python's "list comprehensions".
| "array get count" produces a list of values from the contents
| of the array named count (the list is "key1 value1 key2 value2
| key3 value3 ..."
|
| foreach is Tcl's "iterate over a list" function. In this case
| it is iterating two variables over the list at the same time
| taking two elements off the list each time. The first element
| is assigned to "line" the second element to "n".
| shrubble wrote:
| Reminder that TCL was programmed at a time when SPARCstation
| IPXes with a maximum of 96MB RAM were being used.
|
| Some of the lower-end SPARC machines could only have 16 or 32MB
| RAM and had perhaps 10 to 12 MIPS of computing power.
|
| Expect, which became a very important extension of TCL, was
| released in 1990, when the SPARCstation 1+ with about 15 MIPS and
| max RAM of 128MB was introduced.
|
| Thus any extension language like TCL had to be small and
| efficient; especially when you consider it was designed to be
| embedded inside another program.
| AshamedCaptain wrote:
| As someone is pointing above Tcl is nowadays used as the shell
| language for many EDA tools for which it is normal to consume
| multiple TBs of RAM.
| hfkwer wrote:
| How about some PowerShell instead?
|
| # Echo command-line input $args -join " "
|
| (Yes, it's a single line.)
|
| # Count duplicates in a file $lines = @{}
| foreach ($path in $args) { cat $path | % { $lines[$_]
| += 1 } } $lines.GetEnumerator() | % { if
| ($_.Value -gt 1) { "$($_.Value)`t$($_.Name)" } }
|
| # GET request param($url) irm $url
|
| # Parallel GET requests $before = get-date
| $args | % -parallel { $res = iwr $_
| $after = get-date $time = ($after -
| $using:before).TotalSeconds
| "${time}s`t$($res.RawContentLength)`t$_" } -ThrottleLimit
| 12345 $after = get-date $time = ($after -
| $before).TotalSeconds "${time}s elapsed"
|
| I'm showcasing a few different ways of doing things: using $args,
| using the param directive; using foreach, or % which is an alias
| of ForEach-Object; irm for Invoke-RestMethod, iwr for Invoke-
| WebRequest...
| ptx wrote:
| No thanks. PowerShell seems to have all sorts of crazy gotchas
| in addition to the weird syntax.
|
| For example, if I understand correctly, your "cat $path" won't
| actually work for all filenames, because "cat" is an alias [1]
| for "Get-Content -Path" which will expand wildcards in the
| filename [2][3], so you have to know to use "-LiteralPath"
| instead of you want it to work properly.
|
| And then there's Microsoft's telemetry, which is enabled by
| default. [4]
|
| [1] https://learn.microsoft.com/en-
| us/powershell/scripting/learn...
|
| [2] https://stackoverflow.com/questions/33572502/unable-to-
| get-o...
|
| [3] https://learn.microsoft.com/en-
| us/powershell/module/microsof...
|
| [4] https://learn.microsoft.com/en-
| us/powershell/module/microsof...
| hfkwer wrote:
| A shell language that expands wildcards isn't what I'd call a
| "crazy gotcha". And let's be real, if you name your files
| with * or ? in their names, you're just setting yourself up
| for a bad time.
|
| Weird syntax? Weirder than TCL?
|
| I frankly don't care about the telemetry.
| Riverheart wrote:
| "<Language> seems to have all sorts of crazy gotchas in
| addition to the weird syntax."
|
| Says everyone about every language.
| forinti wrote:
| Every few years I use Tcl/Tk and the most common reasons are:
|
| 1- It's easy to make an executable for Windows (as well as
| running it on Linux);
|
| 2- It's easy to write a GUI.
| sigzero wrote:
| Yeah, exactly what I used it for. I used to make small one off
| gui utilities for my team to use to save time doing certain
| tasks.
| axus wrote:
| Yep, what I've always appreciated most about Tcl is ease of
| using Tk.
|
| Worst way to make a scripted GUI: dtksh
| SPBS wrote:
| And there's nothing special about Tcl the language that makes
| it special for scripting GUIs -- some people just put in the
| work to make a cross-platform GUI library and now everyone
| using Tcl benefits from it. I really wish Go had something
| similar to Tcl/Tk. I know making a cross-platform GUI library
| is hard, so how did Tcl/Tk's authors do it? All the way back in
| 1991, which still works even today?
| mometsi wrote:
| Sun put money into it in the mid 90s, it was their big cross-
| platform project before putting everything behind Java.
|
| see https://www.tcl.tk/about/history.html#Sun
| dsab wrote:
| Its easy to develop, surely, but my style feeling hurts how
| ugly TCL GUI looks like compared to modern GUIs
| rightbyte wrote:
| Given the recent trends in "UX" I would regard that as a a
| feature though.
| IshKebab wrote:
| Because you are forced to. That's the only reason.
|
| Otherwise please use something modern and sane like Deno, Python,
| Go or even Rust.
|
| TCL has many large flaws that those languages don't share:
|
| * No static typing so trivial errors are not caught early and
| code is difficult to understand and navigate.
|
| * Everything is a string (TCL people try to claim otherwise but
| semantically it really is true). This leads to typing mistakes
| too.
|
| * Quoting is a mess. It's simple in that _the implementation_ is
| simple, but languages shouldn 't optimise for that alone.
| Actually getting quoting right in TCL is ... well it's not as bad
| as Bash or even YAML but it's still something you have to _think_
| about, which isn 't true for any of the other languages I listed.
|
| If you need a language to embed in your program then while I'm no
| Lua fan, it is at least significantly better than TCL.
| MrStonedOne wrote:
| [dead]
| a2tech wrote:
| My biggest question about TCL--pronouncing it: T C L (each letter
| pronounced on its own) or tickle. I've heard it pronounced both
| ways by different programmers
| greenpeas wrote:
| https://wiki.tcl-lang.org/page/How+do+you+say+%27Tcl%27
|
| > It was a good decision to invent tcltest rather than, say,
| "testtcl". Or, better yet, do not say the latter, at least in
| English.
| VBprogrammer wrote:
| It's weird, I spent 3 years working on one of what must have been
| the largest TCL codebases in existence, since then I've reached
| for the language exactly zero times in personal or professional
| use. I have very little fondness for the language.
| thenewwazoo wrote:
| For a company in the rental automobile space?
| IggleSniggle wrote:
| I think it is extremely cool as a toy language. I've loved
| learning it for fun. I absolutely never ever would want to have
| to _use_ it to do something _productive_
| nmz wrote:
| What would you use instead?
| IggleSniggle wrote:
| For almost all the things I would use tcl for, I would
| instead pick whatever scripting language my team happens to
| be most comfortable with, with an eye on any larger company
| norms. In my various organizations, this has usually meant
| one of:
|
| - python
|
| - nodejs
|
| - bash
|
| Of those, I personally would prefer bash as the "organizer
| of commands," but that's probably not surprising from
| someone who would learn tcl for fun.
|
| Usually, the use case for these things is some combination
| of gluing programs together or gluing programs to the
| specifics of their OS. In that regard you might think, that
| picking a language specific for the problem at hand would
| be wise. But pragmatically, I believe you want devs who are
| _mostly_ focused on feature work in their own programs to
| nevertheless be able to "bring their head above the water"
| and still have immediate intuition about how to swim. So
| even though nodejs might suck for this, it's also extremely
| approachable for somebody who spends all their days in js.
|
| I am really drawn to the idea of doing all of this in
| something like nix, but I tried it and didn't have time to
| get past the learning curve. And that points to the other
| issue:
|
| You're probably going to need to glue rpm scripts,
| Dockerfiles, specific system tools which have different
| amounts of portability, etc. At the end of the day, if
| there's a "lingua franca" for the organization, it usually
| makes sense to use it so that nobody needs to spend any
| time becoming accustomed to the idioms of some unfamiliar
| language while they are _simultaneously_ dealing with the
| unfamiliar terrain of dealing with other systems that they
| have very incomplete knowledge of.
|
| If there's no lingua franca, I default to bash as a larger
| lingua franca
| karl_gluck wrote:
| This is a more interesting take to me than others since it
| seems you've actually learned it?
|
| I see the response later that you'd rather use whatever the
| team already uses, but could you explain this very strong
| opinion?
|
| I maintained a 200,000 loc TCL codebase running the front end
| for millions of lines of industrial C spread over hundreds of
| machines. It was glorious. After moving on, I'm still
| struggling to figure out why TCL is so unpopular outside that
| domain. Other comments seem to boil down to not understanding
| the language or how to apply it. So what's your take?
| lanstin wrote:
| In the 1990s the services in AOL were all written in C, using
| a very very good event based callback library, which had Tcl
| embedded in it. We had a very rigorous standard of nothing in
| the server was hard wired, any change that ops might want to
| make would be applied to a running server, and dev had the
| job to expose all configurable state as either Tcl Vars or
| Tcl commands. It was a no thread environment (one process per
| CPU and one CPU for the OS) so while your Tcl command was
| running you could do anything to the in memory structures you
| wanted as long as it was fast. The ability to have a Turing
| complete language available for ops to do config in was
| extremely useful, they wrote amazing Tcl making configuration
| on the fly.
|
| Not sure any of it would have carried thru till today even if
| the business hadn't stumbled, but it very productive in the
| 1990s.
| jakswa wrote:
| same. Back in ~2009 I had the pleasure/horror of
| debugging/fixing "TCL drivers" for a piece of Java software
| that aimed to integrate with various pieces of hardware. I'll
| never risk putting anyone else through a similar torture if I
| can help it. ...then again I've left a trail of Ruby/Rails
| behind me that might get the same job done :)
| jacknews wrote:
| I think the comparison to bash etc is apt.
|
| tcl is definitely much better, but equally uninspiring.
| eesmith wrote:
| The Python and Tcl programs don't do the same thing. The Python
| output is in most-common order, which requires a sort. The Tcl
| one is in arbitrary order.
|
| The idiomatic Python matching what the Tcl code does is:
| #!/usr/bin/env python import collections
| import sys for p in sys.argv[1:]: try:
| with open(p) as f: c = collections.Counter(f)
| for k, v in c.items(): if v > 1:
| k = k.rstrip("\n") print(f"{v}\t{k}")
| except Exception as e: print(f"dup: {e}")
| continue
|
| Except, even then there are three differences:
|
| 1) the Tcl code accumulates the counts across all the files, the
| Python code resets each time. Though the Tcl code _reports_ the
| counts after each file???
|
| 2) the Tcl code has a file descriptor leak (one of the big issues
| I have with Tcl is in dealing with resource management. I've used
| an upvar with a delete trace to emulate local scope, but that
| makes passing the result upstream tricky).
|
| 3) the Tcl code includes the empty string "" after the final
| newline in the count, which doesn't make sense.
|
| To show the issue, I've replace the Tcl code so it outputs quotes
| around the line: puts "$n\t'$line'"
|
| and set the file descriptor limit to 10 before having it read a
| file containing only two lines, each containing "A":
| % printf "A\nA\n" > x % limit descriptors 10 % tclsh
| dup.tclsh x x x x x x x x x x x 2 'A' 2 '' 4
| 'A' 3 '' 6 'A' 4 '' 8 'A' 5 ''
| 10 'A' dup: couldn't open "x": too many open files
| dup: couldn't open "x": too many open files dup: couldn't
| open "x": too many open files dup: couldn't open "x": too
| many open files dup: couldn't open "x": too many open files
| dup: couldn't open "x": too many open files % python dup.py
| x x x x x x x x x x x 2 A 2 A 2 A 2 A
| 2 A 2 A 2 A 2 A 2 A 2 A 2 A
| waynecochran wrote:
| No Perl comparisons? I must be a dinosaur, but Perl is the best
| for reading in text, regex matching/search/replace/, and
| outputting a transmorgified result.
| systems wrote:
| For me for Tcl to be relevant again its needs
|
| 1. a Package Manager (they sort of already have one called TEA,
| but its not active as far as I know)
|
| 2. an IDE or a good modes for the popular editors (VS Code,
| Emacs, Vim, Sublime Text)
|
| For a UI language the absense of a good IDE or editor modes is
| very strange, you would expect that a Tcl/Tk IDE written in
| Tcl/Tk (one that also serve as UI framework or scaffolding for
| other apps) would be its killer app, but there isnt one
| LesZedCB wrote:
| my espresso machine has software written in TCL and within the
| group of owners/hackers it's quite the bit of drama how much
| everybody regrets the original developers choice for it and his
| insistence it is still a good choice. personally, i value
| language aesthetics highly and TCL is an ugly one.
| roflyear wrote:
| Decent proved that they can't do a good job at software and
| don't really have a vision or intention to do well. The owner's
| proposed "fix" for TCL is a rewrite using "vanilla javascript"
| using little or no libraries. What?
| bit_flipper wrote:
| The author should investigate their networking setup. I can run
| their Go fetchall example in no more than 70ms. Their benchmarks
| are surely dominated by noise.
| stealthcat wrote:
| Because you work in semiconductor industry.
| hoosieree wrote:
| The best thing about TCL is it's not OCEAN.
| mardifoufs wrote:
| Is Tcl widely used in semiconductors because of a particular
| thing it does well or is it mostly because of inertia? I don't
| know a lot about the language so I'm curious :)
| mschaef wrote:
| The language originated as a common language for
| semiconductor design tools.
|
| Ousterhout saw that a number of design tools he was involved
| with all had ad hoc languages, so he developed Tcl as a
| single common solution to the 'scripting language problem'.
| This is partly why the language is designed to be as easily
| embeddable as it is.
|
| Post this origin, Tcl developed a modicum of broader fame
| through Tk (one of the best/easiest early X11 toolkits) and
| expect (which is a tool for automating control of command
| line interactive tools).
| uncertainrhymes wrote:
| I only came across TCL as the scripting language used
| internally by the F5 (BigIP) load balancer. Writing irules was
| fine because they are usually one and done. It was tempting to
| try to do complicated things until you realized that was
| exactly the wrong place to try to fix the underlying problems
| of a broken web application.
| jeremy0x4a wrote:
| Or have an ancient and undying passion for Eggdrop IRC bots.
| Eggdrop was an introduction to TCL for _dozens_ of us.
| a_wild_dandan wrote:
| The gist of those examples in TypeScript:
|
| EXAMPLE 1: Echo command-line input
| console.log(process.argv);
|
| EXAMPLE 2: Count duplicates in a file import {
| readFile } from "fs/promises"; readFile("0.txt",
| "utf-8").then((text) => { const frequency: { [line:
| string]: number } = {}; text .split("\n")
| .forEach((line) => (frequency[line] = frequency[line] + 1 || 1));
| Object.entries(frequency) .filter(([key, value]) =>
| value > 1) .forEach(([key, value]) =>
| console.log(value, key)); });
|
| EXAMPLE 3: GET request
| fetch(process.argv[2]).then(console.log).catch(console.error);
|
| EXAMPLE 4: GET parallel requests
| process.argv.slice(2).map((url) => { const start =
| Date.now(); fetch(url).then((res) =>
| console.log( `${(Date.now() - start) / 1000}s`,
| res.headers.get("Content-Length"), url
| ) ); });
|
| Using the author's criteria, relative to Tcl, these
| implementations (to me) are:
|
| 1. Significantly shorter, just as expressive, and familiar to
| millions of (JS/TS) devs
|
| 2. Fast, owing to Node.js/V8's insane optimization level
|
| 3. Strongly typed
|
| But you know what? I don't care much about terseness or speed
| when writing scripts. Honestly, the _real_ reason I use TS for
| scripts is simple: comfort. I 'm comfortable and productive with
| it. Everything else is just post-hoc rationalization. I'd wager
| it's the same story for many of these "Why <language/tech>?"
| posts.
|
| It's perfectly fine to use something simply because you like it
| -- you're in good company. :)
| bentinata wrote:
| I used to think POSIX shell scripts are the best. But ever
| since deno support npm packages directly, running `deno run
| url-to-scripts` seems really good now. You get readability,
| types, and library ecosystem.
| vdksbskdb wrote:
| i frown on anything JS because it always end up requiring some
| sort of 'npm install' or, shivers, 'npm install -g'. it's just
| as bad a running a random 4gb java binary with extra steps.
|
| js will only run on users machines or inside a vm without even
| kvm because we've seen plent ecosystem hijacks and exploits in
| the wild already. and you can only fool me MAX_INT.
| motogpjimbo wrote:
| Generally, when you see a package asking you to install it
| globally with `npm -g i`, you can install it locally with
| `npm i` and then run it with `npx`. Requesting global
| installation is either an expression of ego or the author is
| a Python refugee.
| arp242 wrote:
| > 2. Fast, owing to Node.js/V8's insane optimization level
|
| But you need to convert the TS to JS, and the TS compiler takes
| like 3 seconds to start on my laptop (orders of magnitude
| slower than any other compiler I know, although you can speed
| it up a bit if you disable type checking, but that, well,
| removes type checking).
| a_wild_dandan wrote:
| You don't need a compiler. The vanilla `node` binary works
| fine with a few trivial syntactic changes.
|
| It sucks that your compiler's slow! Check out `swc` if you
| prefer speedy compilation.
| arp242 wrote:
| swc doesn't do type checking, so while useful in some cases
| it's not really a replacement for tsc.
| tom_ wrote:
| Does node do static type checking?
| ori_b wrote:
| I'm pretty sure your examples behave differently from the
| example programs.
|
| For example, 'console.log' will pretty-print the data
| structure, rather than a single space separated line, the
| duplicate counter only reads from one file (with a hard-coded
| name) and will not correctly handle errors and move to the next
| file, and your parallel get doesn't seem to print one duration
| for all requests to complete.
| a_wild_dandan wrote:
| Ergo the weasel word "gist" of the examples! :) Want variadic
| arguments? Wrap your code in
| `argv.slice(2).forEach(mySweetParser).catch()` or whatever.
| My point wasn't to scrupulously transpile Tcl to TS via HN
| dialog boxes. I don't have myself _that_ much. My point is
| just that the real work in those examples can easily be
| hogged out faster via other languages, so Tcl isn 't an
| outstanding tool for brevity.
| eesmith wrote:
| .split("\n")
|
| It looks like this has the same issue as the Tcl code, where
| the empty string after a terminal "" is treated as a line. I
| think that is an error in the Tcl.
|
| You'll also need a .catch(err => console.log("dup:", err));
|
| And the console.log(value, key) needs a tab separator.
|
| And a loop over the argv input files.
|
| All minor tweaks which don't detract from your conclusion.
| dangerboysteve wrote:
| This brings back memories. I used TCL/Expect for automating 3rd
| party software we were told could not be done. TCL/Expect: Hold
| my beer!
| NelsonMinar wrote:
| TCL is a primary language for sqlite testing:
| https://www.sqlite.org/testing.html
|
| I never liked TCL because the string quoting rules were almost as
| bad as Shell's. For small scripting I prefer Lua.
| gorjusborg wrote:
| Similarly, Redis uses TCL for unit testing.
| stevekemp wrote:
| Well Redis started off being written in TCL.
|
| https://gist.github.com/antirez/6ca04dd191bdb82aad9fb241013e.
| ..
|
| And of course Antirez has a soft-spot for TCL:
|
| http://antirez.com/articoli/tclmisunderstood.html
|
| Which inspired me to create a (trivial) TCL interpreter in
| golang. Not perfect, but almost as good as picol:
|
| https://github.com/skx/critical
| dangerboysteve wrote:
| I just remembered the Decent Espresso machine has its UI written
| in tcl/tk https://decentespresso.com/
| Pompidou wrote:
| I have a tcl/tk distribution (now IronTcl 8.6.7) with tcllib on
| each computer I use since a lot of time. It's very handy : md5
| and other hash tools ? tcllib. Quick and simple representation of
| data as graph and calculations ? tcllib. Simple data
| structuration ? Tcl dicts. String search/substitutions/regex ?
| pure tcl. batch operations on files/folders ? pure tcl. Easy and
| fast database with sqlite ? Tcl sqlite lib. Custom menu and app
| launcher in your desktop ? Pure Tcl. Hex and binary file reading
| and formating ? Pure tcl. And so on. As a public administration
| worker, Tcl Tk helped me working very faster for a lot of tasks.
| generalizations wrote:
| I've actually found some use for it as a lisp-ish shell scripting
| language, when the project grows too large for a bash script. In
| cases where there's a lot of interaction with the OS and a lot of
| text processing that has to be done on the results, python just
| gets in the way and TCL is well suited for that.
| IggleSniggle wrote:
| Honestly I wish all the old awk fanatics had been tcl fanatics
| instead.
| catminou wrote:
| I wonder how many folks learned of tcl/tk cause of eggdrop.
| ursuscamp wrote:
| I learned it originally because of Xircon:
| https://en.wikipedia.org/wiki/XiRCON
| jll29 wrote:
| I found Tcl hard to write, read and debug. (But I'm quite
| impressed with some of Ousterhout's writing.)
|
| In contrast, Python is easy to read, write and debug.
|
| I quite like the small footprint of Lua as an embedded script
| language, which is easy to read, write and runs relatively fast.
|
| I'd probably use Lua or a Scheme as an embedded scripting
| language if I had the need (generally, I try to not let my
| programs get so big that the require embedded scripting, but
| instead attempt to create orthogonal CLI commands that do one
| thing well and that can be scripted from the outside via POSIX
| sh).
| giraffe_lady wrote:
| Everyone likes lua but out of the box it's pretty poor for
| string manipulation, a particular strength of tcl. I don't
| consider them to have much overlap for that reason.
|
| Lua's match system is cool for what it is, and how small its
| implementation is. But it's really not powerful in the end and
| lua has almost no other string tools in the standard lib.
| synergy20 wrote:
| lua has decent string lib in the stdlib, you can also use 3rd
| party libraries such as https://github.com/stein197/lua-
| string, I'm not familiar with tcl, can you elaborate why tcl
| is much better than lua in string manipulations?
| nick__m wrote:
| In tcl strings are first class citizens as everything in
| tcl is a basically a string.
| giraffe_lady wrote:
| Lua has a very minimal string library that doesn't include
| basic things like escaping and interpolation. It doesn't
| include regex. I understand the choices behind these
| decisions and don't disagree with them. But what it means
| is now you're not just embedding lua, you're embedding lua,
| vendoring extensions to the standard library, and selecting
| a regex implementation compatible with your expected
| runtime and distribution method.
|
| Tcl is built around string manipulation, it's the main and,
| for a long time, only data type. It has regex built in, a
| full set of string manipulation functions, and an
| interpolation primitive.
|
| It's not about what's _better_. They are both full blown
| programming languages and you can implement any behavior
| you care to. In lua you have to care to implement string
| functions if you 're going to do anything complex with
| strings. Tcl comes with them. That's all.
| pfix wrote:
| Not OP, but I think the reasoning behind that argument is:
| TCL has only one data type: string. Everything you do in
| TCL is reduced to string manipulations up to having
| optional function arguments starting with a - like a shell
| command. A string in TCL is like a list in Lisp, the most
| fundamental building block.
| boringuser2 wrote:
| One thing about scripting languages is that it doesn't seem like
| a hugely meaningful choice anymore.
|
| GPT-4 can easily generate trivial scripts in any language.
|
| Any complex codebase can be maintained in a typical language.
| jrm4 wrote:
| So curious as to why this got downvoted -- it feels exactly
| right.
| boringuser2 wrote:
| Tech type people that previously found a massive value in
| producing simple scripts probably wouldn't like this. It
| erases the value of the skills they developed.
|
| Only a professional programmer is insulated from this
| obsolescence.
|
| I am sympathetic to the fact that low-knowledge tech workers
| had their value erased over night. I don't have any solutions
| for this problem.
| DonaldPShimoda wrote:
| Any sufficiently complex LLM-generated program is
| (semantically) indistinguishable from garbage.
| boringuser2 wrote:
| GPT-4 is fantastic as one-off scripts for any task.
|
| It can produce scripts in seconds that might have taken
| technical support people an entire day (stretched to a week
| or more of work) prior.
|
| Of course, it can't maintain a codebase like a professional
| developer can. Thank God.
| jrm4 wrote:
| Well duh, that's not what you use it for. You use it to
| generate parts and snippets quicker.
| generalizations wrote:
| I've found that GPT4 is particularly good at generating TCL
| code. Possibly because what's out there is generally high-
| quality, possibly because there's very little syntax for it
| to keep track of.
| lizknope wrote:
| Most of the digital semiconductor design EDA / CAD tools from
| Cadence and Synopsys use Tcl as the built in scripting language.
| I have to work with thousands of lines of Tcl code whether I want
| to or not.
|
| I learned Tcl / Tk back in 1995 because I wanted to write GUI
| programs and Hello World in Motif was about 2 pages of boiler
| plate code while in Tcl / Tk it was about 2 lines.
|
| Then I started in the chip design world and Tcl took over so it
| was good that I already knew it. I was teaching the older
| engineers Tcl so it helped me gain their respect.
| BeetleB wrote:
| Although I never used Tcl myself, I've worked in/with teams
| that need to interface with these EDA tools, and most of the
| folks there are _not_ SW programmers, but electronics folks who
| need to write Tcl to get their job done.
|
| Their code sucked like crazy. Usually in such teams you are not
| evaluated by the quality of code.
|
| Ever since then, any time I'm job hunting and I see a listing
| for a SW programmer that mentions Tcl, it's always been for EDA
| tools and I run in the other direction.
| doix wrote:
| > Their code sucked like crazy. Usually in such teams you are
| not evaluated by the quality of code.
|
| I worked in the semiconductor industry, specifically writing
| internal tools. I had to look at _many_ tools/scripts written
| in Tcl/SKILL/perl/awk/sed with some code being 30 years old
| and still being used.
|
| Honestly, it wasn't the worse thing. There was usually very
| little abstraction, the code pretty much always told a story
| of what the writer was trying to achieve. Naming things was
| usually pretty bad and you'd get into some pretty gnarly
| regex/string matching, but at least it usually wasn't some
| over-complicated highly flexible but also restricting in-
| house framework.
| i_am_a_peasant wrote:
| at my last job we used tcl for manufacturing tests
| automation. it was way better than the dsl they previously
| had. tcl was chosen because it was easy to port an
| interpreter to their c++ test automation framework
| zwieback wrote:
| Maybe because EDA users think in terms of hardware
| description languages like Verilog. When I realized that they
| have to start with things as basic as clock edges and
| registering signals it dawned on me that that mindset also
| lends itself to TCL code unpalatable to SW engineers.
| Kosirich wrote:
| Siemens NX uses it for the CAM post-processor customization.
| appleflaxen wrote:
| What are your thoughts? How do you like it as a language?
| MrStonedOne wrote:
| [dead]
| malkia wrote:
| The only two times I've touched something remotely tcl was -
| working on Metal Gear Solid's port from PS1 to PC - it used TCL-
| like scripting language for the levels, functions were main-like,
| e.g. "Chara_Init(int argc, const _argv[], /_ something else here
| */)", and then it was quickly parsing arguments (like tcl) to
| initialize initial state and types of characters/items/etc.
|
| The second one was through Maya, if you can call maya's language
| tcl.
|
| It was fascinating to me back then, but nowadays I'm leaning more
| and more towards static typing.
| LexiMax wrote:
| This is an amazing - I remember that PC port and you can even
| buy it on GOG today.
|
| Do you have any interesting stories from the porting process?
| DonaldPShimoda wrote:
| > Ousterhout's dichotomy claims that there are two general
| categories of programming languages: > > low-level,
| statically-typed systems languages > high-level, dynamic
| scripting languages
|
| I understand that this may have seemed somewhat more true at the
| time it was originally stated, but it's not really been true
| since the '90s, and it's certainly not true now. What an odd
| thing to lean into in this day and age.
| lanstin wrote:
| The general principal of alternating soft and hard layers is
| still a useful design tool. Even starting from silicon with the
| microcode emulation of the x86 instruction sets, kernel,
| syscall interface, building an app and exposing configuration,
| whether into Tcl, yaml, tool, .properties, json or xml, it's
| very likely the consumers of complex software will want to
| configure its characteristics into a specific use case, but the
| implementation will be more general. Look at LLM as he ultimate
| soft layer.
|
| Unless your team manages to never write YAML files.
| ukuina wrote:
| Are you saying the lines are blurred, or that there are more
| tiers of abstraction?
| TillE wrote:
| It's all shades of grey. Look at C#, it's a statically-typed
| high-level language which runs in a VM, but can also be
| compiled to native code. It has a massive standard library
| and can do all sorts of script-y things (see eg, top-level
| statements), but can also be tightly optimized to avoid GC
| allocations. You can mess with pointers in unsafe blocks.
|
| The only thing it really can't do is kernel code.
|
| Even C++ is incorporating more and more high-level
| constructs.
| BiteCode_dev wrote:
| The author should rather be honest and say "I like TCL just
| because", instead of coming up with contrived examples to state
| alternatives are bad.
|
| E.G, in the Counter snippet, why make some complicated code when
| Python is designed to make it simple? import
| sys, collections for p in sys.argv[1:]:
| try: with open(p) as f: for
| k, v in collections.Counter(f).items():
| if v > 1: print(v, "\t", k, end="")
| except Exception as e: print("dup error: ", e)
|
| I don't buy the argument of simplicity here. Also, if you are
| going to just do "get", you don't need requests, the stdlib is
| fine.
|
| And I don't get the speed argument either, given his script uses
| most_common(), that basically sorts the entire dict, which none
| of the other codes do. Yes Python is likely slower, but let's not
| push it.
|
| Also the Go code is more complicated, but you can cross compile
| it and ship it as is. And it's fast.
|
| I get it, TCL is cute, but making up arguments is not selling it.
| eesmith wrote:
| The "take command-line input and print it out" in Python is
| even more succinctly written: import sys
| print(*sys.argv[1:])
| bragr wrote:
| The author, while having a passing familiarity with it
| obviously, is clearly not a Python expert, so take all the
| Python stuff with a major grain of salt. Like they claim not to
| know how to get granular exceptions out of the requests
| modules:
|
| >The requests here is a third-party package that required
| installation and a virtual environment to use. I don't know how
| to catch more granular exceptions in this example.
|
| so I guess they even didn't RTFM:
|
| https://requests.readthedocs.io/en/latest/api/#exceptions
| karl_gluck wrote:
| Yeah--as a TCL fan, I agree. Comparing implementations of
| common coding tasks with other languages doesn't highlight
| TCL's strengths or, really, its purpose.
|
| Personally, TCL fits a niche like QBASIC did. QBASIC was the
| shortest path from brain -> code drawing on a monitor.
| Literally 1 line to draw a shape, no initialization and not
| even an entry point function.
|
| TCL similarly lets you just get on with what you're doing when
| you need glue code, GUI's, and DSL's. It is easily (even
| trivially) able to do things that are just a pain in other
| languages, especially all at once:
|
| - interop with native code (no limits on who calls who or in
| what order)
|
| - define GUI's that behave well without it being a huge pain to
| make anything non-trivial (lookin at you, UE5)
|
| - create novel control flow that feels built-in
|
| - implement an interactive GUI debugger with breakpoints &
| variable watch in ~200 LOC (saw this once, it's amazing what
| you get "for free")
|
| - save or load a running program's entire state, including code
| defined at runtime
|
| - detour any function, allowing you to optimize or patch on the
| fly
|
| - run from tiny, standalone executables so your users don't
| have to install a ton of crap just to run your widget
|
| There's more but you get the idea. It's been around for decades
| for a reason :)
| kazinator wrote:
| TXR Lisp: (each ((file *args*)) (catch
| (dohash (k v [group-reduce (hash) identity (op succ @1)
| (file-get-lines file) 0])
| (put-line `@v\t@k`)) (error (e) (put-line
| e *stderr*))))
| kajaktum wrote:
| Sure its good but its a one off script, so who really cares how
| fast the startup is? Or how elegant it is? I can literally ask
| LLMs to write a rough working code in seconds and I only need to
| fix it up a little bit. There's way more resources to find
| solutions in Python out in the wild that I can leverage.
|
| I would imagine if you just have a tiny bit harder problems, the
| Tcl code quickly becomes unwieldy and you end up digging through
| the archives to find some wizard's tome (or maybe there's a large
| community of Tcl users out there? IDK).
|
| I can easily spin up a GUI in an hour tinkering with PyQt. Can
| you do the same in Tcl?
|
| DSLs like this tend to have a very nice local maxima. But once
| you stray away from its original use case you start writing some
| really confusing code.
| cmacleod4 wrote:
| "I can easily spin up a GUI in an hour tinkering with PyQt. Can
| you do the same in Tcl?"
|
| No, it would probably take 10 minutes with Tcl/Tk ;-)
| o1y32 wrote:
| The article is so laughable.
|
| 1. Of course "Hello world" takes more lines in Go than Python or
| Tcl. But that does not mean anything. The "overhead" here will
| become meaningful for larger scripts/projects, and Go or Python
| are far more capable of much more complex things than Tcl. This
| is simply a dumb example.
|
| 2. Other than certain circumstances, I never heard any one care
| about scripting performance on the ms level. Often not even at
| 1-2s (which rarely happens anyway). Putting a table out there and
| say "this is faster by <1ms" is meaningless to anyone other than
| the author.
| greenpeas wrote:
| #!/usr/bin/env tclsh puts $argv
|
| I kinda wanted to stop reading after this example. It feels
| dishonest to start with an example for which there is a builtin.
| Why didn't you show instead how to output arguments joined by a
| comma or some other separator instead of space. If I were to
| update the Go or Python examples to use another separator, it'd
| be just a 1-2 character change, whereas for Tcl I have no idea
| how that would look.
| pwg wrote:
| > Why didn't you show instead how to output arguments joined by
| a comma or some other separator instead of space.
|
| The Tcl variant to output "comma" as separator (note -- this is
| not "CSV"). puts [join $argv ,]
|
| If you wanted "comma space" you'd do: puts
| [join $argv ", "]
|
| If you actually wanted "CSV" then it would be (assuming tcllib
| is installed): package require csv
| puts [csv::join $argv]
| AshamedCaptain wrote:
| Funnily neither version gives the correct result when you have
| arguments with spaces, e.g. for "-v 5" -d , the tcl one will
| print {-v 5} -d as a consequence of how tcl represents lists.
| pwg wrote:
| The author should have done: puts [join
| $argv]
|
| to avoid that little issue. Doing "puts $argv" triggers Tcl's
| output of "lists" in a special format that allows the list to
| be parsed from the text again at a later time.
| shrubble wrote:
| The author is following examples given in a book, however.
| greenpeas wrote:
| Oh, I missed that. I guess it's alright then. I thought they
| chose this particular example to "showcase" Tcl by
| comparison.
___________________________________________________________________
(page generated 2023-06-20 23:02 UTC)