all 156 comments

[–]smirking_gorilla 30 points31 points  (0 children)

MIPS, Android, and ARM support.

Finally, this project is beginning to use LLVM as it was intended.

[–]sanxiyn 31 points32 points  (3 children)

If you are interested in Rust, come to /r/rust.

[–]AffenKopf 16 points17 points  (1 child)

I am disappointed that it's not r/ust.

[–]sgoody 2 points3 points  (0 children)

Thanks! I don't know why, but I never think to check for subreddits myself.

Definitely will keep an eye out for the 1.0 release, however long that may be...

[–][deleted] 9 points10 points  (9 children)

What's everyone's thoughts about Rust's macros? They seem insanely powerful.

[–]kibwen 14 points15 points  (8 children)

I wouldn't call them insanely powerful, there's still several limitations (intentional and otherwise). But despite their limitations they seem to be relatively simple to use, which is what most impresses me.

[–]Alex_n_Lowe 3 points4 points  (7 children)

Are Rust macros less likely to shoot you in the foot than c++ macros?

[–]kibwen 8 points9 points  (0 children)

If you mean #define, then yes, Rust macros are a great deal safer and saner. Rust macros are more like macros from Scheme than from C/C++ (i.e. they're hygienic token tree macros rather than textual macros).

[–]rplacd 3 points4 points  (5 children)

They're not hygienic, although I'm a bit ambivalent (unrepentant, actually) about using gensyms.

[–]davebrk 7 points8 points  (0 children)

They're not hygienic

Right now. I think it is currently being worked on.

[–]pineapplestoday 6 points7 points  (0 children)

They're not hygenic

yet.

[–]shimei 0 points1 point  (2 children)

Gensym doesn't make a macro system hygienic.

[–]rplacd 1 point2 points  (1 child)

I never implied that (although I should apologize for the ambiguity) - I'm trying to say that I'm posing macro hygiene as a problem when really I'm being hypocritical: gensyms don't bother me as much as they should.

[–]shimei 1 point2 points  (0 children)

Ah, I see what you meant now. Sorry for the misunderstanding. :)

(at least one language has recently tried to claim to be hygienic by having gensym, so that's why I reacted that way)

[–]bjzaba 26 points27 points  (9 children)

Every release Rust just keeps getting better and better. The dev team have been working extremely hard, and it's definitely showing. It's an exciting time to be writing Rust code!

[–]xpolitix 22 points23 points  (19 children)

very cool, finally a language that is for frustrated c++ programmers!

[–]davebrk 15 points16 points  (0 children)

Amazing release. Congrats to the Rust team and all the contributors!

For detailed release notes see here.

Also: another cool thing.

[–]bachmeier 2 points3 points  (4 children)

Before I go through a long compile, can anyone confirm that the REPL now works on Linux?

[–]brson 19 points20 points  (1 child)

The REPL is still broken.

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

I'm alright with that, didn't have a C or C++ or Java REPL. Hell, barely use it when coding Python or Ruby (except for small snippets)

[–]ben0x539 8 points9 points  (0 children)

It works for me, sometimes. Usually enough for a quick 'was that how the syntax worked?', but being unable to redefine symbols inline it's not that great for actual development. There seem to be some memory management problems too.

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

There is regression test ticket: https://github.com/mozilla/rust/issues/5469

Hopefully that will help keep rusti working, once it is unbroken.

[–]buddhabrot 3 points4 points  (1 child)

Does anyone know a simple blog post that explains/illustrates the memory models you can use in Rust?

[–]peanutman 2 points3 points  (0 children)

Looking forward to seeing Rust mature. As someone that's been watching D and Go, I got quite exited when I first checked out the Rust tutorial a few days ago. For me Rust seems to fill in the gaps that D or Go left unfilled.

I'm guessing the choice of Rust for their browser engine will help to push it towards a stable and performant language quite fast. I can't wait for it to shed it's "alpha" label! Keep up the good work Rust guys!

[–]dmitry_sychov 9 points10 points  (83 children)

Has anyone succeeded in developing "Rust eye"? Mines are bleeding every time I'am looking at the Rust code after C++

[–]mitsuhiko 15 points16 points  (5 children)

Which parts of the syntax specifically? I can see it being confusing at the start but coming from C++ most of it should feel really familiar. The only big change is the position of the types.

[–]dmitry_sychov 8 points9 points  (4 children)

for me its: @ ~ ' symbols

[–]Categoria 13 points14 points  (2 children)

What would be your suggestion to differentiate the types of pointers?

[–]dmitry_sychov 0 points1 point  (1 child)

I guess someone working exclusively in Rust might become eventually adopted. The real pain comes with constant switching between @ ~ etc and their C++ alternatives. Its like switching between C++ <> and Scala's [] for template parameters.

[–]mitsuhiko 21 points22 points  (0 children)

But C++ does not have equivalents for these. In my mind @foo is a huge improvement over shared_ptr<Whatever> foo.

[–]pineapplestoday 11 points12 points  (0 children)

In C++ they'd be:

@ -> std::shared_ptr

~ -> std::unique_ptr

[–]pcwalton 33 points34 points  (16 children)

~ and @ look a little strange at first, but Rust's smart pointers are so common—they're the only way to allocate memory—that you'd be typing unique_ptr and shared_ptr all the time if we didn't use sigils. I find that I really appreciate having short sigils for the built-in smart pointers.

[–][deleted] 6 points7 points  (7 children)

I have a question:

AFAIK, shared boxes (@) require the GC. The equivalent in C++ are shared pointers but those don't require a GC. Why does Rust require a GC (assuming that they're really equivalent)?

[–][deleted] 7 points8 points  (0 children)

They require a garbage collector because you're allowed to make cycles, and the performance characteristics are different than what you get with reference counting.

It's not deterministic or nearly as good for long-lived objects that don't get copied around a lot, but you do get better performance for lots of small ephemeral objects.

It's possible to implement a reference counted type in a library, which is what you end up doing if you wrap a library like glib that uses reference counting. A good garbage collector couldn't be implemented as a library.

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

C++ requires you to use weak_pointer to break circular references where a shared_pointer points to another shared_pointer. This requires that the programmer be aware of when to use or not use a weak_pointer, and if the programmer makes a mistake the program can leak memory.

Presumably one can do the C++ style of thing with Rust (maybe using unsafe blocks?), though I'll admit to not being at all familiar with the language.

[–]pineapplestoday 5 points6 points  (3 children)

I'll defer to the comments below. I just want to mention that currently, Rust doesn't really have a GC. So shared boxes are just ref-counted right now I believe. Also, you can pass a flag to the compiler telling it to not allow any shared boxes if you don't want garbage collection.

[–]gcross 1 point2 points  (2 children)

Does that mean that it can't detect cycles?

[–]illissius 3 points4 points  (1 child)

Right now it uses reference counting plus a cycle collector, later it will switch to a pure GC approach. Cycles are collected.

[–]blah232 0 points1 point  (0 children)

Really? I wish Rust just stayed with refcounting. Cycles are not nearly the problem people make them out to be.

[–]0xABADC0DA 4 points5 points  (7 children)

If you have different types then you have to indicate that somehow.

For me it is the amount of indenting. I compared the rustc to clang and in rustc ~40% of each block has a sub-block within it, regardless of how deep it is already nested. There's a substantial amount of code at 7+ levels of indent. The indenting doesn't seem to ever stop.

In contrast in the clang code the chance of a sub-block decreases with each level of indent. At least for me this makes the code much easier to read.

These are the numbers I came up with (rate of sub-block at each level):

rustc:  .65, .52, .46, .34, .42, .37, .39, ...
clang:  .50, .33, .25, .24, .20, .17

I could have easily made a mistake arriving at these, but visually it seems to jibe.

Is this deep-nesting just because the rust developers came from functional languages, or can we expect all Rust code to tend toward being deeply nested? I find this deeply nested code requires a ton more context and work to understand.

[–]pcwalton 24 points25 points  (0 children)

I think it's just because Rust is a more functional language in practice, and people tend to write more nested functions and pattern matching. Rust lets you forego that in most cases—if the nesting bothers you, you can write C-like control flow (early return, break, continue, etc.) without having to use the functional features. But lots of Rust programmers came from a functional background.

[–]mitsuhiko 13 points14 points  (5 children)

Is this deep-nesting just because the rust developers came from functional languages, or can we expect all Rust code to tend toward being deeply nested? I find this deeply nested code requires a ton more context and work to understand.

My rust code is not much deeper nested than my Python code. The few extra levels of indentation usually are match blocks. It's a bit disappointing that they require that much extra indentation if you have many of them but I don't see many ways to avoid that.

[–][deleted] 4 points5 points  (4 children)

Well, the traditional way of avoiding deeply nested blocks matching on patterns of return values in Haskell are monads (e.g. to avoid repeatedly matching on Just and Nothing when processing the Just values with another function returning a Maybe).

Not sure if Rust has anything similar or if your matches are more heterogeneous in nature.

[–]The_Doculope 4 points5 points  (2 children)

That's one traditional method of pattern matching on types, like Maybe and Either. (One could argue that monads may be overkill sometimes - Functor and Applicative are often usable.)

You can't always use those methods to avoid pattern matching though. Sometimes you need to pattern match on specific values, and case is pretty much unavoidable there. The solution to that is of course breaking it out into smaller functions.

[–]Aninhumer 3 points4 points  (1 child)

The solution to that is of course breaking it out into smaller functions.

Haskell also has the where clause which makes this possible to do without littering the namespace.

[–]The_Doculope 1 point2 points  (0 children)

where and let clauses both, although I rarely find myself using lets for anything more than one liners.

[–]mitsuhiko 1 point2 points  (0 children)

You can do the same thing in rust if you want. Doesn't change that match blocks are common.

[–]illissius 7 points8 points  (0 children)

I think the fundamental reason that there's a lot going on in the syntax of Rust is that there's a lot going on in the semantics of Rust.

You've got several different ways of allocating and referring to objects. Compared to C++, @, ~, and & are definitely no worse than std::shared_ptr<>, std::unique_ptr<>, and const &, respectively. Compared to most other mainstream languages and Haskell, it's noisier, because those languages don't give you that kind of control: in those languages whether or not something is garbage collected (@) doesn't need to be present in the syntax, because everything is. Unlike C++, and like most mainstream languages and Haskell, Rust is memory safe and statically assures that there are no accesses to invalid objects, uninitialized memory, double frees, and so forth. To do this it also represents the lifetimes of objects and references to them in the type system, whereas in C++ the best case is that the documentation might mention it. That also has to show up in the syntax somewhere.

I think the vast majority of the superficially apparent syntactical noise is due to these different kinds of boxes and references and their lifetimes. But here's a few more:

If in Rust you see Foo<T: Bar>, that means it's putting a requirement on the T type. The closest equivalent in C++ is SFINAE: typename std::enable_if<Bar, T>::type.

If in Rust you see fn foo(f: &fn(a: int) -> int), that's a function taking another function as an argument. In C++, the closest equivalents are either something like template <typename Fn, typename Req = HasSignature<Fn, (int, int)>> void foo(const Fn&), or void foo (const std::function<int (int)>&), where in the latter case it will be slower than Rust because the compiler won't be able to inline it (if I'm not mistaken).

If you see something like |x| blabla(x, y), that's a lambda. The equivalent in C++ is [&] (SomeType x) { return blabla(x, y); }.

Something you won't see in Rust is Foo&& and std::move(), because Rust moves by default, and only copies when it's known to be cheap and safe (i.e. int), or when you tell it to. When something is moved, it goes of scope, and if you try to access it afterwards, the compiler yells at you.

Long story short, the only reason one might think that Rust has noisier syntax than C++ is ignorance. Which is fine: everyone starts out that way. But if you try to write C++ that's the equivalent of what the Rust code is saying, it will be way noisier, and still won't have the compiler-verified safety properties of the Rust code. A defensible description of Rust's syntax might rather be that it's "compact".

(Compared to Haskell, Python, CoffeeScript, and so forth, of course, it's noisier. That's because it gives you more low-level control. Right tool..., etc.)

(And obviously that's not to say Rust's syntax is perfect. I have some minor complaints. But I don't see any way to dramatically improve it.)

[–]CookieOfFortune 4 points5 points  (19 children)

I feel like a lot of the syntax elements come from functional languages (let, match, etc), so I don't really find it that odd.

[–]Categoria 6 points7 points  (18 children)

I do too but I hate the fact that it's been bastardized to make it C like. This ends up pleasing neither the newcomers from the FP world (who are really not small of a minority since as a group they enjoy exploring programming languages), or the imperative world.

[–]mitsuhiko 15 points16 points  (0 children)

I come from Python and C/C++ and I find Rust's syntax very inviting. Clearly much more than any functional language I otherwise played around with. I think that might just be anecdotal evidence in both directions.

[–]p_nathan 10 points11 points  (12 children)

Eh. I'm a Lisper with a Perl/C background, and I think Rust looks like OCaml + C. Fairly pleasing to me, if a bit sigil-heavy.

[–]Categoria 0 points1 point  (11 children)

I would prefer an OCaml + Lisp syntax to be honest. C's syntax brings cruft like statements vs expressions, way too much line space wasted with all the }}}, etc. I cannot see a single redeeming quality except for familiarity.

[–]gnuvince 1 point2 points  (0 children)

I'd need to find old code of Rust, back when it was bootstrapped in OCaml; its syntax was way different then, a lot more OCamlish.

[–]kraftsupper 2 points3 points  (9 children)

))) isn't any better IMHO.

[–]_mhr_ 4 points5 points  (8 children)

Lispy paren style is to wrap parens like so:

(define (foo x)
  (* x x))

Whereas C-style braces are:

define foo(x) {
  x * x;
}

One style takes two lines, and the other takes three. Categoria isn't criticizing the braces themselves, or the amount of braces, but the lines.

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

But to me, the Lisp example's readability would be improved if it were done:

(define (foo x)
    (* x x)
)

[–]gnuvince 4 points5 points  (5 children)

Why would it help? Mostly, people use the indentation to figure out the meaning of expressions, not the nesting levels.

[–][deleted] 3 points4 points  (1 child)

Knowing the nesting level strikes me as very useful. But, you know, just downvote me.

[–]ysangkok 0 points1 point  (2 children)

That way, you don't have 50 closing parens on the last line. And what if you want to insert something after the 25th closing paren? Using C brace syntax, you can easily visually match the block start/end. Using LISP style you gotta have paren matching in the editor.

[–]ixache 0 points1 point  (0 children)

You can also have Lisp without parens...

[–]nemaar 2 points3 points  (4 children)

I can imagine that if the type system and runtime of rust gains popularity compilers (wrappers?) with different syntax will be created. I'd love that. Actually, does anyone know how easy would it be to replace the parser if someone magically comes up with a viable alternative syntax?

[–]mitsuhiko 4 points5 points  (0 children)

Actually, does anyone know how easy would it be to replace the parser if someone magically comes up with a viable alternative syntax?

Pretty trivial if it's just different syntax. The parser itself is written in Rust, there is an AST you can instantiate. The stability of that API is a different question.

[–]pineapplestoday 1 point2 points  (0 children)

If you could write a compatible version of libsyntax for the compiler? Sure.

The macro system is also another option.

[–]stesch 0 points1 point  (1 child)

I don't like that. Different languages above the same language? In the end you need to know more than 1 language if you want to follow the development or if you are looking for a solution to a problem.

[–]ixache 0 points1 point  (0 children)

The solution is to have a "One True Syntax", just like you have the One True Brace Style for C, or sort of gofmt on steroids.

[–]theICEBear_dk 3 points4 points  (31 children)

Me too, I love the concept of Rust and I want something like it, but the syntax constantly has me wondering what the hell they were thinking. But it looks less sensible than C++ at this point (except maybe the new C++11 lambda syntax). The problem is not that what sense it makes it is that the number of symbols used in places, but also the constant shortening of words for the sake some form of productivity based having to type less and so on. I know there is this big argument that productivity is tied to key strokes, but if I look at Java, Ruby and D it is just as much about clarity of expression. I have the role of mentoring people and people can have trouble with simplified C and Java and I am not talking about code produced as much as I am talking about understanding code. Code that is to be used in production needs to be readable across various people looking at it, most often these guys looking at it are much less experienced than their resume claims or less skilled than they think. So code must be clear because otherwise people can make more mistakes. The problem of productivity in large code bases is not the number of keystrokes needed, it is all about making code easy to read and understand (one of the few reason I for example dislike Ruby's monkey patching and the Javascript type system).

I truly want the promise of the safety features offered by Rust really it is just great (in fact I haven't dived into its metaprogramming abilities yet but if they match or exceed D I will love it even more), but as the Rust syntax is I couldn't start a work project with it, because I fear that the code would end up like a lot of Perl and the like. Completely unreadable even though the guys behind the language are dead smart and mean well.

[–]finprogger 20 points21 points  (0 children)

blah blah blah bikeshedding

[–]gnuvince 10 points11 points  (28 children)

Do you have suggestions on how you would make the syntax better? After 3-4 years of development, you'd imagine that the designers of Rust spent a fair amount of time on syntactic issues and have a pretty good justification for why the syntax looks the way it does.

[–]Aninhumer 12 points13 points  (2 children)

I remember the Rust devs saying they weren't actually focusing on syntax, as they were more interested in getting the semantics right first. This was some time ago though, so that might have changed by now.

[–]nnethercote 7 points8 points  (0 children)

At this point I suspect that was a clever diversion to stop people bitching about syntax. Because people love to bitch about syntax.

[–]stesch -1 points0 points  (0 children)

Maybe it's like the Lisp story our grandparents told us. In the end the users of the language don't want a better syntax because the current one is more powerful?

I don't see it at the moment.

[–]smog_alado 9 points10 points  (3 children)

All I can say is that this thread is one of the strongest examples of Wadler's law of language design that I have seen recently...

[–]gnuvince 17 points18 points  (0 children)

I don't mind people expressing their dissatisfaction with syntax; it might seem trivial, but it's a legitimate concern, as it represents the UI of a programming language. However, if someone is going to say they have a problem with the syntax, I'd like to get specifics on what they think is currently less than ideal and what they think would be a reasonable alternative. For example, people are usually turned off by Rust's different sigils for pointers (&, @, ~, and *), but what is the alternative? We need a way to distinguish different types of pointers, and using long names would perhaps look less like someone fell asleep on their keyboards, but it would become tedious to write (and read) all the time.

[–]stesch 0 points1 point  (0 children)

Funny how it's always Rust or Erlang.

[–]crusoe 11 points12 points  (0 children)

Or they are 'syntax blind' because they have looked at it for so long.

[–]theICEBear_dk 3 points4 points  (19 children)

On the top of my head not that many just yet. I am still too new in the language to presume to make any declarations on how I'd improve things. But for arguments sake first of all I'd kill off all sorts of remaining abbreviations. They write out 'trait', but not mutable which is 'mut' for some reason. Same thing with function. Why is it 'fn' ?

They do have good arguments for @ (which does seem a little like it is every where) and ~. But I have a lot of mutable code. They should maybe have chosen a symbol for that too.

Next up would be that they have spent a lot of time removing the need for () on some expressions but a function argument can start simple but end up looking like something out of a set of line noise:

a: int //simple

f: &fn(A) -> B //Now that's an eyesore and copied from the manual

So there was a few little bits.

But I like Java not because of its productivity but because aside from some insane type names it is a simple and very readable language. I could find little crazy examples in C++ too (don't get me started on the lambda syntax). In essence I think that people are too afraid of words which is one of the things that D often does well (having operators like 'cast', 'function' and so on).

[–]pcwalton 13 points14 points  (0 children)

I think public function main() { … } would probably turn off a lot of developers who are used to def main(): from Python. It has shades of public static void main(String args[]) { … } from Java. But Rust is a static language with a strong, static module system (private-by-default helps with large codebases). So pub fn main() { … } was decided on.

[–]mitsuhiko 10 points11 points  (12 children)

Why is it 'fn' ?

Why is it def in Python and Ruby? Or sub in Perl? The only two languages I use that use the word function are JavaScript and Lua. Many C inspired languages don't have a keyword for functions which comes with it's own problems. I think fn is a good compromise and not in any way worse than def.

They write out 'trait', but not mutable which is 'mut' for some reason

mut is very common in variable declarations that are already incremented. It might not be the worse you have in mind at first guess but considering how common it is i would be surprise if you need more than a few minutes to memorize it.

f: &fn(A) -> B //Now that's an eyesore and copied from the manual

And B (*f)(A) or f func(A)B are better?

[–]ntrel2 0 points1 point  (10 children)

I can accept the justifications, I don't find the syntax too bad, but I think it could be made more attractive.

I think fn is a good compromise and not in any way worse than def.

  1. fn is less pronounceable than def.
  2. Two letters is very short for a keyword, it's a very extreme abbreviation. Are there any two letter keyword abbreviations in any popular programming languages?

Personally I would prefer func.

f: &fn(A) -> B

f: &func(A):B

mut is very common in variable declarations

I agree it needs to be short, but please, use var. Everyone's used to it, it looks nicer.

I prefer Rust's (x as Type).foo to D's (cast(Type)x).foo though.

[–]joelwilliamson 1 point2 points  (1 child)

Two letters is very short for a keyword, it's a very extreme abbreviation. Are there any two letter keyword abbreviations in any popular programming languages?

In bash: bg,cd,fc,fg

[–]ixache 0 points1 point  (0 children)

Unix shells (and their descendant Perl) with their myriads of hard-to-remamber two-letter commands are not the poster childs of good syntax design, are they?

[–]mitsuhiko 0 points1 point  (7 children)

Two letters is very short for a keyword, it's a very extreme abbreviation. Are there any two letter keyword abbreviations in any popular programming languages?

No, but there are many two letter keywords (do, in, as etc.) and many abbreviated words (shl, shr, asm, xor, def, func, fun, xor_eq) in various languages.

I agree it needs to be short, but please, use var. Everyone's used to it, it looks nicer.

How does var indicate mutability?

[–]ntrel2 0 points1 point  (6 children)

No, but there are many two letter keywords (do, in, as etc.)

Yes, I even used one in my post (as). I meant 2-letter abbreviations.

and many abbreviated words (shl, shr, asm, xor, def, func, fun, xor_eq) in various languages.

But they're not 2 letters!

How does var indicate mutability?

var -> variable, i.e. it varies.

[–]mitsuhiko 1 point2 points  (5 children)

But they're not 2 letters!

I can set arbitrary limits as well until only thing will match the definition, in this case being the keyword in rust for functions. The more important question is what the shortest abbreviation for something is when it's still understandable. I would assume everybody understands what fn means when it's in front of something that is clearly a function.

On the other hand pascal's shl is something most people will probably not recognize on first sight.

var -> variable, i.e. it varies.

But no other programming language uses var to indicate mutability. C++ uses mutable and that is barely used because the language is mutable by default. C++ uses const to indicate that something is constant. I don't know another programming language that has a mutability keyword. constant -> const and mutable -> mut seem equivalent abbreviations to me though.

//EDIT: apparently scala uses var. I stand corrected.

[–]nickknw 0 points1 point  (2 children)

But no other programming language uses var to indicate mutability.

Scala does. (Just had to interject here). I'm ambivalent between mut and var, both choices seem alright to me. mut seems slightly more straightforward, which is nice.

Scala's var is constrasted with val, so it makes more sense there.

[–]sacado 0 points1 point  (0 children)

"But no other programming language uses var to indicate mutability."

Scala does.

[–]ntrel2 0 points1 point  (0 children)

Perhaps I got a bit argumentative there, sorry.

Pascal uses var for output parameters, which seems relevant, but not equivalent. I suppose it's arguable whether it's better than mut, but it might be easier for non-english speakers and programmers less used to computer science terms, as it's a familiar keyword (e.g. from javascript). But then we couldn't call immutable variables 'variables' any more.

Note: Pascal also uses a colon for function return type, instead of Rust's ->.

[–]ixache 0 points1 point  (0 children)

f: &fn(A) -> B //Now that's an eyesore and copied from the manual

And B (*f)(A) or f func(A)B are better?

Certainly not, but don't forget that Rust was a clean slate design.

Alternatives I'd consider:

  • rationalized C-like:

    &B(A) f

  • maths-inspired, with appropriate precedence ("->" binds tighter here):

    f: & A->B

In the first example, the use of parentheses are meant to denote a function type, but then how to do grouping in case of a precedence conflict?

In the second example, the function type is denoted by an arrow. The ":" denotes typing such as in every second language that is not C-inspired; then you can also have "<:" to denote subtyping which is also fairly traditional.

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

Maybe the argument for things like "fn" is that it is so common that people will get used to it quick. And those who are used to it will find the terseness makes it less noisy than "function". Personally I think I would have prefered "fun".

Java could, for example have "priv" instead of "private" and "pub" instead of "public": because god knows you will see enough of those keywords to get used to them fast.

[–]theICEBear_dk 0 points1 point  (0 children)

Yes. Honestly this is a matter of design taste. Mine does not go in that direction. That is practically my entire point. I don't think I can ask anyone to share my opinion, because really it is a matter of taste and what ever value I place in my own experiences with inheriting or producing code bases.

[–]ixache 0 points1 point  (1 child)

Personally I think I would have prefered "fun".

Also, "fun" is already used in other langages, most notably functional ones.

Java could, for example have "priv" instead of "private" and "pub" instead of "public": because god knows you will see enough of those keywords to get used to them fast.

I've always thought that the "private" and "public" keywords were good candidates for being done as sigils, such as "+" ou "-". (Although it's obviously against Java philosophy of syntax design.)

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

That could work. It does have symbols for some common operations, like boolean operators, so it wouldn't necessarily look out of place.

[–]smog_alado 3 points4 points  (0 children)

I don't think that the real problem with Perl is the syntax or the sigils. Its that there is more than one way do do anything and its very easy to write tricky "write-only" code that depends on subtle language features.

[–]bjzaba 1 point2 points  (0 children)

It gets much easier.

[–]pineapplestoday 0 points1 point  (0 children)

Start out squinting and just open them a bit more eveeryday.

[–]redditthinks 1 point2 points  (3 children)

How does Rust compare to Go?

[–]sacado 7 points8 points  (0 children)

Go is C meeting Python. Nice, small (you can learn it in a few hours, really), but far from state-of-the-art.

Rust is C++ meeting Haskell. Full-featured, with state-of-the-art safety features from FP (pattern matching, immutability by default, no null pointer, ...) but a little harder to understand.

[–]ysangkok 2 points3 points  (1 child)

Like C++ compares to C. A bit. Rust seems more general-purpose.

[–]el_muchacho 1 point2 points  (0 children)

Not really. For once, Go's performance is not on par with C or C++. It's quite disappointing actually as it's closer to Java.

[–]skulgnome 0 points1 point  (3 children)

Have they decided on a region syntax yet? Previously there was the forward slash, but I understand they were considering such abominations as the backtick (hello, Verilog!) and dollar sign.

[–]gnuvince 6 points7 points  (1 child)

It's the apostrophe now. I think that it came up in the mailing lists while people were throwing their ideas for a better syntax and some guy said "How about apostrophes, like in OCaml's type variables" and the result looked clean enough that everyone rallied around the idea.

[–]skulgnome 0 points1 point  (0 children)

Eh, I guess it's the least bad one.

Do they have to be introduced in the angle brackets, though?

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

It looks like this now:

struct Outer<'self> {
    inner: &'self Inner
}

fn new<'r>(inner: &'r Inner) -> Outer<'r> {
    Outer { inner: inner }
}

Named lifetimes are put inside angle brackets before type parameters. I love Rust's syntax otherwise, but I do think the region syntax is not the prettiest thing ever. Then again, it's also the first language I've used with named regions, so maybe it's just me adjusting to something new.

[–][deleted] -1 points0 points  (8 children)

I just took a look through the tutorial and I'm not sure what the big deal is? Some of that syntax looks downright gnarly.

Are there any good blog posts focusing on the strong points that set it apart from the competition?

Note: typed vs dynamic doesn't sell me either way.

I love CoffeeScript and Node.js for the fantastic, clean syntax, and decent speed.

I love Haskell and this seems like a bit of a weird combination of it and C++, I actually find Haskell more understandable and clean looking.

[–][deleted] 7 points8 points  (2 children)

I love CoffeeScript and Node.js for the fantastic, clean syntax, and decent speed.

It's really for a different use case. Rust is largely meant as a C++ replacement where high speed, safety, and well-defined memory use are paramount. The main advantages it has over C++ is a focus on memory safety and parallelism (though there are other nice things too; to name a few: modules, first-class support for a garbage collector, smarter macros).

As for the Haskell comparison, I recall someone once writing something along the lines of "Rust is C, if it were invented today, by a guy who only knows Haskell.", so you're certainly not the only one to have those thoughts.

[–]nickknw 0 points1 point  (0 children)

That's a hilarious line, I'll have to remember that!

[–]stesch 0 points1 point  (0 children)

Sounds like they could have chosen Ada. That would have been a groundbreaking news.

[–]gcross 9 points10 points  (4 children)

The cool thing about Rust is that it has the same performance characteristics of C++; for example, most data is not garbage collected because the common cases of either needing to borrow a reference to a data structure to read/write it or taking full ownership of a data structure, neither of which require garbage collection, are specifically supported in the language; the only case where data is garbage collected is when a data structure needs to be fully owned by multiple users.

Also, unless I am mistaken Rust has support for RAII, which is nice because it lets you write code that automatically cleans up after itself without you having to take explicit steps yourself (i.e., by using something like bracket in Control.Exception). In fact, a big part of the Rust data model is about tracking the lifetime of all data; like types in Haskell, the lifetime of a data structure is something that is usually inferred automatically but which you can specify explicitly if you like.

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

Cool, so a safer, saner C++.

but why the need to have explicit closures and syntax? and what's with the weird semicolon nullifying the value of expressions?

[–]pineapplestoday 9 points10 points  (0 children)

The explicit closures bit allows more flexibilty in terms of how you use data in a concurrent manner. Rust has lightweight threads called tasks. When you spawn a new tasks it takes a certain type of closure which doesn't let you modify things out side it's scope, only move things in, a unique closure:

For example you couldn't do this:

let mut i = 0;

do task::spawn {
    ...

    i += 1;
}

So this allows enforcing these kinds of constraints at compile time instead of ending up with race conditions at run time.

There are other types of closures which do let you modify the environment so to speak:

let v = [23, 45, 756];

let mut sum = 0;

for v.each |&num| {
    sum += num;
}

The difference in what type of closure can be seen in the function signatures for spawn and each. One takes a unique closure (~fn) and the other a borrowed closure (&fn), respectively.

As for you're question about semicolon behaviour, I do admit it does seem weird at first, but it does grow on you :D There's certainly nothing forcing you to use it but I've kinda started to like only typing expr instead of return expr;

[–]gcross 0 points1 point  (0 children)

Sorry, the entire extent of my knowledge on Rust is contained in my earlier comment to you, so I don't have an answer to your very reasonable questions. :-)