I'm glad that systems languages are getting a little more love these days. However, I'm a little saddened to see that no one seems to want to write a language that can also be used at the write-a-kernel level. Both Rust and GoLang have expressly made this a non-goal[1][2].
I think you could write a kernel in Rust (though you'd need to add unsafe pointers, direct calls, and possibly other stuff to the language), it's just not a goal of the project. There's no reason why I wouldn't accept patches to the language that would help in that effort as long as they didn't wildly conflict with the main goals of the project.
I consider ATS [1] a systems language and it can be used at the write-a-kernel level. It can be used without a garbage collector using linear types to ensure memory is deallocated.
One of the contributed examples is some kernel development [2].
Y'know, it's funny. For no good reason I've failed to give D any consideration. I guess I've had it in my head that it wasn't as small or speedy as C/C++, but I'm pretty sure that's unfounded prejudice talking. I think I'll give it a try. Thanks!
The Habit language, being developed at Portland State (by my colleagues -- I'm a grad student there) falls into the category you're looking for, though the implementation is still under development:
Maybe Clay (http://tachyon.in/clay/) would interest you then? It does not explicitly says that it can be used for kernel development, but from the feature set it seems like it could.
A function has an effect. It can be annotated as 'impure' or 'unsafe'. Any function that is not annotated in that way is considered pure.
Pure functions that return a boolean value can be used in the typestate system (ie. typestate calls must not have side effects). 'pure' functions cannot call 'impure' functions, etc.
I'm guessing that's what the quoted sentence refers too.
Well, inside a function, you can have as much imperative code as you like, with mutable local variables and what-not, the function overall is still pure as long as it does not cause side-effects.
Eg, functional code could looks something like this:
foo a b = if a < b then quux (map bar a) else b
while a pure imperative function could look something like this:
int foo (string a, int b) { // since a is passed by value, mutating it below will not modify the original
if (a < b) {
for (int idx=0; idx<a.length; ++idx) {
a[idx] = bar(a[idx]);
}
return quux(a);
} else {
return b;
}
}
Obviously this example is contrived and dumb, but both do the same thing and, besides the syntax difference, the first is written in a functional style, the second in an imperative style, but both are still pure (as long as bar and quux are also pure).
So you can mix functional and imperative without making functions impure.
Yes, but you don't have to mix them each and every time. It's just that you have the option to do so and aren't constrained to a single language designer's favourite style.
I love destructors and RAII. They're more elegant than "with" constructs and much safer (unless you have a fancy type system that warns you when you create a resource object outside a "with.") They're the only thing about C++ that I really miss in other languages.
One problem with the name Resource Acquisition Is Initialization
is that it is inaccurate: it's not always about resources, and
it is nothing to do with initialization -- what makes the idiom
tick is finalization.
In Rust, the semicolon is the expression sequencing operator (like in ML), not a statement terminator. "a;b" means "evaluate a, throw away the result, and return the result of evaluating b". So the semicolon is more than just boilerplate.
I guess we could do some sort of automatic semicolon insertion like JavaScript, but I'm not sure that the benefits outweigh the complexity.
/*
* Go language grammar.
*
* The Go semicolon rules are:
*
* 1. all statements and declarations are terminated by semicolons.
* 2. semicolons can be omitted before a closing ) or }.
* 3. semicolons are inserted by the lexer before a newline
* following a specific list of tokens.
*
* Rules #1 and #2 are accomplished by writing the lists as
* semicolon-separated lists with an optional trailing semicolon.
* Rule #3 is implemented in yylex.
*/
But obviously this is very language-specific and given the case discussed above likely not to work in quite the same way.
Hey - I know this is trivial, but I just find it takes away from the clarity of the code when you must terminate lines with a semicolon.
It's obviously very useful to use ';' in the scenario you mention, I think a good comparison is F# which doesn't force semicolons but does permit usage like that. I guess, e.g.:-
foo
bar
baz
implies foo |> ignore; bar |> ignore; baz
Oh, and just to make it very clear, I am talking about something really rather petty, I do not mean to do down rust in any serious way - I'm a wannabe-language designer myself, so major respect to you guys :)
I'm a longtime C++ (semicolons everywhere) and Python (no semicolons) programmer who has also used and very much enjoyed Common Lisp and Scheme (no semicolons, but parens everywhere.) Right now I'm learning Scala (semicolons usually optional but occasionally required.) After my experience with all those languages, honestly, I don't care at all whether Rust uses semicolons or not. I like Python's meaningful whitespace, but the lack of semicolons is only a side effect of that, not the primary benefit. Optional semicolons in Scala actually seem like a bit of a wart since you get used to leaving them out but on rare occasions have to include one to make the code mean what you want. Putting them in all the time provides a nice visual cue and doesn't cost anything. Like the parens in Lisp, they disappear as long as they're where you expect them.
I hate automatic semicolon insertion. They complicate the language. Here's the rule for a language that uses semicolons to terminate statements:
1. Semicolons terminate statements.
Look at the rules for Go semicolon usage[1] or Javascript semicolon usage[2] or Python newline usage[3]. They're not simple. Entire essays can be and have been written describing the complexity introduced by saving programmers that single keystroke.
Maybe I'm crazy, but I want my tools to be simple. I would much rather type a thousand extra semicolons than spend extra hours internalizing the statement termination rules of the languages I use.
[1] https://github.com/graydon/rust/wiki/Project-FAQ
[2] http://groups.google.com/group/golang-dev/browse_thread/thre...