Clay – A language designed for generic programming
claylabs.com
claylabs.com
ATS: http://www.ats-lang.org/
BitC (seems to be dead): http://www.bitc-lang.org/index.html
Tart: https://code.google.com/p/tart/
Deca: https://code.google.com/p/decac/
Cyclone: http://cyclone.thelanguage.org/wiki/Why%20Cyclone/
Nimrod: http://nimrod-code.org/
Habit (Haskell adapted for systems programming): http://hasp.cs.pdx.edu/
Plus of course the obvious ones, Go, Rust, D. I don't keep track of these projects' usability, I just write them down as I come across them.Apart from this family the other I have been window-shopping on is the high performance/productivity family, consisting of the likes X10, Chapel and Fortress. Thanks to Oracle, Fortress is now abandonware.
Off late I have been quite disappointed by this trend in HN to be very hostile to things that I would consider to be the very distinguishing traits of a Hacker. Now it seems some people here compete to jump over the other to complain against things that encourage/facilitate or are meant for tweaking, learning, exploring and breaking: all things that I consider the very essence of hacking. Case in point, recent discussion on Gentoo.
The behavior reminds me of a bunch of desperate and wannabe Pink Floyd fans we had in college, who would jump to rally the crowd to disco to the opening strains of Another Brick in the Wall, much to our bewilderment but apparently to look cool.
There is always Java, if you are happy with it, stay happy with it.
Felix is on my big list of interesting languages, but I didn't really think of it in the same category as these. I'm sort of aiming for something better than C when I get around to writing an OS kernel, you know, "someday".
I think for your use case decac, clay, bitC and Cyclone would indeed be ideal. There is this Haskell like language with effects based typesystem that might be worth looking at, the name continues to escape me.
One can go very low level with Felix, after all you can write inline C, C++ and define C and C++ functions, but those are not type checked. ABI could also be an issue given that it compiles to C++.
All the best for fun with kernel writing :)
Disciple ? (DDC) http://disciple.ouroborus.net/
http://www.codeblog.ch/2011/06/statically-linked-linux-execu...
Myrrdin: http://eigenstate.org/myrddin.html
Pascal: http://www.freepascal.org/
Cyclone is pretty dead.
It's pretty incomplete, and definitely not ready for prime time yet.
I like to read about this stuff and compare design decisions between languages.
http://code.google.com/p/june-language/ (java+python)
http://code.google.com/p/j-rest/ (meta: api creator)
https://code.google.com/p/szl/ (google data project)
http://luvit.io/ (nodejs for lua)
http://sourceforge.net/projects/sisal/
http://zenlang.sourceforge.net/index.html (in dev)
http://ufo.wikispaces.com/ (in dev)
Ok, the last one is a joke, but worth sharing, haha really funnny how people spent their time http://code.google.com/p/penor-programming-language/ (a joke?)And in every language thread someone starts mentioning how good go is,.
- https://github.com/jckarter/Vinyl
- https://github.com/Blei/claytracks
I don't see anything here that would make me consider this over Go, though. Languages are rarely chosen based on their designs alone. Go is about as bleeding edge as I can get away with in my job.
A big problem is lack of good, built in UTF-8 support. But the no garbage collection thing is interesting as I didn't spot any explicit allocs or frees anywhere when I skimmed.
Go is about concurrency. Clay is about generics.
Go is garbage collected; Clay is not. This allows Clay to be more suitable in environments where GC non-determinism/performance is unacceptable.
A better comparison would be Rust and Clay. Rust seems to emphasize correctness in the type system, Clay on making existing C++ style generics less cumbersome to use (a frankly laudable intention). On the other hand, I think it would be easier to give Rust the good things in Clay than the other way around.
Languages always succeed based on support (documentation, community, tooling)--not features.
I brought Go up here because it stands the best chance of inheriting the role that C and C++ occupied for systems software, and which Python is also taking over. That's why it was created, so developers could have a statically-typed systems language that wasn't C or C++ or Python or Java, since all of those were unsuitable in various tasks for one reason or another.
I did not in fact read all 63 pages (!) of the language reference, but as for the predicated type declarations (found here[1], for the curious), I agree, they are very cool.
Let me clarify: I'm not saying the language does not have good parts to it. I'm not even saying that there's no room for a new systems language. I'm just saying for my use case, I can't justify using it and I'll stick with Go for now.
[1] https://github.com/jckarter/clay/blob/v0.1.0/doc/language-re...
record MyInt (value:Int);
// delegate any function called with a MyInt to be called on its Int value
[F] overload F(x:MyInt) = ..F(x.value);
where `..` must be used to extract multiple values in a single-value context. This could easily avoided using tuples.The only advantage of Matlab-style multiple values is that they allow a kind of return-value type overloading, i.e. some Matlab functions perform less work if you don't only consume 1 return value. But I believe that this could be easily solved with a first-class code pattern.
One language that prominently relies on tuples with unnamed fields, in the absence of a built-in record syntax, is Erlang. The downside to not having names is that to find a value you must know its position, which hides information in the implementation (refactoring the code in a way that changes the position, for example, might not result in a compile-time error), which is one reason that Haskell provides syntactic sugar for expressing tuple types using a record syntax.
One thing that Go does right is to sometimes allow you to address a record as a tuple:
var x SomeRecord = {1, "Bob"}
However, when reading, I believe (I haven't actually checked) you can't access a record variable as a tuple. key, value = {'a': 1}.iteritems().next()
I could also do: item = {'a': 1}.iteritems.next()
key, value = item
which shows that tuples are first-class.By "multi-value context" I mean treating expressions differently depending on their context; some contexts are then "multi-value". E.g. in go:
v, ok = a[x]
Here, if `x` is present in `a`, `v` is assigned the value at `x`, and `ok` is `true`; otherwise, `ok` is `false`, and `v` is assigned the zero value of its type.Note that I cannot do this:
pair = a[x]
v, ok = pair
as `pair = a[x]` has a different meaning in this context: it only returns the value at `x` (or the zero value), and gives no indication of whether `x` is present or not. So, the meaning of the expression `a[x]` changes depending on the context, which can be either "single-value" or "multi-value". "In Clay, all arguments are passed by reference."
Looks like a nest of bugs waiting to grow as new users try out the language.In C#, if I do
int foo(int x) { x += 1; return x; }
...
int x = 3;
foo(x);
then afterwards the value of x is still 3. In Clay, if I do foo(x : Int) { x += 1; return x; }
var x = 3;
foo(x);
then the value of x is now 4. I agree with the grandparent: this seems like a really terrible idea. (In fact, I was going to post a comment saying so until I saw that someone else had got there before me.)[EDITED to add: By the way, usually "dynamic languages" means "languages with dynamic typing", and Java and C# would be excellent examples of widely used languages that are not dynamic in that sense. The question of whether values are passed "by object reference" (my preferred way of describing what they do) is pretty much entirely separate from whether the language is dynamic. For instance: C++ (not dynamic, not p.b.o.r.), Java (not dynamic, p.b.o.r.), MATLAB (dynamic, not p.b.o.r), Python (dynamic, p.b.o.r). C# has the unusual feature that some kinds of mutable objects are passed that way while others -- structs -- are passed by value, with the object (in principle) being copied when the call happens.]
int foo(obBob o) { o.x += 1; return o; }
...
Car.x = 3;
foo(Car);
Then Car.x = 4 which has confused a lot of new programmers. More importantly it's a more consice standard for cube(x) to cube(x) than to say x=cube(x).It's over 3 years old so a lot of it is probably out of date, but still interesting to see the thought process behind the language design.
main() { println("Hello world!"); }