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.
# 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.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.
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.
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.
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?