Heh, I wonder if anyone has tried transpiling the C generated by Chicken Scheme to Go.
Would be interesting to see how (horrifically?) the garbage collector would fare in performance once it's transpiled to a garbage collected language like Go.
What would also be nice is an ML or Lisp transpiled to Go. Go has a nice compiler with a lot of money thrown into it, but it's locked into one syntax, and set of language features that isn't optimal for every use case, so it's a good target for transpilation.
It would be fun to see Go with a terser syntax, better type inference, nicer error handling, etc.
Something like that would be amazing, like the godsend that Scala was for the JVM back when Java was very, very imperative and totally stagnant, though Scala didn't/doesn't transpile to Java, but compiles to JVM bytecode directly. I don't think the same would be possible for Go, which is a shame, but AFAIK there is no such intermediate to target. And given how limited Go itself is, I wouldn't be all that optimistic that a transpiling approach could support many advanced features without tanking performance because you just can't model them efficiently in Go at all, even if you limit enforcement of most guarantees to the transpiler.
I’m not who you are responding to, but optimizing recursions (e.g. tail-call elimination), loop fusion, etc. Functional languages (at least haskell) does plenty of optimizations not generally possible in imperative codes.
tail call elimination is possible by converting the tail-recursive function to a loop. in fact Go could support it, but the team doesn't want to do that.
I agree that everything Haskell does would be hard, but everything e.g. Clojure does should be possible
Compiling functional languages to other high-level language s generally has pretty awful performance compared to simple native compilation. Even compiling to C has it's limitations.
The fact that Go has a nice compiler doesn't really help, because the code generated by the functional compiler will have usage patterns that are very different from what the Go compiler is designed around.
I’ve used all of those except SML. Go is much easier to set up and get productive in, in my opinion. And if you care about compilation speed, you can forget about F#.
> the old word already perfectly describes translating from one formal language into another
The word “compiler” actually doesn’t do that (like, say, “translator” would). “Compiler” originally referred to something more like what is today called a linker. It “compiled” (put together) a set of subroutines (in assembly/machine code) into a combined executable.
You were arguing that the word “perfectly describes translating from one formal language into another”. The word doesn’t do that, as it’s not descriptive in that sense.
Furthermore, translating from (say) JSON to XML is also “translating from one formal language into another”, but that’s not an example of what we mean by “compiler”.
So what do we mean? That’s actually not easy to define. Defining it as translating from one programming language into a different programming language isn’t quite correct, because machine-code binaries aren’t a programming language. Defining it as translating from a programming language into a different representation preserving the program semantics is also not quite correct, because e.g. pretty-printing to HTML would arguably fit that definition.
Clearly there’s some general definition of what we mean by “compiler”, even if I’m failing to find a precise and correct wording for it here. But there’s also the more narrow meaning of “translating from a programming language into object code”, which is what is usually meant in the majority of cases. Because we don’t have a separate word for that narrower definition, there is some ambiguity. The word “transpiler” resolves the ambiguity in one direction. In the other direction, the ambiguity is usually resolved by assuming that “compiler” means “to object code” by default when the context doesn’t specify otherwise.
> machine-code binaries aren’t a programming language
Machine-code binaries aren't (they are programs), but ISA of a CPU is.
I'd plug in a requirement of Turing-completeness for the source and destination language, and at that point the "semantics-preserving" variant makes perfect sense to me. Although canonically textbooks and Wikipedia don't seem to require that, so I'm fine accepting a definition not requiring Turing-completeness, just preservation of semantics.
It makes sense to drop Turing-completeness. Many interesting languages are not Turing complete.
Perhaps the most practical example: just-in-time compilation of regular expressions to native code via LLVM. Regular expressions are not Turing complete.
Another example: take Agda as a source language. Agda is deliberately not Turing-complete, but can express almost any program you might be interested in. (Basically, Agda only allows you to express terminating programs. That's why it's not Turing complete.)
> Furthermore, translating from (say) JSON to XML is also “translating from one formal language into another”, but that’s not an example of what we mean by “compiler”.
I'd be perfectly happy to describe that as a compiler.
Transpiler is a pretty old word too. My understanding is that it's a compiler whose output is human readable. Readability is more about whether it is an explicit goal: all compiler output is readable by some humans.
I don't think anyone would say Unity's il2cpp is a transpiler even though it compiles .net bytecode into C++: producing readable C++ is a non-goal for il2cpp.
> Also why do people invent a new word 'transpile'
Not this ignorant myth again - it isn’t a new word, been in use since mid 60s. A transpiler is a form of compiler from high-level language to high-level language. A compiler didn't even originally translate, but just link.
The same way ‘navy’ is a kind of blue but we can say navy and add a little more specific information. Nobody rails against navy saying ‘but it’s just a shade of blue!’
> Also why do people invent a new word 'transpile', when the old word already perfectly describes translating from one formal language into another?
The answer is... the old word ('compiler') didn't mean what it does today, back in the 60s, when 'transpiler' was coined. Compiler with its current meaning isn't a much older word than transpiler - they're near contemporaries (50s and 60s). Before that a compiler meant a linker.
Ok, that makes sense. I had thought 'compiler' was from the 1950s and already had its modern meaning.
Of course, if we had more rational vocabulary, we'd call them 'translators' instead. (In fact, that's what German does. Perhaps they coined their corresponding term a bit later, when things had already shaken out a bit more.)
That is absolutely not true. Just because early compilers acted more like linker/loader doesn't mean they used the word compiler to mean "linker". When the term was coined it absolutely meant translating mathematical formulas into machine code. Compiler very much had the same meaning it has today.
Sorry that's not my understanding of the history - early compilers were more like what we'd call today template compilers - linking blocks of pre-defined machine code together.
Yes, that is very much what they were. However, they used the term compiler in very much the same way it's used today. It didn't mean something different. The concept of the "compiler" was to translate mathematical symbols (or predefined machine code representing that math) and later English like words into programs a machine could execute.
The selling point of Go is readability, feature minimalism and code that might be boring to write but gets you readability in return. Putting a Lisp on top of that throws these away.
I'm not saying there's nothing left - channels, maybe the standard library. But putting a Lisp on top of Go feels like going strongly against the grain.
But Go is not that readable. In fact across all languages I know I would factor go towards the bottom end of readability. Mostly because of it's insane error handling overhead. A lot of function bodies are like reading a book where every sentence is followed with 3 that have no meaning.
The fact that goland automatically collapses error handling blocks is solid evidence that enough developers find go's error handling blocks to be invasive.
I agree. My point is that you can't objectively define readibility, so it will always be a matter of preference. I've met my share of Go developers that think it is very readable. I personally can't stand it.
You don't understand 'readability' the same as the language creators.
More text to read doesn't necessarily make a file or function less readable. Quite the opposite usually.
IntelliJ collapses the repeatedly occurring err != nil blocks with expandable placeholders in grey color to aid readability. Not the ultimate evidence but says something when a commercial product spends effort behind such features.
I don’t know, I understand most assembly line I see in isolation, yet often have no idea what the whole does. Sometimes too primitive primitives actually hinder readability/understanding.
I know many don’t feel that way, but functional stream manipulation is a very good example for that — I much rather deal with filter.map.reduce whatever, than 3 nested for loops with random breaks inside, even though the latter may be easier to reason about line-by-line
Not necessarily no. It's a balance. And Go skews so far that it's no longer reasonable. It's so bad that the most popular Go IDE by default removes the error handling code from view.
That’s a myth. Go read some random Go. Trivial functions often do nothing but call a couple of other functions, check errors and return. But non-trivial functions use relatively less lines for error handling.
> The selling point of Go is readability, feature minimalism and code that might be boring to write but gets you readability in return.
That is one selling point. Another is that it's a GC'd language that compiles to native on all major platforms, and is more popular than the alternatives, like OCaml, Haskell, D, Common Lisp. Just like Java was used as a platform on which to build languages, like Groovy, Scala, Clojure and Kotlin t otake only the most popular.
Besides the (subjective) advantages that you've mentioned, the selling points of Go include standalone binaries, fast compilation, a good standard library, and crucially, strong corporate support. A transpiled language could benefit from those.
I've been dinking around with generating Go from Lisp macros. For me the motivation is that infra teams in my company have been supporting Go but dropping the ball on Java/Scala, so I want to generate review-ready code for them while letting my experienced team work in some more complete language (maybe Java though that seems like a lot of work for a prototype).
Ecosystem, you forgot ecosystem. Go has lot of mature libraries. So new language will not have to create yet another library for HTTP server, JSON parsing, SSH connection, key-value DB, SQLite connection etc..
And network applications can be written without relying on async.
JVM: 'bloated' or at least the perception of it. Now improving quite fast but also Oracle.
Dot net: still Microsoft.
C/C++: Not similarly high level languages
Scripting languages: lol slow.
Turns out Go ecosystem isn't that tiny at all. Yeah java is larger but also comes with a bad perception among other programming language users. So after Java, if you're targetting a general purpose audience, it's Go I think.
Never really understood this company-problem - if we squint hard enough, then perhaps .NET is really too Microsoft-centred (though improving rapidly in recent years), but Java has multiple, fully independent implementations and a specification. It is much much more open than Go in this regard, though again, I think it is often overblown of a problem.
Not trying to start a flame war, but.. is the Go compiler nice? Other than being fast, and static compilation what good features does it have compared to say the LLVM toolchain? It barely does any optimizations.
Would be interesting to see how (horrifically?) the garbage collector would fare in performance once it's transpiled to a garbage collected language like Go.