Live data from Hacker News

ClojureC, a compiler for Clojure that targets C as a backend

github.com

21–30 of 89 posts

Re: ClojureC, a compiler for Clojure that targets C as a backend

#21
post #17

Earlier quoted context omitted.

"more ... error prone" Can you prove that? If not, it's just a baseless opinion.

What's with this childish "can you prove this, can you prove that" thing? Are you 12 year old? Not everything can (or should) be proved of the drop of a hat in a discussion list -- that doesn't make everything without a formal proof "baseless" opinion. If you cannot see the self-evidentness (sic) of a STRUCTURED API to produce an AST makes it easier to avoid mistakes compared to spitting out text to compile as a C pr…

We work in a technical field. We call ourselves engineers. The academic version is computer SCIENCE. Unsupportable opinions and opinions presented as facts are inexcusable.

Re: ClojureC, a compiler for Clojure that targets C as a backend

#22
post #17

Earlier quoted context omitted.

"more ... error prone" Can you prove that? If not, it's just a baseless opinion.

What's with this childish "can you prove this, can you prove that" thing? Are you 12 year old? Not everything can (or should) be proved of the drop of a hat in a discussion list -- that doesn't make everything without a formal proof "baseless" opinion. If you cannot see the self-evidentness (sic) of a STRUCTURED API to produce an AST makes it easier to avoid mistakes compared to spitting out text to compile as a C pr…

  Not everything can (or should) be proved of the drop 
  of a hat in a discussion list
If you say something that doesn't make sense, you're saying that one shouldn't have to back that up?

  It's like asking me to prove why using an XML processor 
  to crete and save a DOM tree would produce more error 
  free results than manually compiling tags as strings.
It is in fact the equivalent of asking you to prove that an XML parser after serializing a DOM tree and then parsing that same document produces a non-equivalent DOM tree to the original.

I think the reason pat_punnu is balking at what you have said is because of this: You can think of C as a serialized form of an AST. In order for parsing to produce a non-equivalent AST to the one used to serialize it, the C grammar must be non-deterministic. The C grammar is not non-deterministic, therefore what you said does not make sense and pat_punnu (somewhat rudely) asked you to back up what you were saying.

Asking people to back up what they have claimed is part of intelligent discourse. This happens often on HN and is one of the reasons I like this community because when the person who makes a non-intuitive or seemingly wrong remark turns out to be correct, I learn something.

UPDATE: I should point out that I'm responding specifically to this sub-thread of the tree and not arguing about whether or not this should target the LLVM IR. I think that would be nice.

Re: ClojureC, a compiler for Clojure that targets C as a backend

#24

"Before you can run anything make sure you have GLib 2 and the Boehm-Demers-Weiser garbage collector installed." Wow, that's a pretty skimpy list of dependencies. But.. "Make sure you're using Leiningen 2." ..argh, installing that on ubuntu that requires 110 packages. All that just for a build system?

> ..argh, installing that on ubuntu that requires 110 packages. All that just for a build system?

Don't install lein using the OS packaging system (apt, rpm, yum, etc.).

Instead, just grab the `lein` script (linked to from http://leiningen.org/ ), put it into your ~/bin, set it executable, and you're all set.

Re: ClojureC, a compiler for Clojure that targets C as a backend

#25
post #24

"Before you can run anything make sure you have GLib 2 and the Boehm-Demers-Weiser garbage collector installed." Wow, that's a pretty skimpy list of dependencies. But.. "Make sure you're using Leiningen 2." ..argh, installing that on ubuntu that requires 110 packages. All that just for a build system?

> ..argh, installing that on ubuntu that requires 110 packages. All that just for a build system? Don't install lein using the OS packaging system (apt, rpm, yum, etc.). Instead, just grab the `lein` script (linked to from http://leiningen.org/ ), put it into your ~/bin, set it executable, and you're all set.

This. It's a lot easier to do it that way.

Re: ClojureC, a compiler for Clojure that targets C as a backend

#26
This is neat.

What worries me about this and similar efforts (like https://github.com/takeoutweight/clojure-scheme) is that clojure's standard library design assumes that the underlying runtime will be do some kind of polymorphic method inlining.

For example: the sequence library is all defined in terms of ISeq, which basically requires a "first" and "rest" to be defined for the data structure in question. These are polymorphic: there are different implementations of these for different data structures (list, vector, map, etc). So a dispatch step is required to choose the right one. In clojure-jvm, this is implemented using a java interface; this means the jvm will inline calls to said methods when they're being used in a tight loop. And if you use the standard library, calls to 'first' and 'rest' are going to be inside nearly all of your inner loops.

Compare this to a normal lisp or scheme: 'first' and 'rest' (or 'car' and 'cdr', whatever) are monomorphic. They only work on the linked-list data structure. So compiling these directly down to C functions makes perfect sense and incurs no performance penalty.

So in summary: clojure assumes theres a really smart JIT which is helping things along. This means it's not as suitable for alternate compilation targets as you might want it to be.

I wonder if there's something clever you could do here. Vtables could be reordered based on expected usage, certainly. Clojure can already do some measure of type inference, so this could be used for AOT inlining when it's available. Even if it's not, perhaps several versions of a call could be speculatively generated based on what the compiler does know already. The normal polymorphic inline caching technique could perhaps be abused to apply here. But it's hard to see how any of this can work in absence of a profile or heavy hinting.

(not a compiler writer, just interested in the problem)

Re: ClojureC, a compiler for Clojure that targets C as a backend

#27
post #5

Why C but not llvm? Structured code generation is always better than string-based one.

People have made this argument for ClojureScript as well. In the case of ClojureScript the benefits are considerably less clear as we rely on the ability of Google Closure to do fairly amazing optimizations on the generated JavaScript source.

That said I'd love to see a serious Clojure-in-Clojure targeting LLVM.

Re: ClojureC, a compiler for Clojure that targets C as a backend

#28
post #15

Earlier quoted context omitted.

What is his definition of better? It sounds like he thinks it's entirely objective, so he should be able to express it clearly and logically. Does he think that it's technically more powerful? Again he should be able to prove that if that's the case. Otherwise he's just giving a shitty opinion, and should say that. I think the claim is nonsense because with inline assembler there is nothing that you cannot express in…

> Does he think that it's technically more powerful? Again he should be able to prove that if that's the case. Otherwise he's just giving a shitty opinion, and should say that. It's not like it's some controversial opinion what he said -- it's both self evident and common place. It's you who offers the more controversial opinion (and in a rude way, to top). > I think the claim is nonsense because with inline assemble…

> It's not like it's some controversial opinion what he said -- it's both self evident and common place.

As someone who has written more than one compiler, I don't see how it is self-evident at all. It's also not at all that common-place compared to generating C or asm output textually.

> It's about having more structure and less of an ad-hoc pipeline, which helps with better tooling, error prevention, etc.

Those provide some benefits, sure. At the cost of massive amounts of complexity in the case of LLVM.

> The only benefit to using C for something like this is portability, which is something else altogether.

Now it is you who are wrong. Other people have already pointed out, for example, that C provides an easy-to-read intermediate format, and is simple to generate, as other benefits. Not having to deal with a massive C++ codebase is another.

You may disagree that these other benefits are worth it, but for me at least they are (just taking a break from a compiler that generates textual asm because I find even that preferable to dealing with LLVM).

Re: ClojureC, a compiler for Clojure that targets C as a backend

#29
post #10

Earlier quoted context omitted.

Nonsense?! Outputting text to be interpreted as code is far more low level and error prone than targeting an AST via an API like LLVMs. And you loose a lot of high quality tooling that you could take advantage of.

"more ... error prone" Can you prove that? If not, it's just a baseless opinion.

More moving parts being more error prone is not generally a controversial opinion.

Re: ClojureC, a compiler for Clojure that targets C as a backend

#30
post #26

This is neat. What worries me about this and similar efforts (like https://github.com/takeoutweight/clojure-scheme ) is that clojure's standard library design assumes that the underlying runtime will be do some kind of polymorphic method inlining. For example: the sequence library is all defined in terms of ISeq, which basically requires a "first" and "rest" to be defined for the data structure in question. These are…

You can do polymorphic method caching/inlining with a hybrid ahead of time / JIT compiler targeting C reasonably easily. The code fragments required for caching at least will be small, and code to generate them at runtime is not a big deal. I'm playing with a Ruby compiler, and Ruby badly needs these type of optimizations to get fast, so I've spent a fair amount of time looking at it.

For a fair amount of cases you can do static analysis to get good guesses at likely types, even for cases where you can't be sure. E.g. speculatively even looking near call sites by method name to see if you can guess the type of objects that will get passed in looks to get you a reasonable chance at guessing at the top contenders to let you speculatively generate inlined versions without creating too much junk. But to get the most performance out of this you're likely to need to be prepared to do some very basic JIT.

Post reply on HN