Tcl Ported to Go
gitlab.com
gitlab.com
This person or this collective have been transpiling C projects into Pure Go projects, like sqlite[1], libx11[2], xcb[3], and much more[4]… They use their own homegrown transpiler from C99 to Go.[5]
I can only have respect and admiration for whoever is behind this effort :)
[1] https://modernc.org/sqlite
[2] https://gitlab.com/cznic/x11
Even as a Czech, I have no idea if they are owned/governed by state, or not. I need to look into wiki for that.
edit: oops it might be entirely unrelated. Sorry!
edit2: my confusion is understandable, as cz.nic has some open-source projects, too!
https://www.nic.cz/page/2049/projekty-pro-odbornou-verejnost...
For example open source routers Turris
But I believe, based upon my membership on the GoNuts group / mailing list, that this is mostly the work of one individual, Jan Mercl (he is quite active in GoNuts) — as also stated in the previously mentioned AUTHORS file, and in the AUTHORS file for the port of Tcl that is the subject of the OP [1].
I have used some of his non-transpiled code/projects in my own Go projects in the past. He seems to be a very solid coder, often happy to share his views in GoNuts, and also frequently reviews others' code too.
This sort of code isn't readable, idiomatic nor maintainable.
https://gitlab.com/cznic/tcl/-/blob/master/lib/capi_windows_...
> This sort of code isn't readable, idiomatic nor maintainable
isn't really fair. The original code is hopefully readable, idiomatic and maintainable, and if the transpiler does a correct job, who cares about the output any more than I care about the ugliness of the ASM in my object code when I compile it from source.
Yes, it's true that it doesn't matter if you only want to get the code running in a Go environment for whatever reason. But anyone wanting to learn about TCL or idiomatic Go by reading the source code for this project will be disappointed, and that struck me as the main appeal of this when I saw the headline.
A port would imply and independent maintenance.
Here you wouldn't maintain that codebase, instead you'd fix the upstream or the compiler, and recompile.
Quite the opposite. Port refers to targeting a different environment using the same codebase. The aforementioned ARM port wouldn't require a new codebase to maintain, but rather a new/modified compiler to target the ARM environment. Similarly, a macOS port of Linux software wouldn't require maintaining another codebase, it would require changing the compiler to support a macOS target.
> Here you wouldn't maintain that codebase, instead you'd fix the upstream or the compiler, and recompile.
Exactly. In this case a different compiler that targets the Go environment has been introduced. That does not imply that the compiled output is what should be maintained going forward. You wouldn't maintain the product of an ARM port or macOS port either. It is a port, not a fork. Fork is the word we use when there is implication of independent maintenance.
On extreme end, porting something from let's say Commodore 64 to Spectrum ZX would be more a complete rewrite.
I also don't really understand the point of this project. Since it's compiled from C, it doesn't get any of possible benefits of using a language that is not C.
That may be part of the process, sure. The formal definition isn't clear on exactly what process is necessary to target a new environment, just that some action is necessary. Introducing a new compiler is one possible action to achieve the result.
However, when you do have to modify the code like you suggest, typically you are adding the environment specific aspects in #ifdef-type directives, so you're still not introducing a new codebase to maintain. It's still the same codebase that will be maintained just as it always way.
And even if you want to split hairs, no matter how you slice it there is no implication that the product of the port is what you will maintain. I still have no idea where that is coming from.
> I also don't really understand the point of this project.
To avoid cgo when using the library, I'm sure. Isn't that the point of a lot of cznic/modernc.org's projects?
I'm interested in the source of this "formal definition", because it doesn't really match anything I have come across over the years.
> typically you are adding the environment specific aspects in #ifdef-type directives
Not really, more like writing platform-specific parts as separate modules. Of course you can write Java for Android and Objective C for iOS in the same file if you really want, but it doesn't make much sense. Or even write a compiler that takes a source file with target-specific paths and transpiles to Java and Objective C if you want to go all in. I've never seen anyone do that.
"In software engineering, porting is the process of adapting software for the purpose of achieving some form of execution in a computing environment that is different from the one that a given program (meant for such execution) was originally designed for (e.g., different CPU, operating system, or third party library)."
Here we have software (Tcl) that was adapted to work in a computing environment (Go) that is different than the given program was originally designed for. This doesn't seem very controversial.
> Of course you can write Java for Android and Objective C for iOS in the same file if you really want, but it doesn't make much sense.
If you are changing the language software is written in, it is a stretch to call that porting. That isn't even a fork. That is a new project.
The Go project's gc compiler was source-to-source compiled from its original C codebase into a Go codebase, which became the new source as the original C code was abandoned. Is this the origin of your confusion? That is a strange place to arrive just because Go is in the title, though.
Or is it that you also don't understand what the word source means?
> Compiling is repeatable, however. Porting is done once.
Second,
> The original Tcl codebase written in C remains the source and must be compiled each time it is modified to keep this Go package in sync.
which implies that it is done more than once. If you are talking about something else than the Go "port" of tcl, it is not really obvious to me what it is.
In the case in question, Tcl was both ported and compiled to Go. There was a process required to allow the software to run in an environment it was not originally designed for, and there was a process required to transform the software into another language.
Said compiler is one of the things that was produced to allow porting to the new environment. The compiler is not the port. Porting is not compiling. We've been over that many times now.
> while the tcl was running nothing else was being done, so you could rearrange memory and it was cool as long as you finished before the end of the command
My mind immediately springs to all the ways this can go horrifically wrong.
There's support for deep coroutines and non-blocking I/O so it isn't limiting. You only really need multiple threads when dealing with compute-heavy code or a particularly crufty API.
It was desgin3d to be easily horizontally scalable, and to be easy to write code for that was stable. We would put one process per CPU, and leave one for the OS. Also would put in one Ethernet card per process, if it was one that talked to the internet, and then used a user-land TCP stack on top of DLPI (?).
The services there were all high volume but not super latency sensitive, so. A poll/select loop that spun a thousand times a second or so was fine. You could add or reload all kinds of config without restarting and hence without losing any traffic. It was designed for zero downtime maintenance.
There were a few HTTP servers written for things like AOLTV and as an RPC gateway from third parties into the “host complex” e.g. one called ewoks was used for user registration. It was headless, only gave out 302 replies or 4xx replies.
What about the unattractive ones, Harvey Weinstein?
Ok I’ll leave quietly
It's on most of the other fronts that it did.
But any harm done by Tcl is more than redeemed by its creator being the author of one of my favorite of all programming books, A Philosophy of Software Design.
I briefly worked on a WASM to TCL transpiler so I could write EDA scripts in Rust. Got it kind of working but WASM is actually quite large and TCL integers in the version I was forced to use (thanks PowerArtist) are completely broken so it ended up being not worth it.
obviously I was the go to expert on everything related to computers and I still remember the shock when she told me that I need to spend my weekends on helping her to understand tcl.
Here's a link to his C to Go translator: https://gitlab.com/cznic/ccgo
https://gitlab.com/cznic/tcl/-/blob/master/lib/tcl_windows_a...
But seriously, I would expect most editors to handle large files relatively gracefully, even if they aren’t as fast as vim for example. Browser based code viewers on the other hand, I grant you, aren’t generally up to the task.
some don't care about the "in $lang" branding.
I recall Tcl being described as a Lisp without the parenthesis many years ago, which I still think is somewhat apt.
Antirez' article "Tcl the Misunderstood" [0] is well worth a read if you want to know more.
He also has an interpreter, Picol [1], in 500 lines of C code that is very easy to read and to understand.
"hey this can do everything tcl does, but we are not going to show you, you just will have to find out yourself"
Tcl can still be found in a few places powering some pretty critical infrastructure, I know a few networks running with significant automation being driven with Tcl
Why be cgo-less, when in the end, it is just transpiled, with unsafe.pointer everywhere?
Do you gain some portability, that was not in the original C? Is there a speed gain, or ease to build gain?
Maybe the end "consumers" have it simpler, because they don't need to worry about cgo, but then it's harder to compile in the first place.
I also share the same sentiments [2].
[1] A command language on top of D:
https://til-lang.github.io/til/
[2] Tcl-inspired command language on top of D:
Some things I love about Tk:
- adds a cool 1990s retro aesthetic
- usable in X11 tunneled over an SSH connection
- doesn't consume all available CPU and memory resources
- the Tk canvas is a beautiful thingI just physically shuddered. Tk with GDI was a work of art. Electron is... not that.
Pithy joke aside, TCL is an underloved language and I'm always happy to see it in projects. Nice work!
Thankfully that was my last exposure to TCL.
Thanks Robey.