Would it be possible to modularize the crystal compiler (i.e. make shards out of the compiler internals which the crystal compiler itself would require as a shard)
The reason behind this is I have a couple of projects in mind, one is a different compiler backend for crystal (which means I want to reuse the crystal parser-compiler) and the other is the ability to include the crystal-compiler itself in crystal applications (i.e. so you can use crystal as a configuration language)
You can simply require the compiler, or parts of the compiler, from any crystal install: the compiler sourcecode is part of the stdlib. Simply require "compiler/crystal/<whatever>"
and code away.
Understood, however you I would need to add entire crystal repo as a git module and manually require it, as well as managing the dependency of this git module seperately
In other words, its not ideal (but its doable)
Why would you need to add the crystal repo as a git module? I just said it was part of the stdlib and compiler sourcecode can be required anywhere with even less work than using a shard.
@RX14 Would be posible to use a different backend for Crystal?
I mean, an alternative to LLVM, maybe a JS backend like Nim or Kotlin.
Currently, JavaScript world is very important.
Related: https://github.com/crystal-lang/crystal/pull/3634 (Web Assembly would be useful but still will use LLVM)
JS backend would require more work than a WebAssembly backend...you still have to implement another stdlib, only now you're playing by the JS rules and have to write another code generator. Things like the struct vs class distinction would be irrelevant, and I'm not even sure how the Int32 vs Int64 deal would work.
So, WebAssembly is the way :sweat_smile:
Currently, JavaScript world is very important.
One day Crystal will obviously become more important than JavaScript. 馃槂
Actually the idea is to make a JS backend, and surprisingly a JS backend is easier than a WASM backend (this is the experience that the Scala guys had with Scala.js, im actually coming from Scala and exploring other languages)
WASM has a very unique way of handling memory management, furthermore it doesn't have any interaction with the DOM so its incredibly limited for now.
Why would you need to add the crystal repo as a git module? I just said it was part of the stdlib and compiler sourcecode can be required anywhere with even less work than using a shard.
The compiler itself is part of the stdlib?
The compiler itself is part of the stdlib?
@mdedetrich Yes, It's
Actually the idea is to make a JS backend, and surprisingly a JS backend is easier than a WASM backend
Crystal uses LLVM, which would mostly take care of the actual codegen.
surprisingly a JS backend is easier than a WASM backend (this is the experience that the Scala guys had with Scala.js, im actually coming from Scala and exploring other languages)
Is that coming from something that emits LLVM IR already or not? Crystal's entire codegen phase is already emitting LLVM IR, surely using LLVM's WASM output will be easier than outputting JS. If scala had to port to LLVM and make it work with WASM that sounds like an entirely different proposition to me. I don't know anything about scala's position though so that's all a guess.
Is that coming from something that emits LLVM IR already or not?
Scala already has scala-native, which has an LLVM backend
Crystal's entire codegen phase is already emitting LLVM IR, surely using LLVM's WASM output will be easier than outputting JS. If scala had to port to LLVM and make it work with WASM that sounds like an entirely different proposition to me. I don't know anything about scala's position though so that's all a guess.
Afaik, although Scala.js requires a different backend, its not that complicated because
Of course, the main point is that the future of WASM (or when it will get there) is unclear at this point. In any case this is just something that I personally want to look into ;)
The idea, if I understand correctly, is to create a JavaScript transpiler, bypassing LLVM completely. That is take the semantically analyzed crystal AST, and generate JavaScript instead of generating LLVM IR to eventually generate WASM (or anything else).
I wouldn't be surprised for such a solution to be simpler to handle than WASM; granted that you'll may not have access to low level features (pointers) or the crystal stdlib, but you gain direct access to the whole JavaScript land 鈥攚hich seems impossible currently in WASM.
With a crystal compatible runtime, and a previously agreed subset of (in)compatibility (some things possible in crystal aren't possible in the transpiler) you could end up with something similar to Opal (a Ruby engine that transpiles to JavaScript).
That's still hard work, though. But the most interesting part of the crystal compiler (lexer, parser, semantic analysis) can be reused, yes.
The idea, if I understand correctly, is to create a JavaScript transpiler, bypassing LLVM completely. That is take the semantically analyzed crystal AST, and generate JavaScript instead of generating LLVM IR to eventually generate WASM (or anything else).
I wouldn't be surprised for such a solution to be simpler to handle than WASM; granted that you'll may not have access to low level features (pointers) or the crystal stdlib, but you gain direct access to the whole JavaScript land 鈥攚hich seems impossible currently in WASM.
Yup exactly
With a crystal compatible runtime, and a previously agreed subset of (in)compatibility (some things possible in crystal aren't possible in the transpiler) you could end up with something similar to Opal (a Ruby engine that transpiles to JavaScript).
Scala.js didn't have this problem, they pretty much support everything apart from Char
and certain exceptions (for interest you can see them here https://www.scala-js.org/doc/semantics.html)
Surely the better idea would to use the already-mature emscripten to port the stdlib. Then you wouldn't have to fight both at the same time. The counter-argument is that translating crystal to more semantically correct JS will be easier to debug and easier to minify. Also having 2 possible routes to generating JS will make the stdlib port more general.
Also can we not use gcc to refer to the google closure compiler, overloading acronyms is terrible.
Surely the better idea would to use the already-mature emscripten to port the stdlib. Then you wouldn't have to fight both at the same time. The counter-argument is that translating crystal to more semantically correct JS will be easier to debug and easier to minify. Also having 2 possible routes to generating JS will make the stdlib port more general.
Actually there are more compelling arguments to go for a JS backend
Since #3634 the opinions in this issue are nice to read.
@mdedetrich A React wrapper is awesome, Nim also has it https://github.com/andreaferretti/react.nim
Would be awesome to see Crystal.js
compiling a React project written in Crystal :smile:
JavaScript is like assembler for browsers right now :sweat_smile:
@mdedetrich emscripten != WASM. They both compile to JS and as such can make arbitrary JS calls. GC is an issue though, and it's probably a big enough issue to create a custom codegen phase.
Creating an entirely seperate stdlib may be an easy way to start a compiler port but there's no point in merging support unless it supports at least a core set of the stdlib.
Regardless, this issue has become off-topic, would it be better to discuss a JS backend in a dedicated issue?
@RX14 Maybe, JS backend issue already exist, see: #829 (Can be reopened?) and #535.
@faustinoaq #829 is about wasm, #535 is about asm.js. Neither of those are applicable to writing a backend without LLVM involved.
Creating an entirely seperate stdlib may be an easy way to start a compiler port but there's no point in merging support unless it supports at least a core set of the stdlib.
Actually the idea is to make a seperate compiler for the .js backend rather than to merge it into the main crystal-lang compiler as there are too many differences to consider
Regardless, this issue has become off-topic, would it be better to discuss a JS backend in a dedicated issue?
Agreed, should I close the issue?
@mdedetrich if you make a new issue, sure close this one. The compiler is already reasonably modular and usable from other code.
I don't think creating a seperate project is a good idea. We should aim to use the same compiler and same stdlib for every project. Creating a seperate project for testing is fine but you should aim for it to be mergeable. That means upstreaming some patches in the parser and semantic passes if it helps you.
I don't think creating a seperate project is a good idea
Ahhh, I had a logo :sweat_smile: (just kidding)
@RX14 You are right, duplicate eforces are bad, maybe we can compile to javascript using a flag --js
like Nim does. However, languages like Kotlin and Scala have a separate project to achieve a JS backed.
Some related projects I found on http://crystalshards.xyz/:
@mdedetrich are you going to open a issue related to JS backend? :sweat_smile:
Crow looks like a good start. If it could be brought up to latest crystal and working on nearly all crystal syntax, it would be fantastic. Working out how to take advantage of the huge repository of existing compiler specs to test the new codegen is a must. After that, a stdlib port could be attempted.
After it works, we could start thinking about whether we want to merge this and if so how. Having 2 entirely separate backbends to the crystal compiler would be great for keeping clean code, as it helps ensure separation of concerns between parts of the compiler.
I think this issue went a bit off-topic :-)
Closing.
Most helpful comment
One day Crystal will obviously become more important than JavaScript. 馃槂