Transpiler, a Meaningless Word (2023)
Mood
calm
Sentiment
mixed
Category
other
Key topics
Compilers
Programming Languages
Terminology
The article argues that the term 'transpiler' is meaningless, sparking a discussion on the definition and usefulness of the term among HN commenters.
Snapshot generated from the HN discussion
Discussion Activity
Very active discussionFirst comment
2h
Peak period
92
Day 7
Avg / period
18.8
Based on 113 loaded comments
Key moments
- 01Story posted
Nov 6, 2025 at 3:26 PM EST
19 days ago
Step 01 - 02First comment
Nov 6, 2025 at 5:27 PM EST
2h after posting
Step 02 - 03Peak activity
92 comments in Day 7
Hottest window of the conversation
Step 03 - 04Latest activity
Nov 17, 2025 at 4:08 PM EST
8 days ago
Step 04
Generating AI Summary...
Analyzing up to 500 comments to identify key contributors and discussion patterns
I think this is a pretty acceptable definition, and yes, it does make the term transpiler a little useless.
I think this is how the word is commonly understood, and it’s not useless (even if there’s no absolute standard of when it does or does not apply).
Edit: sorry, realise I should have read the article before commenting. The article calls out my definition as one of their ‘lies’. I guess I just disagree with the article. Words can be useful even without a 100% watertight definition. They’re for communication as well as classification.
Overall, I find this discussion very odd. It seems like a kind of deletionism for the dictionary. I mean, what's the use of the word 'crimson'? Anything that's crimson is also just 'red'. Why keep 'large' when we have 'big'? You could delete a large percentage of English words by following this line of thinking.
The same thing applies to compilation to Javascript, the resulting code may use a tiny subset of the language.
I don't like the word transpiler, because there is nothing useful about the distinction (unless you count people using it to denigrate compilers that doesn't target traditional machine code).
I could see the case of using it as a name when the transformation is reversible, like you could probably turn Javascript back into Coffeescript.
In my book, transpilers are compilers that consume a programming language and target human-readable code, to be consumed by another compiler or interpreter (either by itself, or to be integrated in other projects).
i.e. the TypeScript compiler is a transpiler from TS to JS, the Nim compiler is a transpiler from Nim to C, and so on.
I guess if you really want to be pedantic, one can argue (with the above definition) that `clang -S` might be seen as a transpiler from C to ASM, but at that point, do words mean anything to you?
For example, a 'native compiler' outputs machine code for the host system, a 'cross compiler' outputs machine code for a different system, a 'bytecode compiler' outputs a custom binary format (e.g. VM instructions), and a 'transpiler' outputs source code. These distinctions are meaningful.
If you implement SKI combinators, or three-address instructions, as functions in javascript, and that's the output of your compiler, I would not call that a transpiler.
For example, most SCSS workflows I've worked with converert SCSS source code into minified CSS, which is pretty difficult for a human to read. But I think that SCSS => CSS still counts as transpiling.
I would say "yes, but the minimization is an additional step that is not actually a direct part of the transpiling process." :-)
So, a program that does this would not a transpiler by itself, but a program that
- executes a pipeline of which the transpiling is the most important step,
- can also be used as a transpiler by making transpiling the only step in the executed pipeline.
And furthermore, what if you run Prettier on the minified output, turning it into readable CSS? The pipeline as a whole would input SCSS and output formatted CSS and therefore would be considered a transpiler, but the subprogram that does all of the SCSS heavy lifting would input SCSS and output minified SCSS, making it not a transpiler.
P.S. I love your username
I personally think that the central point whether it is a transpiler or not is whether the generated output is in the "spirit" in which the output language was conceived to be written by a human programmer.
So, if the outputted CSS code is in a rather similar "spirit" to how a human programmer would write it (though having possibly lots of traces of being auto-generated), it is a transpiler.
For example, if a transpiler generates hundreds of rules for CSS classes, but humans would solve the problem very differently using CSS code, it is rather not a transpiler, but some program that uses CSS as an output format for the reason that this is the output format that has to be used for technical reasons.
This of course encompasses the case of minified CSS code: hardly any programmer would write minified CSS code in a text editor.
Similarly, I would argue that a "transpiler" that generates highly non-idiomatic C code (i.e. it is "insanely obvious" that the output is not C code in the sense how the C language is "intended" to be used) is not a transpiler, but rather a compiler that uses C as some kind of high-level assembler code for output.
In this sense I would indeed say that some "transpiler" that generates highly non-idiomatic JavaScript code is in my opinion rather a compiler that uses JavaScript as an output format because it is necessary because this is necessary to run the code in the browser. I am of course aware that many programmers do have a different opinion here.
So, I would say a strong rule of thumb to decide transpiler or not transpiler is: if there was a choice to use a different output language than the destination language - would the transpiler use the latter one instead? So, to answer your question
> And furthermore, what if you run Prettier on the minified output, turning it into readable CSS? The pipeline as a whole would input SCSS and output formatted CSS and therefore would be considered a transpiler, but the subprogram that does all of the SCSS heavy lifting would input SCSS and output minified SCSS, making it not a transpiler.
If the goal is clearly to generate idiomatic CSS code that can be well understood by a human programmer, by my stance it clearly is a transpiler. If you, on the hand, create such an example just to find a corner case for "transpiler or not transpiler", I would say it is not.
# some comment
myFun = ->
alert 'Hello CoffeeScript!'
into // some comment
var myFun;
myFun = function() {
return alert('Hello CoffeeScript!');
};
clearly intending the output code to be quite readable (even preserving comments).Whereas Elm is a compiler since it transforms
module Main exposing (main)
import Html
main =
Html.text "Hello Elm!"
into (function(scope){
'use strict';
function F(arity, fun, wrapper) {
wrapper.a = arity;
wrapper.f = fun;
return wrapper;
}
// about 4000 lines ommitted
var $author$project$Main$main = $elm$html$Html$text('Hello Elm!');
_Platform_export({'Main':{'init':_VirtualDom_init($author$project$Main$main)(0)(0)}});}(this));
Clearly not intended for (easy) human consumption.Classifying Nim as a transpiler also results in weird cases like NLVM[1] which most would consider a compiler even though it is a back-end on the same "level" as Nim's C generator.
I suspect the first compilers were named that because they were making compilations of assembly routines, probably slightly modified/specialised to the rest of the routines.
Compilers still do that. Some of the input is your source, but there's also "the compiler runtime" which is essentially a lot of extra routines that get spliced in, and probably "the language runtime" which gets similar treatment.
So compilers are still joining together parts, we've just mostly forgotten what crt or udiv.s are.
Linking and loading are more dubious names, but also they refer to specialised compilers that don't need to exist and probably shouldn't any more, so that may resolve itself over time.
An extreme caricature example of a "lumper" would just use the word "computer" to label all Turing Complete devices with logic gates. In that mindset, having a bunch of different words like "mainframe", "pc", "smartphone", "game console", "FPGA", etc are all redundant because they're all "computers" which makes the various other words pointless.
On the other hand, the Splitters focus on the differences and I previously commented why "transpiler" keeps being used even though it's "redundant" for the Lumpers : https://news.ycombinator.com/item?id=28602355
We're all Lumpers vs Splitters to different degrees for different topics. A casual music listener who thinks of orchestral music as background sounds for the elevator would be "lump" both Mozart and Bach together as "classical music". But an enthusiast would get irritated and argue "Bach is not classical music, it's Baroque music. Mozart is classical music."
The latest example of this I saw was someone complaining about the word "embedding" used in LLMs. They were asking ... if an embedding is a vector, why didn't they just re-use the word "vector"?!? Why is there an extra different word?!? Lumpers-vs-splitters.
I don't think that's a caricature at all; I've often seen people argue that it should include things like Vannevar Bush's differential analyzer, basically because historically it did, even though such devices are neither Turing-complete nor contain logic gates.
A programmable computer is a physical device which has input states which can be deterministicaly set, and reliably produce output states.
A digital computer is one whose state transition is discrete. An analogue computer has continuous state transition -- but still, necessarily, discrete states (by def of computer).
An electronic digital programmable computer is an electric computer whose voltage transitions count as states discretely (ie., 0/1 V cutoffs, etc.); its programmable because we can set those states causally and deterministically; and its output state arises causally and deterministically from its input state.
In any given context these 'hidden adjectives' will be inlined. The 'inlining' of these adjectives causes an apparent gatekeepery Lumpy/Splitter debate -- but it isnt a real one. Its just ignorance about the objective structure of the domain, and so a mistaken understanding about what adjectives/properties are being inlined.
It's unfortunate that "computer" is the word we ended up with for these things.
But to the overall point, this kind of reply is exactly why I don't think this is a case of L vs. S -- your reply just forces a concession to my definition, because I am just wrong about the property I was purporting to capture.
With all the right joint-carving properties to hand, there is a very clear matrix and hierarchy of definitions:
abstract mathematical hierarchy vs., physical hierarchy
With the physical serving as implementations of partial elements of the mathematical.
If you mean that classifications are a matter of convention and utility, then that can be the case, but it isn’t always and can’t be entirely. Classifications of utility presuppose objective features and thus the possibility of classification. How else could something be said to be useful?
Where paradigmatic artifacts are concerned, we are dealing with classifications that join human use with objective features. A computer understood as a physical device used for the purpose of computing presupposes a human use of that physical thing “computer-wise”, that is to say objectively, no physical device per se is a computer, because nothing inherent in the thing is computing (what Searle called “observer relative“). But the physical machine is objectively something which is to say ultimately a collection of physical elements of certain kinds operating on one another in a manner that affords a computational use.
We may compare paradigmatic artifacts with natural kinds, which do have an objective identity. For instance, human beings may be classified according to an ontological genus and an ontological specific difference such as “rational animal“.
Now, we may dispute certain definitions, but the point is that if reality is intelligible–something presupposed by science and by our discussion here at the risk of otherwise falling into incoherence–that means concepts reflect reality, and since concepts are general, we already have the basis for classification.
I'm not sure that your definition helps capture what people mean by "computer" or helps us approach a more ontologically coherent definition either. If, by words like "computing" and "computation", you mean things like "what computers do", it's almost entirely circular, except for your introduction of observer-relativity. (Which is an interesting question of its own—perhaps the turbulence at the base of Niagara Falls this morning could be correctly interpreted as finding a proof of the Riemann Hypothesis, if we knew what features to pay attention to.)
But, if you mean things like "numerical calculation", most of the time that people are using computers, they are not using them for numerical calculation or anything similar; they are using them to store, retrieve, transmit, and search data, and if anything the programmers think of as numerical is happening at all, it's entirely subordinate to that higher purpose, things like array indexing. (Which is again observer-relative—you can think of array indexing as integer arithmetic mod 2⁶⁴, but you can also model it purely in terms of propositional logic.)
And I think that's one of the biggest pitfalls in the "computer" terminology: it puts the focus on relatively minor applications like accounting, 3-D rendering, and LLM inference, rather than on either the machine's Protean or universal nature or the purposes to which it is normally put. (This is a separate pitfall from random and arbitrary exclusions like cellphones and game consoles.)
Indeed. To elaborate a bit more on this...
Whether a definition is good or bad is at least partly determined by its purpose. Good as what kind of definition?
If the purpose is theoretical, then the common notion of "computer" suffers from epistemic inadequacy. (I'm not sure the common notion rises above mere association and family resemblance to the rank of "definition".)
If the purpose is practical, then under prevailing conditions, what people mean by "computer" in common speech is usually adequate: "this particular form factor of machine used for this extrinsic purpose". Most people would call desktop PCs "computers", but they wouldn't call their mobile phones computers, even though ontologically and even operationally, there is no essential difference. From the perspective of immediate utility as given, there is a difference.
I don't see the relevance of "social construction" here, though. Sure, people could agree on a definition of computer, and that definition may be theoretically correct or merely practically useful or perhaps neither, but this sounds like a distraction.
> I'm not sure that your definition helps capture what people mean by "computer" or helps us approach a more ontologically coherent definition either.
In common speech? No. But the common meaning is not scientific (in the broad sense of that term, which includes ontology) and inadequate for ontological definition, because it isn't a theoretical term. So while common speech can be a good starting point for analysis, it is often inadequate for theoretical purposes. Common meanings must be examined, clarified, and refined. Technical terminology exists for a reason.
> If, by words like "computing" and "computation", you mean things like "what computers do", it's almost entirely circular
I don't see how. Computation is something human beings do and have been doing forever. It preexists machines. All machines do is mechanize the formalizable part of the process, but the computer is never party to the semantic meaning of the observing human being. It merely stands in a relation of correspondence with human formalism, the same way five beads on an abacus or the squiggle "5" on a piece of people denote the number 5. The same is true of representations that denote something other than numbers (a denotation that is, btw, entirely conventional).
Machines do not possess intrinsic purpose. The parts are accidentally arranged in a manner that merely gives the ensemble certain affordances that can be parlayed into furthering various desired human ends. This may be difficult for many today to see, because science has - for practical purposes or for philosophical reasons - projected a mechanistic conceptual framework onto reality that recasts things like organisms in mechanistic terms. But while this can be practically useful, theoretically, this mechanistic mangling of reality has severe ontological problems.
In the case of embeddings vs. vectors, classical vs., baroque, transpiler vs., compiler -- i think the apparent 'lumper' is just a person ignorant of classification scheme offered, or at least, ignorant of what property it purports to capture.
In each case there is a real objective distinction beneath the broader category that one offers in reply, and that settles the matter. There is no debate: a transpiler is a specific kind of compiler; an embedding vector is a specific kinds of vector; and so on.
There is nothing at stake here as far as whether the categorisation is tracking objective structure. There is only ignorance on the part of the lumper: the ignorant will, of course, always adopt more general categories ("thing" in the most zero-knowledge case).
A real splitter/lumper debate would be something like: how do we classify all possible programs which have programs as their input and output? Then a brainstorm which does not include present joint-carving terms, eg., transformers = whole class, transformer-sourcers = whole class on source code, ...
Proceeds to urm actually split.
All "ontologies" are false.
There is, to disquote, one ontology which is true -- and the game is to find it. The reason getting close to that one is useful, the explanation of utility, is its singular truth
>In each case there is a real objective distinction
No, Lumper-vs-Splitter doesn't simply boil down to plain ignorance. The L/S debate in the most sophisticated sense involves participants who actually know the proposed classifications but _chooses_ to discount them.
Here's another old example of a "transpiler" disagreement subthread where all 4 commenters actually know the distinctions of what that word is trying to capture but 3-out-of-4 still think that extra word is unnecessary: https://news.ycombinator.com/item?id=15160415
Lumping-vs-Splitting is more about emphasis vs de-emphasis via the UI of language. I.e. "I do actually see the extra distinctions you're making but I don't elevate that difference to require a separate word/category."
The _choice_ by different users of language to encode the difference into another distinct word is subjective not objective.
Another example could be the term "social media". There's the seemingly weekly thread where somebody proclaims, "I quit all social media" and then there's the reply of "Do you consider HN to be social media?". Both the "yes" and "no" sides already know and can enumerate how Facebook works differently than HN so "ignorance of differences" of each website is not the root of the L/S. It's subjective for the particular person to lump in HN with "social media" because the differences don't matter. Likewise, it's subjective for another person to split HN as separate from social media because the differences do matter.
I'm just saying, often there is no real debate it's just one side is ignorant of the distinctions being made.
Any debate in which one side makes distinctions and the other is ignorant of them will be an apparent L vs. S case -- to show "it's a real one" requires showing that answering the apparent L's question doesnt "settle the matter".
In the vast majority of such debates you can just say, eg., "transpilers are compilers that maintain the language level across input/output langs; and sometimes that useful to note -- eg., that typescript has a js target." -- if such a response answers the question, then it was a genuine question, not a debate position.
I think in the cases you list most people offering L-apparent questions are asking a sincerely learning question: why (because I don't know) are you making such a distinction? That might be delivered with some frustration at their misperception of "wasted cognitive effort" in such distinction-making -- but it isnt a technical position on the quality of one's classification scheme
> No, Lumper-vs-Splitter doesn't simply boil down to plain ignorance.
If I can boil it down to my own interpretation: when this argument occurs, both sides usually know exactly what each other are talking about, but one side is demanding that the distinction being drawn should not be important, while the other side is saying that it is important to them.
To me, it's "Lumpers" demanding that everyone share their value system, and "Splitters" saying that if you remove this terminology, you will make it more difficult to talk about the things that I want to talk about. My judgement about it all is that "Lumpers" are usually intentionally trying to make it more difficult to talk about things that they don't like or want to suppress, but pretending that they aren't as a rhetorical deceit.
All terminology that makes a useful distinction is helpful. Any distinction that people use is useful. "Lumpers" are demanding that people not find a particular distinction useful.
Your "apparent L's" are almost always feigning misunderstanding. It's the "why do you care?" argument, which is almost always coming from somebody who really, really cares and has had this same pretend argument with everybody who uses the word they don't like.
There are a small number of highly technical cases where an L vs S debate makes sense, biological categorisation being one of them. But mostly, it's an illusion of disagreement.
Of course, the pathological-S case is a person inviting distinctions which are contextually inappropriate ("this isnt just an embedding vector, it's a 1580-dim! EV!"). So there can be S-type pathologies, but i think those are rarer and mostly people roll their eyes rather than mistake it as an actual "position".
Ha. I see this same thing play out often where someone is arguing that “X is confusing” for some X, and their argument consists of explaining all relevant concepts accurately and clearly, thus demonstrating that they are not confused.
Splitters make more sense to me since different things should be categorized differently.
However, I believe a major problem in modern computing is when the splitter becomes an "abstraction-splitter."
For example, take the mouse. The mouse is used to control the mouse cursor, and that's very easy to understand. But we also have other devices that can control the mouse cursor, such as the stylus and touchscreen devices.
A lumper would just say that all these types of devices are "mouses" since they behave the same way mouses do, while a splitter would come up with some stupid term like "pointing devices" and then further split it into "precise pointing devices" and "coarse pointing devices" ensuring that nobody has absolutely no idea what they are talking about.
As modern hardware and software keeps getting built on piles and piles of abstractions, I feel this problem keeps getting worse.
By your logic I could use the term "apple" to describe apples, oranges, limes, and all other fruit because they all behave in much the same ways that apples do. But that's silly because there are differences between apples and oranges [citation needed]. If you want to describe both apples and oranges, the word for that is "fruit", not "apple".
Using a touchscreen is less precise than using a mouse. If the user is using a touchscreen, buttons need to be bigger to accommodate for the user's lack of input precision. So doesn't it make sense to distinguish between mice and touchscreens? If all you care about is "thing that acts like a mouse", the word for that is "pointing device", not "mouse".
"Computer"? You mean object, right?
Compiling is high-level to low-level (source code to runnable, you rarely look at the output).
Decompiling is low-level to high-level (runnable to source code, you do it to get and use the output).
Transpiling is between two languages of roughly the same level (source code to source code, you do it to get and use the output).
Certainly there's some wishy-washy-ness due to how languages relate to each other, but none of these terms really acts like a superset of the others.
Is there a merit to this? Can whatever you call compiler do more? Is it all three of the things mentioned combined? Who knows - as is stands I only know that you disagree with the definitions given/proposed.
I define a compiler as something that takes an input in a language, does transformations, and produces a transformed output in a language. All of them do that, and they are more specific terms for types of compilers.
Baroque music is a kind of classical music, though.
I think the argument centers on how transpilers are often justified as being something quite different in difficulty than writing a whole compiler -- and in practice, nearly the whole set of problems of writing a compiler show up.
So, it's more like, don't use the distinction to lie to yourself.
Similarly, distinguishing between transpilers and compilers might be important in some contexts and useless in others. Transpilers are source-to-source compilers, a subset of compilers. Whether it matters depends on the context.
Yes, I know. You could argue that a C compiler is a transpiler, because assembly language is generally considered a programming language. If this is you, you have discovered that there are sometimes concepts that are not easy to rigorously define but are easy for people to understand. This is not a rare phenomenon. For me, the difference is that a transpiler is intending to target a programming language that will be later compiled by another compiler, and not just an assembler. But, it is ultimately true that this definition is still likely not 100% rigorous, nor is it likely going to have 100% consensus. Yet, people somehow know a transpiler when they see one. The word will continue to be used because it ultimately serves a useful purpose in communication.
On the other hand, C to Assembly is not such a thin layer of abstraction. Even the parts that seem relatively simple can change massively as soon as an optimisation pass is involved. There is a very clear difference in abstraction layer going on here.
I'll give you that these definitions are fuzzy. Nim uses a source-to-source compiler, and the difference in abstraction between Nim and C certainly feels a lot smaller than the difference between C and Assembly. But the C that Nim generates is, as I understand it, very low-level, and behaves a lot closer to assembly, so maybe in practice the difference in abstraction is greater than it initially seems? I don't think there's a lot of value in trying to make a hard-and-fast set of rules here.
However, it's clear that there is a certain subset of compilers that aim to do source-to-source desugaring transformations, and that this subset of compilers have certain similarities and requirements that mean it makes sense to group them together in some way. And to do that, we have the term "transpiler".
When people say "Same Level of Abstraction", I think what they are expressing is that they believe both of the programming languages for the input and output are of a similar level of expressiveness, though it isn't always exact, and the example of compiling down constructs like async/await shows how this isn't always cut-and-dry. It doesn't imply that source-to-source translations, though, are necessarily trivial, either: A transpiler that tries to compile Go code to Python would have to deal with non-trivial transformations even though Python is arguably a higher level of abstraction and expressiveness, not lower. The issue isn't necessarily the abstraction level or expressiveness, it's just an impedance mismatch between the source language and the destination language. It also doesn't mean that the resulting code is readable or not readable, only that the code isn't considered low level enough to be bytecode or "object code". You can easily see how there is some subjectivity here, but usually things fall far away enough from the gray area that there isn't much of a need to worry about this. If you can decompile Java bytecode and .NET IL back to nearly full-fidelity source code, does that call into question whether they're "compilers" or the bytecode is really object code? I think in those cases it gets close and more specific factors start to play into the semantics. To me this is nothing unusual with terminology and semantics, they often get a lot more detailed as you zoom in, which becomes necessary when you get close to boundaries. And that makes it easier to just apply a tautological definition in some cases: like for Java and .NET, we can say their bytecode is object code because that's what they're considered to be already, because that's what the developers consider them to be. Not as satisfying, but a useful shortcut: if we are already willing to accept this in other contexts, there's not necessarily a good reason to question it now.
And to go full circle, most compilers are not considered transpilers, IMO, because their output is considered to be object code or intermediate code rather than source code. And again, the distinction is not exact, because the intermediate code is also turing complete, also has a human readable representation, and people can and do write code in assembly. But brainfuck is also turing complete, and that doesn't mean that brainfuck and C are similarly expressive.
There's currently a fad in my country for selling "micellar water" for personal skin cleansing, touted as an innovation. But "micelles" are just the structure that any surfactant forms in water, such as soap, dish detergent, or shampoo, once a certain critical concentration is reached, so "micellar water" is just water with detergent in it. People believe they are buying a new product because it's named with words that they don't know, but they are being intentionally deceived.
Similarly, health food stores are selling "collagen supplements" for US$300 per kilogram to prevent your skin from aging. These generally consist of collagen hydrolysate. The more common name for collagen hydrolysate is "gelatin". Food-grade gelatin sells for US$15 per kilogram. (There is some evidence that it works, but it's far from overwhelming, but what I'm focusing on here is the terminology.) People believe they are buying a special new health supplement because they don't know what gelatin is, but they are being intentionally deceived.
You might argue, "People somehow know micellar water when they see it," or, "People somehow know collagen supplements when they see them," but in fact they don't; they are merely repeating what it says on the jar because they don't know any better. They are imagining a distinction that doesn't exist in the real world, and that delusion makes them vulnerable to deception.
Precisely the same is true of "transpilers". The term is commonly used to mislead people into believing that a certain piece of software is not a compiler, so that knowledge about compilers does not apply to it.
Why would people use a word that has the word "compiler" in it to try to trick people into thinking something is not a compiler? I'm filing this into "issues not caused by the thing that is being complained about".
Obviously I believe transpilers are compilers. A cursory Google search shows that the word transpiler is equated to "source-to-source compiler" right away. If it truly wasn't a compiler, didn't have a true frontend and really did a trivial syntax-to-syntax translation, surely it would only be a translator, right? That is my assumption.
But all that put aside for a moment, I do stand by one thing; that's still not really an issue I blame on the existence of the word transpiler. If anything, it feels like it is in spite of the word transpiler, which itself heavily hints at the truth...
It's good to be aware of that from an engineering standpoint, because the host language will have significantly different limitations, interoperability and ecosystem, compared to regular binary or some VM byte-code.
Also, I believe that they are meaningfully different in terms of compiler architecture. Outputting an assembly-like is quite different from generating an AST of a high-level programming language. Yes of course it's fuzzy because some compilers use intermediate representations that in some cases are fairly high-level, but still they are not meant for human use and there are many practical differences.
It's a clearly delineated concept, why not have a word for it.
Historically speaking, almost all video games and operating systems were written in assembly languages similar to this until the 80s.
They also called C a high-level language at that time. There was also more emphasis on the distinction between assemblers and compilers. Indeed, they may have used the word compiler more in the sense we use transpiler now, I'm sure people were also saying that it was just a fancy assembler. Terminology shifts.
I've gotten into arguments with people who refuse to accept that there is any difference worth considering between javascript and bytecode or assembly. From that perspective, the difference between a "transpiler" and a "compiler" is just aesthetics.
And the ecosystem of JVM and BEAM hosted languages does make the concept even murkier.
I think the note about generators may be a good definition for when one language is "more powerful" than another; at least it's a good heuristic:
> The input and output languages have the syntax of JavaScript but the fact that compiling one feature [generators] requires a whole program transformation gives away the fact that these are not the same language. If we’re to get beyond the vagaries of syntax and actually talk about what the expressive power of languages is, we need to talk about semantics.
If a given program change is local in language X but global in language Y, that is a way in which language X has more expressive power.
This is kind of fuzzy because you can virtually always avoid this by implementing an interpreter, or its moral equivalent, for language X in language Y, and writing your system in that DSL (embedded or otherwise), rather than directly in language Y. Then, that anything that would be a local change in language X is still a local change. But this sort of requires knowing ahead of time that you're going to want to make that kind of change.
Sadly https://people.csail.mit.edu/files/pubs/stopify-pldi18.pdf is 403. But possibly https://people.csail.mit.edu/rachit/files/pubs/stopify-pldi1... is the right link.
> This is pretty much the same as (2). The input and output languages have the syntax of JavaScript but the fact that compiling one feature requires a whole program transformation gives away the fact that these are not the same language
It is not really the same as (2), you can't cherry pick the example of Babel and generalise it to every transpiler ever. There are several transpilers which transpile from one high-level language to another high-level language such as kotlin to swift. i.e; targeting the same level of abstraction.
Wonder what this person would say about macro expansions in scheme, maybe that should also be considered a compiler as per their definition.
An assembler is a type of compiler that takes in an assembly language and outputs machine code.
A transpiler is a type of compiler that takes in a language commonly used by humans to directly write programs and outputs another language commonly used by humans to directly write programs. E.g. c2rust is a C to unsafe Rust compiler, and since both are human-used languages it's a transpiler. Assembly language isn't commonly written by humans though it used to be, so arguably compilers to assembly language are no longer transpilers even though they used to be.
The existence of a transpiler implies a cispiler, a compiler that takes in code in one language and outputs code in that same language. Autoformatters are cispilers.
Off the top, lets compare that to "serverless."
Poly-transpiler? It will also trigger more people.
These things live on a continuum. Still, I think the different worlds are useful. They put forward different concepts and ideas. It helps framing things.
When used, it has often been implied that a compiler that outputs to a human-readable programming language wouldn't be a "real compiler".
It's basically a flowchart showing all of the different things that we mean when we say compiler/interpreter/transpiler, and which bits they have in common.
Funny, but it has two paths for transpiler - the kind that parses and outputs source from an AST, and the asm.js kind, that actually just uses a high-level language as an assembly-ish target.
For example, Google Scholar search for "transpiler" yields just 3200 results, compared to ~1.4M for "compiler".
So you do know the difference.
A transpiler to me focuses on having to change or understand the code as little as possible - perhaps it can operate on the syntax level without having to understand scopes, variable types, the workings of the language. It does AST->AST transforms (or something even less sophisticated, like string manipulation).
In my mind, you could have a C++ to C transpiler (which removes C++ constructs and turns them into C ones, although C++ is impossible to compile without a rich understanding of the code), and you could have a C++ to C compiler, which would be a fully featured compiler, architected in the way I described in the start of the post, and these would be two entirely different pieces of software.
So I'd say the term is meaningful, even if not strictly well defined.
Is JIT also meaningless?
But ultimately if you don’t want to use a word, don’t use it. Not wanting to hear a word says more about the listener than the speaker
import functools as ft
def fact(n):
lst = range(1, n)
return ft.reduce(lambda acc, x: acc*x, lst)
Amusing that there's not a list comprehension in sight."BabelJS is arguably one of the first “transpilers” that was developed so that people could experiment with JavaScript’s new language features that did not yet have browser implementations"
Just my two cents. Haxe was created long time ago, and BabelJS is arguably not one of the first "transpilers" people can play with.
[1] https://en.wikipedia.org/wiki/Haxe
[2] https://haxe.org
So eloquently put, what starts off as just simple syntactic conversion usually snowballs into semantics very quickly.
"Compiler already covers that"? Yeah, and animal already covers cat, shall we drop the term cat too?
[1] https://github.com/FranklinChen/p2c
[2] https://en.wikipedia.org/wiki/Stalin_%28Scheme_implementatio...
So, where does BabelJS sit? Somewhere in between, depending on what language features you used in the input code. Obviously generators require heavy transformations, but other features don't.
Sure, a transpiler is a specialized form of compiler. However that doesn't mean it's not much clearer to describe a transpiler using the more specific name. As such recommending someone replace "compiler" with "transpiler" (when appropriate) does not mean using compiler is wrong. It simply means that, outside of some very niche-interest poetry, using transpiler is better!
Want the full context?
Jump to the original sources
Read the primary article or dive into the live Hacker News thread when you're ready.