36

Are there any languages that target the LLVM that:

  • Are statically typed
  • Use type inference
  • Are functional (i.e. lambda expressions, closures, list primitives, list comprehensions, etc.)
  • Have first class object-oriented features (inheritance, polymorphism, mixins, etc.)
  • Have a sophisticated type system (generics, covariance and contravariance, etc.)

Scala is all of these, but only targets the JVM. F# (and to some extent C#) is most if not all of these, but only targets .NET. What similar language targets the LLVM?

Matthew
  • 2,151
  • 2
  • 17
  • 13
  • You're asking for a lot from such a small platform. I'd be really surprised if you found something that matches all your criteria. Why do you need to use LLVM specifically? – Sasha Chedygov Jun 10 '10 at 06:39
  • Yes, you are probably right. I don't have a specific use case at this point, I'm just curious about the future of programming languages. It strikes me that LLVM has a very bright future, and given that I'm also very impressed by the new functional language Scala that targets .NET and the JVM, I'm hoping that somebody out there is working on something similar for the LLVM. – Matthew Jun 10 '10 at 06:58
  • Yes, it's definitely an interesting project. The problem is, when you have higher-level platforms like Java and .NET that are much more powerful, no one really wants to deal with something as low-level as LLVM. – Sasha Chedygov Jun 10 '10 at 07:02
  • 3
    @musicfreak: There are plenty of languages offering all or most of the above features, which compile down to assembly. – sepp2k Jun 10 '10 at 07:05
  • 5
    Languages don't target any particular processor architecture be it a physical CPU or a virtual machine written in software. *Implementations* of languages target particular architectures. For example Sun's implementation of Java targets Sun's JVM. There's nothing in principle to stop somebody porting Java natively to x86 or ARM or even Microsoft's CLR. – JeremyP Jun 10 '10 at 13:54
  • 1
    @JeremyP: GNU GCJ compiles Java to native code, IKVM.NET compiles Java to CIL. q.e.d. :-) – Jörg W Mittag Jun 10 '10 at 14:46
  • @musicfreak: the low-level-ness of LLVM is one of the primary benefits of such a project. Compared to .NET or Java, it is very straightforward to bring up LLVM support on new (or old!) architectures. – Stephen Canon Jun 15 '10 at 16:23
  • 1
    First class objects _AND_ first class functions are a rare bread to be found together on any platform. – Eli Oct 04 '10 at 17:36
  • @JeremyP So you're saying that x86 assembly language doesn't target any particular architecture? ;-) – J D Feb 26 '12 at 19:33
  • @Jon Harrop: OK *high level* languages don't target any particular architecture :) – JeremyP Feb 27 '12 at 10:24

3 Answers3

43

There's a Haskell (GHC) backend targeting the LLVM.

You could also try using F# through Mono-LLVM.

Also, the VMKit project is implementing both the JVM and the .NET CLI on top of LLVM; it's still in its early stages but once it matures you could use it with F#, or any JVM-targeting functional languages (Scala, Clojure, etc.)

tzaman
  • 46,925
  • 11
  • 90
  • 115
14

I'm not sure how far these have progressed, but they may be worth adding to the list:

Scala for LLVM - https://github.com/greedy/scala/
Timber for LLVM - https://bitbucket.org/capitrane/timber-llvm
Mono for LLVM - http://www.mono-project.com/Mono_LLVM

T.R.
  • 7,442
  • 6
  • 30
  • 34
-3

Yes... clang. C++ has everything on your list except for list comprehensions. It is also the flagship LLVM language.

"Are statically typed"

Yup

"Use type inference"

// local type inference
auto var = 10;

// type inference on parameters to generic functions
template <typename T>
void my_function(T arg) {
    ...
}
my_function(1) // infers that T = int

// correctly handles more complicated cases where type is partially specified.
template <typename T>
void my_function(std::vector<T> arg) {
    ...
}
std::vector<int> my_vec = {1, 2, 3, 4};
my_function(my_vec) // infers that T = int

"Are functional (i.e. lambda expressions, closures, list primitives, list comprehensions, etc.)"

Lambdas in c++ look like [capture_spec](arglist...) { body }. You can either capture closed over variables by reference (similar to lisp) like so: [&]. Alternatively you can capture by value like so: [=].

int local = 10;
auto my_closure = [&]() { return local;};
my_closure(); // returns 10.

In C++ map, zip, and reduce are called std::transform and std::accumulate.

std::vector<int> vec = {1, 2, 3, 4};
int sum = std::accumulate(vec.begin(), vec.end(), [](int x, int y) { return x + y; });

You can also rig up list comprehensions using a macro and and a wrapper around std::transform if you really want...

"Have first class object-oriented features (inheritance, polymorphism, mixins, etc.)"

Of course. C++ allows virtual dispatch + multiple inheritance + implementation inheritance. Note: mixins are just implementation inheritance. You only need a special "mixin" mechanism if your language prohibits multiple inheritance.

"Have a sophisticated type system (generics, covariance and contravariance, etc.)"

C++ templates are the most powerful generics system in any language as far as I know.

catphive
  • 3,511
  • 3
  • 31
  • 29
  • 5
    I wouldn't call C++ templates _sophisticated_ or even a _type system_, but they do have expressive power on par with some sophisticated type systems :) – opqdonut Dec 03 '11 at 10:32
  • 3
    First, that's not type inference as it's commonly understood in the context of typed functional languages. Second, IIUC multiple inheritance does not allow multiple overrides of a virtual method without another disambiguating override at the bottom of the diamond, so multiple inheritance doesn't cover all the use cases for mixins. – Ryan Culpepper Dec 03 '11 at 20:58
  • @RyanCulpepper C++ has both kinds of type inference (local inference and inference on parameters to generic functions). This is the same as say, ML. In fact, I believe it uses the same underlying type inference algorithms... I'm not sure I understand the part of your comment about mixins. – catphive Dec 08 '11 at 01:17
  • 2
    @catphive: Here are some examples of the kinds of type inference that I believe C++ does not support (but I could be wrong): Can you write `auto f(auto x) { return x+1;}` and have it infer the signature `int f(int)` (ignoring the overloadability of `+`)? Can you write `[](auto x) { return x+5; }` and have it infer that `x` must have type `int`? Can you write something like `auto f(auto x) { vector v; v.push_back(x); return v; }` and have it infer the polymorphic (template) signature `template vector f(T)`? That's what type inference means in languages like ML and Haskell. – Ryan Culpepper Dec 08 '11 at 04:13
  • @Ryan Culpepper: This is a more complicated question than I can answer here. Broadly speaking: Yes, you can do what you are trying to do, but the syntax is different than what you wrote and there are some caveats. Caveats: 1. Templates are lazily instantiated, so they don't have "signatures" in the way you are thinking. Only instantiations of template functions have signatures. 2. Lambdas cannot be generic (template functions) in C++2011. They can do type inference on the return type though. Probably will be fixed whenever they release the next standard... don't hold your breath though. – catphive Dec 14 '11 at 22:04
  • Also, because of overloading, it does not make sense to infer the parameter type from the way it is used in the function body. It's the other way around, you infer which overloads to call from the type passed to the function. This is actually much more powerful than the reverse approach since it means generic functions can accept any compatible type... For instance: – catphive Dec 14 '11 at 22:09
  • template T add(T x, T y) { return x + y; } can accept integers, doubles, or even strings. Any kind of object that + is overloaded for. – catphive Dec 14 '11 at 22:11
  • 19
    I remember the days when type inference was type inference. Then along came Scala with its inability to infer the type of even the simplest recursive functions like factorial but that didn't stop the Scala community from claiming that it had type inference. Then the C# community followed suite. Now you're saying that C++ cannot even infer the type of the generic identity lambda function but you still think it has type inference. I mean, seriously, WTF? – J D Feb 26 '12 at 19:50