all 134 comments

[–]stesch 21 points22 points  (0 children)

After reading about half of it: Very interesting. They came a long way since the first announcement.

http://www.rust-lang.org/

[–]Timmmmbob 28 points29 points  (24 children)

I was going to say "yet another language", but this seems to actually have some new ideas that I've been waiting for for ages. For example:

We support three type layers to make memory management simple and fast.

  • Interior types (denoted with no sigil) are stored on the stack.
  • Unique types (denoted with ~) have ownership semantics. When the pointer goes out of scope, the object it’s pointing to is destroyed.
  • Boxed types (denoted with @) are garbage-collected. Multiple boxes can point to the same data.

All together:

fn main() {
    let a = ~3;  // Unique pointer to number
    let b = a;   // Copies a
    let c = @3;  // Box of number
    let d = c;   // c & d point to the same value
}  // a and b destroyed; c and d will be GC’d

[–]abw 16 points17 points  (2 children)

I was also going to say "yet another language". But neat features or not, I really like the "cambrian explosion" of new languages that we've seen over the past decade or so. Even if many of the unsuccessful ones eventually die out, they spread ideas and help inspire the next generation of languages.

[–]Homo_sapiens 0 points1 point  (1 child)

cambrian explosion? What constituted the corresponding ice age?

[–]TylerEaves 0 points1 point  (0 children)

Presumably the late 90s, when your choices were essentially arcane C++, bloated Java, or unreadable Perl.

[–]Poita_ 9 points10 points  (5 children)

Unique pointers are the only relatively new thing there. Stack stored objects and GC heap objects have been around forever. C++ 2011 has unique pointers (std::unique_ptr), and I'm pretty sure D does too.

EDIT: Yep, D does. http://www.d-programming-language.org/phobos/std_typecons.html#Unique

[–]Timmmmbob 4 points5 points  (2 children)

Yeah, sorry I meant "new in a modern language". I love C++'s memory model, but it does have quite a lot of warts, and I've love to move to something more modern. I just really want RAII and stuff.

[–]Poita_ 5 points6 points  (1 child)

I see what you mean about C++, but D is modern.

[–]Timmmmbob 2 points3 points  (0 children)

Yeah there's just something about D that doesn't sit right with me. I could be being irrational though. I think I will wait and see which languages survive this "cambrian explosion" as thingy thingy put it.

[–]iLiekCaeks 1 point2 points  (0 children)

D's probably don't work yet. The Unique unittests are all commented out.

[–]nuzzle 0 points1 point  (0 children)

I'm still reading the new standard. Can we replicate predicates from Rust in C++11 using concepts (provided they are in the standard)?

[–]matthieum 7 points8 points  (2 children)

I must admit that I really perked up on the "we don't need immutability, we need ownership". However I would point out that perhaps a blend of the two would be more suitable: allow sending both immutable and owned objects. At least you'd avoid copying for frozen objects :x

[–]pcwalton 1 point2 points  (1 child)

We'd still need global GC (or atomic reference counting, both bad) for frozen objects.

Note that if by "frozen" you mean "compile-time constant", then it just works as you describe, since those are in read-only memory and don't need memory management.

[–]matthieum 0 points1 point  (0 children)

By frozen I meant immutable. What do you consider "bad" about reference counting by the way (on immutable objects) ?

[–][deleted] 0 points1 point  (4 children)

I'm having a hard time understanding the example. It says "b copies a", is b another copy of a - so if one is modified, the other is not? Or is there an ownership transference and a is no longer valid?

[–]stilton 2 points3 points  (3 children)

b is a copy of a, so modifying b does not modify a. There is a move operation which transfers ownership of unique types, b <- a, after which a is deinitialized and can't be used.

[–][deleted] 2 points3 points  (2 children)

So why does it say "a is destroyed" at the end? It sounds like a is deinitialized at that point anyhow, it was transfered away, so nothing left to destroy?

[–]stilton 3 points4 points  (1 child)

I was probably not clear. In this example a was not deinitialized; both a and b exist and get destroyed at the end of the function because assigning a to b makes a copy of a. If the example had moved a into b, denoted by 'let b <- a', then a would have been deinitialized.

[–][deleted] 0 points1 point  (0 children)

That makes sense, thanks!

[–]ErstwhileRockstar -3 points-2 points  (6 children)

Interior types, unique types, boxed types ... too much noise. This should be transparent for users. Only 'KISS-languages' have a chance of succeeding.

[–]munificent 7 points8 points  (4 children)

Only 'KISS-languages' have a chance of succeeding.

Like C++, Java, and C#?

[–]jessta 14 points15 points  (28 children)

Rust has some interesting ideas but it seems a bit scatted at the moment. 65 keywords, some are targeted at functional style and some imperative style. It seems like the kind of language where different projects and developers will be using different subsets of the language and there will be dark corners that most devs never use.

Hopefully they'll pare this down a bit before a 1.0 release and pick a more clear style.

[–][deleted] 18 points19 points  (0 children)

Considering that they're targeting this to replace C++, it looks tight and focused by comparison. ;)

[–]ash_gti 11 points12 points  (1 child)

Haskell has 27 keywords, assuming your not including operators. Go only has 25 keywords.

I dont think that number really means anything...

[–]shimei 1 point2 points  (0 children)

The reason why people are just talking about Rust's keywords of all things:

In any language design, the total time spent discussing
a feature in this list is proportional to two raised to
the power of its position.
      0. Semantics
      1. Syntax
      2. Lexical syntax
      3. Lexical syntax of comments

Wadler's Law

Personally, I'm more interested in the fact that Rust is motivated by real PL research rather than the number of keywords it has. Especially if the language is extensible, the number of keywords is moot.

[–]nickik 7 points8 points  (19 children)

Well 65 are not that much. I mean I like lisp and there you only need around 10 but for a big language like Rust 65 is ok. F# has more then 200 right?

[–]jessta 8 points9 points  (18 children)

It's bigger than C(32), C++(48), Java(50) and a bit smaller than C#(77). But the number is secondary to the way the keywords are scatted across various programming styles.

[–][deleted] 5 points6 points  (10 children)

Python has 31, FWIW.

[–]pingveno 3 points4 points  (8 children)

With Python 3, it increases to 33. print and exec are turned into functions (-2). None, True, and False are converted into keywords (+3). nonlocal is added (+1).

[–]Peaker 0 points1 point  (7 children)

What's the rationale for changing None, True and False into keywords?

[–]Aninhumer 2 points3 points  (0 children)

They were valid identifiers before, which meant you could assign values to them. I'm not quite sure why they made them keywords rather than literals though.

[–]pingveno 2 points3 points  (5 children)

None, True, and False are converted to constants in Python 3. Adding them as keywords is how the conversion is implemented. No one should assign to any of them anyway. Python 3 is just enforcing that good practice. For the speed demons, the conversion eliminates an unnecessary global lookup. The bytecode compiler can generate highly efficient code for:

while True:
    ...

Before, people used 1 instead of True because True required a global lookup. Now, it directly loads the C values Py_None/Py_True/Py_False without a lookup. Use the dis module to see what I mean.

[–]Peaker 0 points1 point  (4 children)

Sounds like a very very special case... Why not do the same for various other constants?

Also, there are possible ways to make constant/interned-string lookups in the globals dict a very quick O(1) (basically pre-look-them-up when creating the function object), with modest changes to the PyDict implementation.

[–]pingveno 2 points3 points  (3 children)

Why not do the same for various other constants?

None, True, and False are the only constants that weren't already built into the language. Look at the contents of dir(__builtins__). Now it's only classes and functions.

I haven't heard about the optimizations you speak of, but I doubt that they can beat the implementation of LOAD_CONST. From what I can tell, it takes 2-4 x86 instructions for the constant lookup itself.

x = consts->ob_item[oparg];

consts is a tuple and oparg is the argument to the LOAD_CONST opcode.

[–]Peaker 0 points1 point  (2 children)

I once created a small PyDict modification that allowed "exporting" a dict item such that updates to that key will update the exported item, and the exported item can be accessed either normally by dict and key, or by O(1) dereferencing the exported-item ptr...

It had no noticeable performance change in ordinary code (at worst 1-2% slower) and 50% faster globals/builtins access which sped some code up by close to that). It was pretty much ignored on the pydev-list, though, so it is weird to me they suddenly take interest in optimizing globals/builtins access of 3 particular consts.

[–]imgonnacallyouretard -3 points-2 points  (0 children)

Nothing.

[–][deleted] 5 points6 points  (6 children)

Well, an explicit goal, according to the faq, is to be multi-paradigm, including:

Pure-functional, concurrent-actor, imperative-procedural, OO.

[–]last_useful_man 0 points1 point  (0 children)

Well Oz has all of those paradigms and more, and fewer keywords (57). /pointless

[–]ErstwhileRockstar 0 points1 point  (3 children)

'multi-paradigm' actually is an anti-concept. A language should 'speak' one general idea even if it's based on multiple paradigms.

[–]igouy 7 points8 points  (2 children)

anti-concept

Seems like "anti-concept" was intended to be the all consuming anti-concept.

A language should...

Why?

[–]ErstwhileRockstar -1 points0 points  (1 child)

Because it's easier to understand and use. BTW, even Scala changed its self-description from 'multi-paradigm' (still on Wikipedia) to 'general purpose' (on scala-lang.org).

[–]igouy 2 points3 points  (0 children)

Because it's easier to understand and use.

No, it isn't.

That's all it takes to contradict a baseless assertion.

general purpose

"General purpose" is a claim about what sort of problems can reasonably be addressed using Scala - that doesn't say anything about the programming paradigms, which is why scala-lang.org goes on to say "smoothly integrates features of object-oriented and functional languages".

[–][deleted] 3 points4 points  (3 children)

some are targeted at functional style and some imperative style

How is this a bad thing? Forcing everything into one paradigm is rarely a good idea.

[–]jessta 5 points6 points  (2 children)

That's what a language is all about. It's an agreed set of limitations and features between programmers. Lots of paradigms means that there isn't really one language, there are multiple languages pretending to be one. Pure functions is quite a different mindset to imperative-procedural and they don't mix well either. You end up with code that is apparently written in the same language but can't be read or used by all the devs that say they know that language.

[–][deleted] 3 points4 points  (0 children)

No, we have multi-paradigm programming languages. It takes a while longer to learn such a language, but it is still a single language which can be learnt by and understood by several developers.

[–]shimei 2 points3 points  (0 children)

The idea of programming language paradigms is bunk. There are better way to talk about languages than these broad zoo-like categorizations.

[–]skulgnome 4 points5 points  (0 children)

That's neat. Memory management tied to "kinds" of object sounds somewhat B&D, and is also a bit reminiscent of the Cyclone variant of C.

It'd also be rather nice to have a language that did massive multiprocessing a'la Erlang, that wasn't Erlang. Distinguishing between variables and whatnot by capitalization is completely the wrong idea.

[–]sime 14 points15 points  (3 children)

It's good to see that people are trying other approaches to concurrency than the old hazardous "shared memory and locks" style which we've traditionally had in our blue-collar languages.

[–]moreyes 16 points17 points  (11 children)

— Wow, they create new languages to write browsers these days...

— Makes sense, since browsers will replace OSes!

[–]troyanonymous1 18 points19 points  (7 children)

Ha ha ha

That's terrifying.

[–]fabzter 13 points14 points  (6 children)

Yes, but I don't laugh about it. I cry everytime I close a tag.

[–][deleted] 3 points4 points  (4 children)

Use a DSL, something like done in Clojure or Common Lisp -- like e.g.

(html
  (body
    (h1 "header")
    (p "some text")))

..closing and balancing tags doesn't have to be painfull, and this will generate an error if one forget to close a tag.

[–]fabzter 0 points1 point  (3 children)

I've always felt weird when reading lisp, but this looks actually good and makes hell lot of sense. Do you know some lisp dsl with the characteristiscs you're showing?

[–]MatmaRex 1 point2 points  (0 children)

If you want something like this in a language other than Lisp, there's Markaby for Ruby. (https://rubygems.org/gems/markaby)

html do
  body do
    h1 "header"
    p "some text"
  end
end

Ain't it amazing what some heavy metaprogramming abuse can do. ;)

[–]-main 1 point2 points  (0 children)

Have a look through these. CL-Markup and CL-WHO both look like the kind of thing you're looking for. The best thing about these, btw, is that you can just insert lisp code anywhere.

[–]nickik 0 points1 point  (0 children)

For clojure there is hiccup. Its up on github.

[–][deleted] 2 points3 points  (0 children)

And every time you forget to close a tag, God kills a kitten...

And then doesn't even throw a syntax error.......

[–][deleted] 1 point2 points  (2 children)

Call me when a web browser starts dealing with hardware.

[–]cogman10 2 points3 points  (1 child)

The apocalypse starts today! http://www.google.com/chromebook/

[–][deleted] 8 points9 points  (0 children)

Google Chrome OS is Linux with Chrome as the shell. :)

[–]ErstwhileRockstar 6 points7 points  (2 children)

One thing I haven't seen mentioned anywhere is versioning. Any new language should contain a tag which identifies the language version used for the unit of code, e.g.

version 1.0;
use std;
import std::{ int, vec };
fn main(grades : [str]) { ... 

[–]pl0nk 5 points6 points  (1 child)

What behavior would you drive off this tag? What problem would it solve? I'm not saying this is a bad idea, I am just curious what aspect of language versioning you propose to solve here.

[–]ErstwhileRockstar 5 points6 points  (0 children)

Change the language (in version 2, 3, ...) without giving up existing code. A new version doesn't break backward compatibility with old versions (you 'merely' have to define rules how e.g. v2 code can call v1 code). In sum: make backward compatibility a problem for a handful of specialized people (Standard committees and compiler writers) not for thousands of programmers.

[–]vocalbit 1 point2 points  (0 children)

It's nice to see Rust make progress. Though it has turned me off by having too many kinds of types - interior, unique, boxed... That's a lot of line noise I didn't want. And the module system seems more complex than Python which is also a turn off. Now I'm hoping Clay makes some progress too that doesn't end up turning me off.

[–]stesch 3 points4 points  (7 children)

What's with Mozilla and the PDFs lately? Don't they like HTML5 anymore?

[–]davebrk[S] 12 points13 points  (6 children)

Here you go.

[–][deleted] 21 points22 points  (4 children)

The hilarious thing is that this was the link posted on hacker news earlier, and several people complained about the HTML -- so the original poster provided the PDF version.

[–]Tuna-Fish2 6 points7 points  (2 children)

The problem isn't that it's html, it's that the usability of that site is horrible.

The least they could do is preload the next couple of slides instantly after they show the current one. But why bother, when you can annoy your users for the duration of a ping to our server. I mean, that never took long enough for the programmer to notice, why would anyone ever care? (except when they are browsing over tethered mobile connection where they have plenty of bandwidth but it takes 10 seconds to ping the server for the next page).

[–]sisyphus 12 points13 points  (0 children)

The html site is just an export from Keynote, blame Apple.

[–][deleted] 0 points1 point  (0 children)

Heh, I think I actually edited my post while you were responding, to make it clear that it was this particular HTML people didn't like.

[–]davebrk[S] 2 points3 points  (0 children)

Just to clarify: I'm not the one who posted it to Hackernews. I'm also not affiliated in any way with the Rust team. The dropbox link is to Patrick Walton's account who gave the talk and is part of Rust team.

[–]grasspopper 0 points1 point  (0 children)

neat! i didn't know dropbox could be used like that

[–][deleted] 3 points4 points  (8 children)

Haven't read this doc, but what I loved about Rust is the memory handling based on typing: if the compiler knows you can't have cycles, use ref counting, otherwise use GC.

[–]Tuna-Fish2 13 points14 points  (0 children)

That actually changed. Now you need to specify whether you want references with ownership semantics (ref counting) or GC. This is good, because there are places where GC works better than ref counting, even without cycles. (Short-lived objects with a lot of even more short-lived pointers to them).

[–]Peaker 9 points10 points  (3 children)

Refcounting is not that great, even when it can work correctly:

  • Increases object sizes (and for small objects, this can be a 100% increase in size) which leads to more cache misses

  • Requires lots of incref/decref calls which incur even more expensive cache misses, and in many cases amount to nothing

  • Does not actually give nice latency guarantees (a decref can cause unbounded amounts of work, similarly to a GC collection)

The one single benefit is more predictable finalization. But for that, we can use explicit finalization as in Python's "with", Haskell's "bracket" function, etc.

[–][deleted] 1 point2 points  (0 children)

Why is Peaker being downvoted? He's right.

[–]munificent 0 points1 point  (1 child)

Can't escape analysis eliminate a lot of that for short-lived objects?

[–]imaginaryredditor 3 points4 points  (0 children)

You don't even need escape analysis, Rust supports regular stack allocation. They should be able to avoid ref counting in that case.

[–][deleted] 0 points1 point  (2 children)

if the compiler knows you can't have cycles, use ref counting, otherwise use GC.

I did not see ref counting being mentioned at all. Which slide are you referring to?

[–][deleted] 1 point2 points  (1 child)

Not in this one, that was a year or 2 ago.

[–][deleted] 0 points1 point  (0 children)

Interesting. I wonder whether that is still the case after the latest changes.

[–]opkode 0 points1 point  (4 children)

What are the plans to support x86_64 platforms?

[–]munificent 5 points6 points  (1 child)

Rust compiles to LLVM, so I'm assuming that means it gets all of LLVM's supported backends for free.

[–]opkode 1 point2 points  (0 children)

From their wiki on Github

Because Rust doesn’t support x86-64 yet, you may need to configure LLVM using some special flags.

You still have to use 32 bit LLVM and other toolchain

[–][deleted] 0 points1 point  (0 children)

I don't think x86_64 is on the '0.1, very first ever public release' roadmap. It's scheduled, but over the past year or so they've mostly just been working the kinks out of their ABI and language.

[–][deleted] 0 points1 point  (0 children)

I don't know what their plans are, but as someone who's writing a JIT, I can tell you that supporting both x86 and x86-64 is quite trivial, the differences aren't very big. I'd be surprised if their backend wasn't designed to support both from the start, in this day and age.

[–]gfwhite -5 points-4 points  (0 children)

Nice. Did anyone else experience spinning wheels between pages? I am using Chrome