11 ms·
Rhine – A Lisp on LLVM
- charlieflowers 12y agoI think the holy grail may be the combination of working in a very expressive high level language, but knowing and seeing exactly what that generates at the low level. (And in those few cases where it matters, being able to control/influence/change what it generates at the low level). So this sounds pretty interesting.
- shortsightedsid 12y agoFWIW, SBCL does exactly that. You can defun a function and disassemble it right down to assembly. What this project does is slightly different which is to use LLVM to achieve the same thing.
- sqrt17 12y agoTo use LLVM to achieve the same thing would be to find a way to bootstrap SBCL through LLVM, which would, again, be very cool.
- _delirium 12y agoThere are occasional discussions on sbcl-devel about it, but I'm not aware of anyone committing serious resources to it (it's not really a weekend-project, or even single-GSoC-student, amount of work). There is also some skepticism about whether it's worth doing at all, because of worries that it will be difficult to get good GC performance out of LLVM: http://marc.info/?l=sbcl-devel&m=136219729420475&w=2 http://marc.info/?l=sbcl-devel&m=136219729420475&w=2 (Reference [1] in that email points to: https://github.com/elliottslaughter/rust-gc-notes https://github.com/elliottslaughter/rust-gc-notes, which documents difficulties trying to build a precise GC for Rust on top of LLVM.)
- hga 12y agoSimply doing a correct precise GC with LLVM is still a work in progress: http://www.philipreames.com/Blog/ http://www.philipreames.com/Blog/
- _delirium 12y agoTaking GC seriously in the design of a low-level compiler-target language was one of the aspects that I found very interesting about the C-- project of Simon Peyton Jones & Norman Ramsey. But it unfortunately didn't get anywhere near the same backing/momentum as LLVM, and now seems defunct.
- hga 12y agoIndeed, and I found the whole concept to be excellent. Unfortunately, as far as I can tell, it's defunct outside of its use in the GHC. E.g. the Quick C-- compiler was recently archived here https://github.com/nrnrnr/qc-- https://github.com/nrnrnr/qc--
- charlieflowers 12y agoYeah I realize that, but good point. LLVM is very interesting to me, but you're right that it's not as utterly low level as native assembly. It is the most interesting assembly ("assembly-like"?) language to me at this time. I didn't know SBCL did that. Cool.
- enupten 12y agoAll CL's have a #'disassemble, although the output of it is left undefined.
- dedward 12y agoFYI - that disassemble feature is part of the CL spec - it's not unique to SBCL. http://www.lispworks.com/documentation/HyperSpec/Body/f_disass.htm#disassemble http://www.lispworks.com/documentation/HyperSpec/Body/f_disa...
- dedward 12y agoFYI - that disassemble feature is part of the CL spec - it's not unique to SBCL. http://www.lispworks.com/documentation/HyperSpec/Body/f_disass.htm#disassemble http://www.lispworks.com/documentation/HyperSpec/Body/f_disa...
- ihnorton 12y agoJulia has some nice functionality for introspecting both lowered and type-inferred ASTs, the corresponding LLVM IR, and finally the resulting assembly code. (several Lisp systems have this kind of thing too)
- StefanKarpinski 12y agoSome details here: http://blog.leahhanson.us/julia-introspects.html http://blog.leahhanson.us/julia-introspects.html.
- sgrove 12y agoI believe Haskell compilers are pretty amenable to stuff like this - watching "Data Parallel Haskell", it was interesting to see how they actually map out contiguous memory, etc. https://www.youtube.com/watch?v=NWSZ4c9yqW8 https://www.youtube.com/watch?v=NWSZ4c9yqW8 Sadly, it doesn't seem to be as tightly integrated as what you'd see in SBCL from a developers PoV, but I'm certainly intrigued by their ability to achieve some very specific implementation while separating it from the expression of the algorithms.
- jrapdx3 12y agoYou can add Scheme to the list of languages that do this. CHICKEN in particular works by compiling highly expressive Scheme to C, which can be inspected, modified, etc. Also the CHICKEN compiler has a few dozen switches to tweak output, but it's fully open-source (BSD) if that's interesting. If C is not "low level" enough what are you looking for? (It occurs to me, the C code can be compiled with clang, which provides further opportunities for low-level output.)
- splix 12y agoalso https://github.com/eudoxia0/corvus https://github.com/eudoxia0/corvus
- pjmlp 12y agoNice, but the author could join efforts with one of the few attempts to have a native Clojure compiler instead. Another remark, is that it would have been nicer to have the language being made in itself instead of OCaml. Other than that, very nice work.
- zem 12y agoocaml is really good for writing compilers in, so why not use it?
- pjmlp 12y agoSure it is, but I think writing bootstrapable compilers is a better approach.
- zem 12y agoI have never understood this (admittedly common) mindset. if writing a compiler does not play to your language's core strengths, what have you gained by insisting on bootstrapping it? you might argue that writing a compiler provides a good stress test of the language and stdlib, but so would identifying a large project that does play to its strengths, and developing it in parallel with the language. and contrariwise, bootstrapping a compiler might even be a net negative, not just because you have passed up on the chance to use a language that is better suited to the task, but because you have complicated your build process, created potential morasses when you have bugs with both your language design and your compiler implementation and you can't fix them separately, and are implicitly prioritising those features of your design and implementation that are useful for writing compilers, even though that might not be a very large use case for it at all. in the days where people were building up from assembly, bootstrapping compilers made a lot of sense. but now that there are existing, well established languages that have proven their value in the specialised problem domain, it makes no sense to ignore them and insist on bootstrapping for its own sake.
- pjmlp 12y agoAny Turing complete language can be used to write compilers. For me bootstraping is the best way of testing if the language design is sound and to become independent of other tooling. As you happen to mention. Many language designers that don't follow this process, happen to never fully experiment with their own language, as they spend most of their time in the compiler. As for tooling, the overlying of many designers in C and similar toolchains has created the wrong belief that only the said languages can be used to write compilers. To the point of the famous statement in the language design community "My compiler compiles yours". For me, the only place where bootstraping is to be avoided are DSLs.
- sarnowski 12y agoSomeone mentioned the JVM interop of Clojure is it's main selling point. While its definitly awesome to have that great integration (I'm a heavy interop user), for me, the main strength is having persistent data structures at its base for everything. I myself played with the thoughts of creating a native runtime based on Clojure's syntax and data structures. I cant see that this project uses persistent data structures. Am I wrong? please enlighten me.
- artagnon 12y agoCurrently, vectors are the only real data structures; they're naively persistent: operations like rest and cons create a fresh copy (I haven't implemented COW yet). I'm not quite sure how to implement it for `setq` though (a feature not present in Clojure, but something that's necessary for building an editor like Emacs): when a variable is set to a new value, where is the reference to the old variable, for gc and access?
- sarnowski 12y ago>> ... `setq` though (a feature not present in Clojure... I am not familiar with elisp but from first google result it reads that the equivalent is alter! / swap!.
- artagnon 12y agoOnly special ref objects are mutable in Clojure (via STM). I was talking of `setq` in the context of mutating normal variables. It's perhaps a bad idea, and I have to study how LT manages its plugin system without mutation.
- bjeanes 12y agoYou don't have to mutate them. You can create a new persistent variant and just mutate the ref to point to the new one. Users of that "variable" store the ref instead of the value (well, actually, they get the choice of which to do). If users have held on to references to the old values, the GC doesn't collect them. If they haven't, the GC can collect them just like any other circumstance involving persistent data structures.
- karavelov 12y agoWhat is the reason for using product of all primitive types for boxing instead of tagged union?
- artagnon 12y agoBecause one type may use more than one field. Vectors and strings use the nr field additionally, and functions use the vector/fenv field additionally. Instead of creating a hierarchy, I figured a flat structure would be easier to understand.
- thinkpad20 12y agoI was going to ask about this as well. It seems like there's a lot of wasted space in how things are represented. The first field already tells you what type of object you're dealing with. Since you're using 64-bit integers, you could represent pointers, bools, ints and floats all in the same memory space. I guess there might be some types that use more than one field, but certainly a bool is not going to. There's also the issue of alignment with the usage of 1-bit and 1-byte types...
- dschiptsov 12y agoLisp? So, it runs Maxima?