Hacker News new | past | comments | ask | show | jobs | submit login
Rust by Example (rustbyexample.github.io)
335 points by adamnemecek on Apr 26, 2014 | hide | past | web | favorite | 161 comments



I try to describe Rust to lots of people. It's astonishing to me that most people have not imagined the possibility of a language having manual memory management with the compiler checking for mistakes and guaranteeing safety. So many programmers have such a low opinion and comprehension of type systems that it's very regrettable.


I am one of those people who didn't really consider the possibility. It's not that I thought it was impossible, but I dismissed it as probably impractical to use.

Rust is showing that it's actually practical, in a somewhat-normal language with somewhat-normal libraries.


They should use that on their publicity material: "Rust: it's somewhat normal".


Fwiw, I never appreciated type systems till I learned Haskell, which showed me that mere data types do not a type system make. Type classes, signatures based on currying, an entire language designed around sophisticated type theory, it was probably the biggest eye opener since grokking lisp's code is data is code paradigm. But most undergrad education is C, C++, Java, and maybe Python these days, and don't get me started on Rails schools. You tend not to learn this stuff unless you hang out at HN, or Reddit back in the day, or read PG's essays, or are just naturally curious.


We can see a live example of that in some of the comments in this thread..

Two decades of garbage collected languages, with fat runtimes that does everything under the hood + lazy programmers with Moore's law mentality

Note: its ok for script languages that have exacly this purpose, to be easy and ask less from the programmer.. like Javascript or Lua.. But its a shame that languages like Java have created such a bad mentality..

For system programming its not cool to abstract the machine too much.. we've learned that lesson the hard way (see the big projects like hadoop in manage languages for an example)

Those languages asks almost nothing to use them.. but you end up paying a lot more latter, because of the abstractions layers you just cant change..

You are lucky if you project starts simple and remain simple over time, but the majority of the projects are not like that..

Yes: javascript for system programming like in nodejs is a bad idea (as in: "free entrance, pay with your blood later")


Oh master, please teach an unworthy soul the path to the true enlightenment you must be experiencing everyday while being close to the metal, because this fool was blinded by the promises of fat runtimes that can deliver business value in a shorter amount of time without having to worry about the cost of virtual table dispatches, memory leaks, buffer overflows or differences in the memory models and libc versions of the underlying operating system.

> For system programming its not cool to abstract the machine too much.. we've learned that lesson the hard way (see the big projects like hadoop in manage languages for an example)

Oh master, please do say what's wrong with Hadoop, one of the best and most successful pieces of open-source infrastructure. Truly you must know of a better alternative that isn't burdened with the cancer that is the JVM.

Also, you must mean something different when you're saying system programming, because in my dictionary, Hadoop ain't it. Not a native english speaker here, must take some lessons apparently.


You are probably using Hadoop and not developing it?.. and by the way i was not saying anything against it.. on the contrary.. its a very big respectable project in java.. but if we get into the storage layers for instance, we can find a lot of problems, with memory pressure for instance, because you are paying (without asking for) for the java runtime inner abstractions

Let me ask this diferently? how many Big mission-critical sucessfull projects you see that are not implemented in unmanaged languages like C/C++ ?? Browsers, OS, Databases , speech-libraries, Neural Nets ??

Hadoop happens to be in Java as Lucene and Sorl, because thats what Doug Cutting choose as his language,and this guy is a monster.. If Hadoop was created in something like C++, you can bet that it would have much more success than its having now (as you would probably be able to embedd even in smartphones)

Also java is almost there, because at least it has a type system.. but it started to popularize ideas from the Smalltalk, and Self, wich are good to be well known.. but nowadays, we have too many of them.. (and people seeing Rust ask for more of them?)

The problems that Rust are trying to solve, are very hard.. and we have enough choices for managed languages(java, c#, go, javascript, python, ruby).. but almost none for languages that do the core of our IT infrastructure like C/C++..

My comment was just to point out that there are a whole generation of programmers that were taught not to think about allocations, with everything automated for them.. its cool to have those tools around? of course, its nice to have choice! but not having any other options for much of what we do, and then when something cool like Rust shows up.. not being able to reconize it for what it is.. because you know.. you are expecting that any modern language must have a GC or not have generics or macros like some comments i have seen in this thread... its just plain nonsense..

Not only Rust can be used to those tasks, but also it take in consideration a lot of research in languages and type systems..

I was not saying those languages are bad per se (but used in wrong problem spaces not suited for them).. only that some developers are too much alienated and do not know what they are talking about well as their critiques shows..

edit: about Hadoop and system programming -> what is HDFS? distributed storage, distributed networks, consensus protocol, etc ? The layer that hadoop present to the platform user are definitly not system programming, but the lower levels of the platform wich is what hadoop is made of is


The "oh master" is every bit as juvenile as you think his comment was. I was actually intrigued by what he said (and rewarded when he expanded upon his idea below), and don't think it deserved the flurry of down-votes your condescending comment probably brought it.


You're proving the point, here. The "enlightenment" IS that you can achieve type safety and "business value in a shorter amount of time" WITHOUT the overweight JIT'd runtimes.


What project, written in Rust, actually used by as many people as Hadoop is, has proven that?


Obviously your condition that the answer to your question be a project that is used by as many people as Hadoop is ridiculous given the different language maturity levels you're comparing. But ignoring that requirement, servo is a big project, written mostly in Rust, that (in my opinion) demonstrates that 'you can achieve type safety and "business value in a shorter amount of time" WITHOUT the overweight JIT'd runtimes'.


You do realize that Java has had like a 15 year head start right?


The language hasn't reached 1.0 quite yet. Give it 2 years and then ask this question.


In which language can you get all of that in a shorter amount of time? Rust? I'd have thought that it is still too early to say, but maybe there have been a lot of reports of that even by now.


We spend the better part of two decades focused on the JVM, and then another decade on CLR.

Give it time.


> Give it time.

I am:

> I'd have thought that it is still too early to say,


One of the fascinating ambitions of Rust is to bring linear type systems to the mainstream. The programming world is so un-acquainted with linear types, yet the possibilities are staggering. To me, functional programming languages were always based around referential transparency: the property that a name and its value are interchangeable. But Rust takes another approach: a name is an owner of value, and owners are linear resources. This is very exciting, and makes me want to learn linear logic. It also makes me wonder if there is a smaller language dying to break out of this larger one.


> It also makes me wonder if there is a smaller language dying to break out of this larger one.

I don't think so, at least without sacrificing one of (a) memory safety; (b) no mandatory garbage collection; (c) race-free concurrency. Virtually every feature in Rust* is necessary to achieve one of those three goals.

* OK, not methods, typeclasses, or macros. But methods and interfaces/typeclasses in some form are more or less an expected part of every programming language that is to go mainstream nowadays, and macros are necessary for really important conveniences like println and deriving to work.


You could if you had only linear-typed mutable and refcounted immutable. Refcounted immutable obviously could not contain pointers to linear typed mutable things. That would be much simpler, just as safe and require no GC.


Well, you'd have no multiply-owned mutable state then, which would prohibit a bunch of useful things (such as implementing the DOM in a browser).

In any case, you just described basically how Rust the language works: the ref-counted mutable types are all just part of the standard library, implemented with unsafe code but exposing a safe interface. The only mutability in the language itself is through linear types.


I'm excited about practical linear typing implemented on the top of full-dependent systems. It would bode pretty well for experimentation and research, more so than baked-in linear type systems, because of the possibility of writing new stuff without having to touch the compiler internals.

In Idris there is some experimental support from writing effectively linear/substructural typing rules for some program state, all within the language, and using it to enforce resource usage or state transitions.

http://eb.host.cs.st-andrews.ac.uk/drafts/eff-tutorial.pdf

In its current form it's not all that usable, because Idris itself is not usable, the error messages are positively Lovecraftian, and there is a hefty performance overhead. But it could be really good when fleshed out.

It would be also great to be able to interface higher-level linear typing constructs with low-level primitives, so that we could reproduce some of the main benefits of the Rust type system, and maybe write some kind of custom "ST monad on steroids" with more control over memory.


This is pretty cool. To my surprise, I found many language constructs similar to Scala. Is it just me? It's like go and Scala mashed together with the good parts from both syntaxes.


Rust takes more from OCaml and Haskell than Scala, but it's very inspired by functional languages, it's not just you.


I don't know OCaml much but the syntax for pattern matching, Tuples, Traits, the fact that map, filter etc are methods on the collection (unlike F# or Haskell) feels more like in Scala than pure functional to me.


Yeah, Rust tries to integrate method syntax into the language more than OCaml (whose object system is kind of separate) and Haskell (which doesn't have an object system). It's a different approach from Scala, though: we don't have inheritance or virtual methods outside of traits (which are like interfaces).


There's tons of Python too, wouldn't you say?

In a way, it's good - people are discovering what works and moving it forwards. Language fragmentation often seems like a shame - because most of the time, programming languages don't fit into different niches, we just have a multitude of general-purpose languages with a few special features to argue over. There's some hope that, over long periods of time (longer than our typical careers) languages will combine good features, genetic-algorithm style, and in the end we'll get even better languages.


Scala and Rust share common roots in ML and Haskell. I would say it's more like a mash between C++, ML and Haskell.


This is cool. I'm really excited about Rust, but as a programming hobbyist(noob) I haven't been able to get very far with it. The language is starting to become more googleable now, even though the name "rust" is a hinderance.

That's one of the things I like about clojure. Very googleable name.


As it becomes more famous Google will learn that it's a programming language and that you're a programmer. The first search result for "View" is the Android documentation for me.


This. Google has been talking about personalized search for a decade. And for years they would say that your search results were personalized but it wasn't really obvious. You had to just trust that what you're seeing is better because they say it is and that it's just for you.

But sometime in the last few years this seems to have hit an inflection point. Domain and location specific results are expected now. Where a decade ago I would have to type in "Sycamore San Francisco" now I just type in "Sycamore" and I get what I want.

This also has an effect on adwords campaign tuning. As people become trained to not include locale in their query, the keywords become fewer and more generic. You of course use location targeting but many people crafted thousands of location-specific keywords that get less and less traffic going forward.


I guess/hope that "rustlang" (like with D and go before) will become the googleable term.


Golang was the original name of the language.


Trying to find out what rustc's oxidise step was especially painful.


There, you finally pushed me over the edge on it—https://github.com/mozilla/rust/issues/13781


I am a CS student who had to use Rust for my OS class. I have had several issues using Rust so far, mostly caused by a lack of verbose documentation and examples. The basic ideas are great, but it's hard to learn about some things, such as lifetimes, because it isn't covered in extensive detail in the official documentation, and not at all elsewhere. The compiler is no help, because the errors aren't online.

I won't be using Rust again until well after its 1.0 release. I don't want to struggle with a language, I want to program in it. Rust just seems like it requires a much deeper knowledge of programming theory in general for one to use it effectively, and people like me would rather just write it in Python.


That seems odd for a student. Let me explain what I mean.

As a student myself (formerly in CS, now Software Development), I believe that getting into a new language with a nice community, such as Rust, seems like a very good way to learn from the design mistakes that the implementors do along the way, unlike with a language like C where not much is changing.

It may also be a good place to contribute, especially since docs, tutorials and simple yet useful libraries might not yet be very present even though they are needed.

Finally, you state the the compiler is no help because the errors aren't online. I agree that this is a valid point. However, I would just ask on Stackoverflow or on the #rust IRC and then contribute the answers you get back to Stackoverflow for others to see.


You have valid points, especially about contributing back to the community. However, I was using Rust to learn how a webserver or a kernel worked, not to learn how a language worked.

If I was writing my own code for my own use, and it didn't effect a grade or was part of important work, then using Rust and learning from/contributing to the community would be a great experience.


The bigger issue is that your course professor picked a language that's still pretty new and under development. To quote the Rust website "Rust is a work-in-progress and may do anything it likes up to and including eating your laundry".

> Rust just seems like it requires a much deeper knowledge of programming theory in general for one to use it effectively

I mean it's on the lower end of language spectrum so yes, it requires more knowledge than say Python but it's not much more than say C.

> people like me would rather just write it in Python

Rust is not supposed to replace Python, it's supposed to replace C/C++/Ada.


I think what I should have said is that, since I had deadlines for project submissions, dealing with Rust in its current state was more difficult than writing it in Python would have been.

I do understand that Rust is trying to become a better alternative to current lower-level languages, but my OS class is (supposed) to be about how things like kernels and schedulers work, not about college students struggling with a new under development language. So by "rather just write it in Python" I meant "rather just write it in something I already can use efficiently." I am obviously not who Rust is aimed at.


You can't write an OS in Python.


This looks great, I've bookmarked it for the next time I want to learn a new language.

Speaking of which: I haven't been keeping up with the Rust news, is it stable yet? Or are they still introducing breaking changes?


Breaking changes still happen, but commits to the rust repo are tagged with [breaking-change] so you can easily do a `git log --grep breaking-change` and (hopefully) get a good idea of how to fix your code. For more gradual breaking changes, the developers have been good at adding lints to rustc so you're told how to fix your code via compile-time warnings. Vec migration and crate attribute syntax are two recent examples of this.


It's worth mentioning that this policy is only a few weeks old, so it's more of a 'will be in the future' thing than it is 'all the changes so far' thing.


Not quite stable (current version is 0.10) but they are trying to keep the breaking changes to a minimum.


I wouldn't say "trying to keep breaking changes to a minimum"; breaking changes still happen a lot. More accurate would be that breaking changes are happening less frequently than they were and generally require less effort to accommodate.


Let's be a bit more precise: the _language_ has few breaking changes right now, but the _libraries_ are absolutely in a lot of flux.

My "Rust for Rubyists" doesn't use a ton of library code, and here's all it took from 0.9 to 0.10: https://github.com/steveklabnik/rust_for_rubyists/commit/9e5...


I looked through that, and it seemed that the vast majority of the changes were in prose, tool output, and println. There were some other smallish changes as well, but that doesn't seem so bad for a language that is being very clear that breaking changes are still occurring.


Yup. To be clear, this is a ~50 page introduction to the language, so it's not as though I'm testing all of the features of Rust, but the language itself is not changing a whole lot at this point. And what does is often a find/replace.


A few observations knowing nothing about Rust until I read this, perhaps someone can shed some light on these:

THE BAD:

* keywords like "let" are extra work for the programmer because the compiler can infer them automatically.

* I’m not a fan of printf()-style parameters, because they break ordering (remarkably, php does this best with its “.” and “$” notations).

* Mandatory curly brackets are also more work, although they (could) prevent subtle bugs later.

* I’m not a fan of the generics syntax, borrowed from templates in c++ (I prefer the something like the “auto” style more, shifting work to the compiler).

* Forcing the programmer to manually place values on the heap with “~” is annoying, when other languages can automatically optimize such things.

* It seems that move semantics distinguish between objects and primitives, instead of everything being an object?

* Borrow is confusing to me, because I would probably make an immutable object passed to a function as mutable create a copy (but maybe it avoids subtle bugs).

* Lifetimes completely confuse me, as it seems like they would be handled by garbage collection?

* I don’t have a problem with the “static” keyword, except that wouldn’t global immutable variables be static anyway?

* I might have gone with traits (interfaces) everywhere instead of distinguishing them from structs, because that seems to be the direction the world is going, to avoid inheritance problems.

* I’m not sure I would have distinguished closures from functions with special syntax (although maybe it prevents subtle bugs later).

* #[bench] seems a little weird (putting profiling calls in the code), although I do find myself wanting this constantly, so if they conditionally compile they could be handy.

THE GOOD:

* Real preemptive threads it seems (as opposed to Go’s goroutines which are cooperative threads/coroutines).

* UTF-8, non null-terminated strings are good (I wonder how they handle character boundaries though, especially in languages besides English).

* Some argument could be made that borrowing c++ concepts makes Rust more approachable.


> I’m not a fan of printf()-style parameters, because they break ordering (remarkably, php does this best with its “.” and “$” notations).

Rust's println! macro also supports named format parameters, which don't need to be in the same order as the format string.

    println!("{foo}: {bar}", bar=5, foo="abc");
> It seems that move semantics distinguish between objects and primitives, instead of everything being an object?

Structs fulfilling the Copy trait (meaning they don't have destructors and can be duplicated with a simple memcopy) have the same copy semantics as primitive number types.

> Forcing the programmer to manually place values on the heap with “~” is annoying, when other languages can automatically optimize such things. > Lifetimes completely confuse me, as it seems like they would be handled by garbage collection?

Rust is a systems language. The language makes memory allocation and management explicit, by design. Lifetimes allow Rust to provide memory safety at zero run-time cost. They're how the programmer proves to the compiler that pointers are valid at the time of use. There is no garbage collection by default; only when you use the Rc or Gc types from the library.


Thanks for taking the time to write out your observations! :)

Some comments (speaking as someone who has followed rust for a while, but isn't heavily involved):

In general, rust wants to enable people to write code with unsurprising performance. So leaving it to the compiler to decide whether a value lives on the ~ heap wouldn't be appropriate for all use cases.

Similarly, the thing about the complicated lifetimes and borrowing shenanigans is that they exist to enable safe, efficient code that doesn't require a garbage collector.

Move semantics distinguish copyable-by-memcpy types, those can be primitives or user-defined types. It just can't be something like a ~ pointer or a type with a custom destructor or whatever, since having duplicates show up arbitrarily would mess up the associated bookkeeping. Primitive types also tend to implement the Clone trait so they can be explicitly copied with the .clone() method just like user-defined types implementing it.

Syntax is always a matter of taste... I think most people are happy with "let", there's always people who'd rather have s-expressions or significant-whitspace-delimited blocks instead of curly braces but also the other way around, I sympathize with distaste for the generics syntax to some extent... in the end you can't please everybody and you could probably do worse than making your language that is aimed at C++'s niche look a bit like C++.


> * Lifetimes completely confuse me, as it seems like they would be handled by garbage collection?

Interesting misconception :)

Lifetime is used to avoid garbage collection. By expressing the lifetime of a variable preciously in the code, the compiler knows statically (i.e. when compiling instead of in runtime) when an object can be destroyed, avoiding GC overhead and offering deterministic destructure.


> keywords like "let" are extra work for the programmer because the compiler can infer them automatically.

I strongly disagree. In my experience scope inference either completely blows (javascript, coffeescript), sucks (python) or requires language asymmetries (ruby). Either way, I've come to see it as an awful idea.

> I’m not a fan of printf()-style parameters, because they break ordering (remarkably, php does this best with its “.” and “$” notations).

Rust does not use printf-style parameters, it uses C#-style parameters[0] (also used in Python's "new" str.format[1][2]). The format placeholders can explicitly specify the parameter index (in whatever order, e.g. "{1} {3} {0} {2}") or name ("{foo} {bar} {baz}"). See third and fourth println! of the second page.

> I’m not a fan of the generics syntax, borrowed from templates in c++ (I prefer the something like the “auto” style more, shifting work to the compiler).

?

Rust already has local type inference (which is what `auto` does), generics syntax is orthogonal to TI.

> Forcing the programmer to manually place values on the heap with “~” is annoying, when other languages can automatically optimize such things.

The whole point there is to have the developer knowingly decide whether they want allocation on the stack, the heap or somewhere else (managed or refcounted heaps are/will be available[3]). Rust is aiming at C++'s niche, not Java, having the language heap-allocate by default and try to guess if it could just stack-allocate wouldn't work.

> Lifetimes completely confuse me, as it seems like they would be handled by garbage collection?

Rust's GC is optional, and most of the standard library (and as experience shows libraries and code bases) can avoid GC. The point of lifetime is to avoid both mandatory GC and manual memory management (à la C): if the compiler knows when an object completely stops being used, it can automatically and safely release even heap-allocated objects.

> I might have gone with traits (interfaces) everywhere instead of distinguishing them from structs, because that seems to be the direction the world is going, to avoid inheritance problems.

Where do data members (attributes) live if you don't have structs?

> #[bench] seems a little weird (putting profiling calls in the code), although I do find myself wanting this constantly, so if they conditionally compile they could be handy.

#[bench] is a specialisation (of sorts) of #[test], it's only compiled in when using --test, and run when passing —bench to the resulting test harness. see http://static.rust-lang.org/doc/0.10/guide-testing.html#micr...

Note that it's not a profiling call, it doesn't profile anything (unless you enable the profiler while running the bench), it only provides coarse/toplevel timing information, like python's timeit or ruby's Benchmark

[0] http://msdn.microsoft.com/en-us/library/system.string.format...

[1] https://docs.python.org/3/library/string.html#formatstrings

[2] technically it's probably Python's version, IIRC C# requires the index and has no support for name-based parameters

[3] and maybe user-provided boxes, such as a zeroing box (to store cryptographic keys) or a GPU box, or local v remote for clusters, the sky's the limit


> keywords like "let" are extra work for the programmer because the compiler can infer them automatically.

Apparently, the "let" keyword is needed for parsing so that Rust can have non-trivial patterns on the left hand side of the assignment operator. As in, destructuring binds. I'm assuming you don't know about pattern matching. Pattern matching is a good thing. Maybe even one of the greatest things.

> I’m not a fan of the generics syntax, borrowed from templates in c++ (I prefer the something like the “auto” style more, shifting work to the compiler).

I'm assuming this means you are not a fan of generics. Parametric polymorphism is one of the most powerful things in all of type systems. http://en.wikipedia.org/wiki/Parametricity It's deeply regrettable that not every programming language that exists today has great parametric polymorphism support (Go, I'm looking in your direction). Type parameters and type variable are CRUCIAL for this.

> Forcing the programmer to manually place values on the heap with “~” is annoying, when other languages can automatically optimize such things.

The point of the "~" is to make ownership explicit. C++'s type system is insufficient to make guarantees about ownership. It only recently gained move semantics, which enabled unique pointers, but it makes no guarantees about any other references you make to the object (with the use of .get() and non-smart pointers). As a result, you have to make sure you use C++ smart pointers with discipline. Anytime you are required to do something with discipline, that's an opportunity for a type system to jump in and check your discipline.

> It seems that move semantics distinguish between objects and primitives, instead of everything being an object?

Afaik, in Rust, everything is a primitive, and nothing is an object. What does object even mean?

> Borrow is confusing to me, because I would probably make an immutable object passed to a function as mutable create a copy (but maybe it avoids subtle bugs).

You've never passed anything by reference before? Note that borrowing has less to do with mutability and more to do with ownership discipline.

> Lifetimes completely confuse me, as it seems like they would be handled by garbage collection?

Have you imagined the possibility of a language that does no garbage collection, because it has worked it all out statically? A garbage collector is nothing more than a potentially compile-time problem deferred to run-time. When we moved type-checking from the run-time world to the compile-time world, we gained HUGE benefits in time/space performance and in informing the programmer upfront more about the potential behavior of their program. If only we could do the same thing for memory management. That's what Rust is trynig to achieve.

> I might have gone with traits (interfaces) everywhere instead of distinguishing them from structs, because that seems to be the direction the world is going, to avoid inheritance problems.

Inheritance does cause lots of problems. It's not only that, but Haskell type classes are general and cover lots of real world cases that shitty mainstream type systems can't. One simple example I give is a type-safe .equals method. Java's .equals is type checked ad hoc by the programmer (the argument is an Object, and the programmer typically uses "instanceof" and a cast). You can use generics, but it's still broken, and if someone cares I can go into more detail. Haskell type classes is the only type system I know of where you can just say "hey there's this class of types called 'Eq', where there's a method that takes two arguments of type 'self' and returns a bool". So many OOP type systems only let you have 'this' of type 'self' in a method. I'm handwaving a bit in my description here, but it's a shame this problem isn't just obvious to everyone. Rust is inspired by Haskell type classes, but not fully there.


This is very informative, thanks. If you could share some detail on how Rust falls short of Haskell type classes, I'd love to hear it. I'm digging into Rust, but haven't gotten that far yet.


The Rust trait/typesystem doesn't currently support higher kinded polymorphism.



s/near//.

That article is more "let's describe HKTs in Rust-y terms, so that more Rustaceans understand their purpose" than an actual proposal for implementing them in Rust. Any concrete proposal (i.e. covering implementation details and corner cases, rather than just some syntax/use-cases) would need to go through the RFC process: https://github.com/rust-lang/rfcs/blob/master/active/0001-rf...

((Unfortunately?) I imagine such an RFC would spend a month or two (or more) being discussed/thought-about.... And double that discussing syntax. ;P )


There are LOTS of things you can do with type classes, and they are super sexy. Let me try to enumerate them.

One commenter already noted higher-kinded type classes, which is the basis of Haskell's libraries and do-notation for monads. That's HUGE.

But besides higher-kinded type classes, there are others:

* Factories and constants in your interfaces. Type classes allow you to put a type variable in the return argument of a method. This lets you put factories and constants in your type classes. For example, if you look at the monoid type class:

  class Monoid a where
    mappend: a -> a -> a
    mzero: a
And I can implement this

  instance Monoid String where
    mappend x y = AppendStrings x y
    mzero = ""

  instance Monoid Integer where
    mappend x y = x + y
    mzero = 0
So now I can write generic code where I can get the "zero constant" of a type without knowing what type that is. I could just have a genericMonoid : T where T is a type variable, and all I know about it is that it belongs to class Monoid (maybe it's an integer, maybe it's a string, maybe it's something else). I can now get the zero value of whatever that type is. In fact, my method doesn't have to be dispatched on the type of some input argument. I can dispatch on the return value. Something like

  multiplyByZero : [Monoid T] int -> T  
  multiplyByZero 0 = mzero
  multiplyByZero n = mplus mzero (multiplyByZero (n-1))
(Forgive my crappy Haskell pseudo syntax, I haven't written it in a while). Not that multiply by zero is useful.

* Operators of greater arity than 1. So I hinted at this above. With "method syntax" arity is always 1. I have one "this". I can operate on it. For all other arguments to my method, I cannot actually constrain them to have the same type as "this". At best, with OOP, my method belongs to some base class, and I can insist that the non-this arguments are of base class type, but I cannot constrain them to have "this" type. This is illustrated in the monoid example above, or in the Eq example I gave, where it can be guaranteed that the two operands to == are always of the same type. In Java, the equals method has to take one argument of type "Object", while the "this" argument has the class's type.

* Multiparameter type classes. (This is behind a flag in the Haskell compiler). You can do something like this:

  class Eating E F where
    eat ::  E -> F -> Meal

  # E is short for Eater
  # F is short for Food
so now I can type check to make sure that eaters eat the right type of food.

  instance Carnivore Meat where
    eat = # specialized implementation for eating meat

  instance Carnivore Vegetables where
    eat = # specialized implementation for eating vegetables

  instance Vegeterian Vegetables where
    eat = # specialized implementation for vegeterian food


I'm not sure if all your examples were meant to be things that Rust doesn't have, but Rust certainly has polymorphic return values. For example, see the `Default` trait: http://static.rust-lang.org/doc/master/std/default/trait.Def...

It's also used to generate random values: http://static.rust-lang.org/doc/master/rand/trait.Rng.html

More generally, Rust supports polymorphism anywhere. e.g., The `Eq` trait: http://static.rust-lang.org/doc/master/std/cmp/trait.Eq.html

AFAIK, >1-arity polymorphism in OOP languages is generally achieved with double dispatch. But it's not as nice (or as easy to understand IMO) as in ad hoc polymorphism.

Rust does not have HKT or multi-param traits though.


> Lifetimes completely confuse me, as it seems like they would be handled by garbage collection?

RAII approach (https://en.wikipedia.org/wiki/RAII) is more efficeint than garbage collection and also way better because of predictability. I'd say it's also more straightforward. Instead of some unpredictable and chaotic background magic going on, resources are deallocated right when they aren't needed anymore. I really don't see why would anyone prefer GC to it.


> Real preemptive threads it seems (as opposed to Go’s goroutines which are cooperative threads/coroutines).

Go's goroutines are preemptive.


> Go's goroutines are preemptive.

Not quite. Since 1.2, goroutines can yield on non-inlined function calls (in 1.1 it happens only on IO or on an explicit Gosched() call). A goroutine with no funcall or only inlined function calls will still block the scheduler (and the whole system if there's only one scheduler).


This tends not to be an issue in practice as you almost always have non-inlined function calls or short-executing loops. The one way in which this might be a problem is if you try and implement a spinlock, but there is no excuse for that given the go concurrency features.


> This tends not to be an issue in practice as you almost always have non-inlined function calls or short-executing loops.

Until it's an issue because somebody set up CPU-bound image processing, and then by lying you've set people up for failure and you've given them a huge blind spot once things start not working correctly.


Good point. It was a shortcut that I shouldn't have taken.


You're right, it's generally not an issue. Acting like Goroutines are preemptive isn't likely to land you in a lot of trouble.

Nevertheless, they aren't preemptive, so you shouldn't say that they are. Maybe "almost preemptive"?


:) I like that phrasing, it gets to the main result (you shouldnt ever worry about it) while still giving you the out that more leaks under the covers (in case you think this might be biting you.)


If you use libgreen in Rust, you don't even have the preemption at function calls, and it works OK. I agree that this isn't much of an issue in practice.


I'm very interested in learning either Go or Rust. Of course I could learn both, but when I learn a new language (or anything really), I like to really immerse myself and focus.

I'm leaning towards Go but Rust is very interesting.


Having spent a fair amount of time with both, I have to say that I would suggest Rust. Go is not a well-designed language. The type system is mediocre, generic support is bad (you have to use interface{}, which is like casting to Object in Java or passing structs/objects around as void*s in C/C++), the language relies heavily on non-extensible built-in constructs like range and make(), etc. I use Go a lot, and I like it for building web services, but I really don't see the advantage for anything else.

Rust, on the other hand, takes a lot of cues from Haskell/ML and is actually a very well designed language with lots of cool features like a hindley-milner based type system with strong generic support, pattern matching, strong support for immutable and functional programming styles, etc.


Web services aren't the only things that run on servers. And nobody is forcing you to use just one tool for all your jobs.


>Web services aren't the only things that run on servers.

Of course not, but web services are the only thing that I think Go is much good for.

>And nobody is forcing you to use just one tool for all your jobs.

Does that mean I'm not allowed to talk about which tools I think are good for what?


Go is like a better Ruby or Python. Rust is like a better C++. Go is ready for production today. Rust will have 1.0 this year, and only has 3 production deployments so far.

Hope that helps.


I'm seeing a lot of "No you're wrong!" responses to this comment. I think they're missing the point.

Most of the projects I come across for Go are for things that traditionally have been in Ruby/Python's camp. Examples of these are web infrastructure and command-line stuff.

Rust, on the other hand, seems like its being used more for things that have been done in C++. i.e. rendering engines and operating systems.

The comment author never stated that Go is better than Ruby/Python. The author points out that a lot of Ruby/Python people have switching over to Go... seemingly more than to Rust.

This isn't a statement for or against either projects worth.


I don't even understand on which base you are comparing Go with Ruby or Python (ok, they are programming languages). Care to explain ?

In my point of view, Go is system oriented, concurrency builtin, compiled, lots-of-braces, few syntax features. It's like the opposite of Python and Ruby.

I would compare Go with Vala, Java and C#.


> It's like the opposite of Python and Ruby.

Exactly. Many people are running into issues with Ruby and Python that Go solves. Tons of Ruby and Python programmers are flocking to Go.

It's not better because it's the same, it's better because it's different.


> Tons of Ruby and Python programmers are flocking to Go.

No they aren't. If they were you would be seeing "tons" of job ads or blog posts. I've seen hardly any.


We must operate in disjoint social circles.


On Australia's largest job site: 331 Ruby, 338 Python and 0 Golang jobs.


Australia and/or job sites is not exactly where new languages first catch on.


I've noticed especially with newer tech is that recruiters will scour github for technologies, maybe examine the code a bit, and then write or call the developer directly. I've had that done to me and I have exactly 0 entries at "job sites".


> Go is like a better Ruby or Python.

Not really as it lacks the expressive power of the said languages.

And if one is looking for execution speed there are alternatives like Cython, PyPy, JRuby and RubyMotion.

For the OP question, if he values a mordern 21st century language, Rust is the way to go, even at pre 1.0.


Go wins over Ruby and Python for many people due to it's speed, tooling, and trivial deployment. A language is more than just expressive power.

I personally don't find Go to be that interesting, but the number of Ruby and Python people who are making re move and are happy with it indicates that I'm an oddball.


What I think is that many moving to Go, do so without trying out other runtimes/compilers available for the said languages.


> Go is like a better Ruby or Python.

I don't think so. Go has its own set of pros/cons just like every other platform. You could equally argue that the huge array of libraries for Ruby and Python would make it "better". And ActiveRecord or Rails alone are major advantages of the Ruby platform.

Personally I see Go being more like Java 1.0. Simple and elegant.


I have a Ruby tattooed on my body, we're in agreement. But we're increasingly becoming a minority opinion. Go is certainly eating away at Ruby and Python's mindshare.


I've only seen more people interested in Ruby over the last few years, and only token interest in Go. I hear a lot more interest in Elixir/Erlang, Rust, Clojure, and Haskell from Rubyists around here than I do for Go.


How is Go a better Python?


I think it's more correct to say that Go is a better C (or perhaps: Pascal) than Python (or Ruby).

A lot of the rewrites I've seen done in Go, could probably have been done in C. The thing is, for lots of problems, Go is a better C than C. You can bolt on lots of safety features on top of C, and I think you could probably be very productive and safe in C if you forgot a lot of the dangerous features that C turns "on by default". It is for example possible to use Pascal strings in C.

I don't think the comparison with Vala (or Nimrod) is too far off -- but the Go team has lots of experience with language and system design -- and I think that really helps Go be a productive tool.


Please see the other three replies I've already typed in this thread.


The fact that you are getting so many "erhm, I don't think so" probably indicates that it wasn't a good comment that promotes discussion.

"Clearly X is better than Y" don't do anything except incite flame wars. You can remedy the situation by explaining and showing in what areas it is better or explain what your experience of seeing the benefits are. Just leaving at "X is better than Y obviously..." that usually doesn't end well.

That is why I asked you why it was better, even thought you already answered it 3 times, because it was another chance to explain why it was better.


>The fact that you are getting so many "erhm, I don't think so" probably indicates that it wasn't a good comment that promotes discussion.

Well, that's because they haven't been following the discussion, on HN and on startup circles, going on for a while.

For one, Go creators' themselves said they expected Go to attract more C++/Java people, but instead they got more Python/Ruby people. And that's like 2 years ago.

For the past year or so, there have been numerous posts about how this or that project/startup switched from Ruby/Python to Go. Last 2 weeks alone there have been around 5 such posts on the front page of Hacker News (Digital Ocean being the latest).

Go is getting increasingly used by people that were doing infastructure/backend work in Python/Ruby etc, e.g people using stuff like Twisted and Tornado, JSON services, etc.

>That is why I asked you why it was better, even thought you already answered it 3 times, because it was another chance to explain why it was better.

Well, I guess he pre-supposed people are already familiar with all the "we rewrote our system in Go and we now have X times better performance, no more gimmicks to get async, etc".


> Go creators' themselves said they expected Go to attract more C++/Java people, but instead they got more Python/Ruby people.

June 25, 2012: http://commandcenter.blogspot.com.br/2012/06/less-is-exponen...


I'm also getting lots of upvotes, too.

Really, it's all anecdata. To be clear, when I say "better," (not "clearly better" as you quoted) I mean "I see lots of people re-writing their Ruby/Python code in Go, and they're very happy with the results." Here's the most recent story I remember: https://news.ycombinator.com/item?id=7628472


If you already know C, it would only take a week or two to learn Go, so it would be quite possible to do both.


one of the point people are trying to make and apparently get misundertood:

1) i need to code something quickly, easily, safely, and i don't care for perf too much:

* i use python2

2) i need low level access, i want to manage object copy or the lack thereof, i want to fine tune memory allocation:

* i use C (or C++)

3) I want something like python, but faster, AOT compiles, with more control:

* i use Go but its not that fast and you can't manage everything

* I use C# but outside windows APIs sucks and AOT doesn't work, and unsafe mode is unsafe

* [...]

* I use rust but the syntax is crazy and its far harder than python or Go

So.. of course, rust may not be targeted at 3) - but instead as a real C++ replacement. Turns out many still want 3 regardless - even thus rust is closer to 3 than C++.


It seems number 3 is all about have solid libraries with a nice interface. If I need an API server that can handle a fair bit of traffic, having a solid, easy-to-use HTTP lib and database lib is going to go a long way. Nothing I see in Rust precludes them from delivering these things.


good API is indeed a necessity - and in my opinion at least 50% of the value of a language is the API - or probably more.

That said, rust is still complex IMO due to both specific idioms and weird/unusual syntax.


What are some things that have been written in rust, besides Servo? I think one of the reasons Go has been so successful is that they started right off the bat with something people could use, and focused on creating tools and other things which encouraged people to dive in. Julia had this too with their math libraries. Things like web servers / frameworks, game engines, parser libraries, command line tools... What is written in rust that I could use to start building actual stuff?


Nice. Similar thing for Golang would be appreciated. I mean more advanced than Go tour.


This was actually inspired by exactly that: http://gobyexample.com/


This is really great and answers many questions I had about details of Rust but was too lazy to google. Thanks!

Btw. the lifetimes example misses syntax coloring.


Rust feels a lot like C++ with smart_ptr/unique_ptr by default, just with a different syntax.

Bad things they imported from C++ :

- Traits (a.k.a. I don't known where this method is implemented).

- Over-complicated and compile-time-specialized generics (feel a lot like templates).

- Copy traits feel a lot like C++ copy constructor (a.k.a. I never known what simple things like assignments or passing an object around will actually do) ( https://rustbyexample.github.io/examples/clone/README.html )

- Explicit allocations (stack vs heap) and ownership management.

Yet they added some bug-provoking things like "The final expression in the function will be used as return value". And crazy syntax rules like "ho, only if the expression is not followed by a ;".


> - Traits (a.k.a. I don't known where this method is implemented).

AFAIK, it's implemented either next to the struct definition or next to the trait definition, I don't think it's possible to implement a trait from one library for a struct from an other library.

> - Over-complicated and compile-time-specialized generics (feel a lot like templates).

No, Rust generics are reified (as are C#'s for instance) but they don't do arbitrary codegen, they're just generics, they're not a turing-complete compile-time metalanguage (that's macros)

> - Explicit allocations (stack vs heap) and ownership management.

Rust's very goal is to take on C and C++ with a better language, the inability to manage allocations would be a non-starter. As for ownership, the language formalises and help keep track of something which is only implied in C or C++, which is a good thing (as it moves ownership issues up, front and center, and thus reduces the likelihood of bugs due to muddled ownership).

Note that Rust has Gc and Rc containers, so you don't have to bother if you want (turns out, people like unique/owned pointers and Gc was moved from "language core" to "library" because it wasn't used that much and ended up cluttering the language for little value)

> Yet they added some bug-provoking things like "The final expression in the function will be used as return value". And crazy syntax rules like "ho, only if the expression is not followed by a ;".

Because it's statically typed, there's no possibility of a runtime bug here: `a` has type `A`, `a;` has type `()`. The compiler will tell you to get bent if you use the wrong one.

All in all, your comments read like you want something at a more abstracted level, you should look at, say, OCaml or Go. Which is fine, just not what Rust aims to provide.


I think promoting Rc and Gc in that way is a little disingenuous, since memory safety permeates the whole design, meaning that you can never just throw memory and mutability around without caring like you can in other languages.

They help solve ownership "problems" but can't paper over the interesting part of Rust: lifetimes and memory safety. (i.e. they stop you having to structure everything as a strictly owned tree, allowing DAGs (with plain Rc) and arbitrary graphs (with Gc and Rc + weak pointers).)

However, unique ownership will always be the thing that's easiest for humans, and more importantly, the compiler to reason about, and so shared data will always be slightly harder to work with than non-shared data.


> I think promoting Rc and Gc in that way is a little disingenuous, since memory safety permeates the whole design, meaning that you can never just throw memory and mutability around without caring like you can in other languages.

I'm not sure why it's disingenuous, Rc and Gc are supposed to be memory safe as well, and as you note their point is simply to not bother with ownership.

> However, unique ownership will always be the thing that's easiest for humans, and more importantly, the compiler to reason about, and so shared data will always be slightly harder to work with than non-shared data.

Which, generally speaking, I'd say is an advantage not a drawback.


I just mean saying "Rust has manual memory management but there's Rc and Gc to save you from that" isn't quite true: the hard part of "memory management" in Rust is convincing the compiler that your lifetimes work out (i.e. it's not doing it correctly that's hard, it's getting the compiler to verify what you've done is correct that's hard), and Rc and Gc don't really help with that, except if you use them everywhere (and the stdlib purposely doesn't use them everywhere, so you will hit lifetimes at some point in your codebase).

> Which, generally speaking, I'd say is an advantage not a drawback.

Of course, but being an advantage doesn't change the fact that Rc/Gc are not a solve-all-your-memory-management-issues tool in Rust.


I think you're in violent agreement with masklinn. His point is your point: it is possible to avoid memory lifetime issues by using garbage collection, but that is not idiomatic Rust, and the design of the language encourages you to reason about memory lifetimes.


I'm not disagreeing with them, yes, but I do think people tout Rust's Rc and Gc (the latter og which doesn't even exist properly yet...) as overly optimistic solutions to escape Rust's variation of "manual" memory management: they don't entirely free you from the shackles of the borrow checker, and even introduce worse lifetime issues (failure at runtime as soon as (certain types of) mutability is required).

That said, the lifetime system make it hard to get things dangerously wrong, so I'm quite happy with the tradeoff Rust offers.


If you use RC and RefCell properly, there shouldn't be dynamic borrow failures any more than there are ConcurrentModificationExceptions in Java or NSEnumeration failures in Objective-C. Sadly most people don't use them very effectively; it seems more work is required to make the right patterns more obvious and easy to use.


Of course, if one uses things right then stuff works fine... It's relying on people to do things right that's tricky (which is why we have Rust).

My point was mainly that you lose much of the compiler's assistance by moving from singly- to multiply-owned data.


(note that dbaupp is a core rust developer[0], if he disagrees with my statements I'm probably missing something somewhere)

[0] https://github.com/mozilla/rust/commits?author=huonw


If you actually believe that, you have not really looked. It adds e.g. algebraic data types, pattern matching, actor based concurrency, it's more functional, has pretty good macros, has the compiler do more heavy lifting etc.

> Explicit allocations and ownership management.

It has optional GC. And it's not like automatic memory management comes at no cost.

The last thing makes sense if you think of a semi-colon as an operator turning an expression into a statement. And since it's typed, it won't let you do something dumb.


> If you actually believe that, you have not really looked. It adds e.g. algebraic data types, pattern matching, actor based concurrency, it's more functional, has pretty good macros, has the compiler do more heavy lifting etc.

My point is that they have borrowed really bad features from C++. Pattern matching, Option, etc are cool; but the C++ features are ruining it, IMO.


It doesn't sound like you are a systems programmer. That, and several of the points you mention lack substance.

> - Explicit allocations (stack vs heap) and ownership management.

This is a great feature. If you're writing another web app, then sure, you don't care about stack vs heap. If you're writing performance oriented code, then you do. Both D and C# allow for a similar mechanism.

> Copy traits feel a lot like C++ copy constructor (a.k.a. I never known what simple things like assignments or passing an object around will actually do)

The assignment operator is not overridable.

> Yet they added some bug-provoking things like "The final expression in the function will be used as return value".

Yet you provide no examples on how this is bug provoking. There have been exactly 0 bugs due to this feature.

In short, it seems that you need to read about Rust in more details before making unbased claims.


> It doesn't sound like you are a systems programmer

> it seems that you need to read about Rust

Please keep personal slights out of HN comments. This comment would be much better without the first and last sentences.


Points taken :)


> > - Explicit allocations (stack vs heap) and ownership management.

> This is a great feature. If you're writing another web app, then sure, you don't care about stack vs heap. If you're writing performance oriented code, then you do. Both D and C# allow for a similar mechanism

Some languages do that for you. Allocating on the stack by default and falling back to the heap when it wouldn't be safe to allocate on the stack. e.g. if the object can outlive the current function call, it shouldn't be allocated on the stack.

If the Rust compiled doesn't known how to spot unsafe stack allocations, then you don't have memory safety.

> > Copy traits feel a lot like C++ copy constructor (a.k.a. I never known what simple things like assignments or passing an object around will actually do)

> The assignment operator is not overridable.

That's not what I said. Operator overloading is yet an other feature that's ruining everything else, though.

> > Yet they added some bug-provoking things like "The final expression in the function will be used as return value".

> Yet you provide no examples on how this is bug provoking. There have been exactly 0 bugs due to this feature.

I may be wrong on this one, since type checking would spot most problem at compile time.


> Some languages do that for you. Allocating on the stack by default and falling back to the heap when it wouldn't be safe to allocate on the stack. e.g. if the object can outlive the current function call, it shouldn't be allocated on the stack.

There are several problems with this approach for systems programming.

1. Escape analysis is conservative. Whenever you have an indirect function call or a call in another module, you have to assume that it will cause a value to escape. By making the lifetime part of the type, Rust can keep values on the stack even when indirect or cross-module functions are involved.

2. When you put a value on the heap, how do you know when to destroy it? All industry languages with escape analysis require a garbage collector, which reduces application throughput in the mark phase. But in Rust, with unique ownership, you can make that information known at compile time in most cases.

3. Not all heaps are created equal. There are many kinds of allocators—thread-local allocators, bump allocators, global allocators, etc.

4. Garbage collectors don't work very well with external libraries that don't use the same memory management scheme. By not requiring a garbage collector or a standard heap, Rust can interoperate better with other languages. For example, you can write libraries in Rust that plug into Ruby with no extra runtime support.

> That's not what I said. Operator overloading is yet an other feature that's ruining everything else, though.

Operator overloading is really important for things like bignums and custom containers like vectors. I think the Rust way of using traits for this (meaning that the operators always have consistent types, and have to be defined in one place) makes it much less confusing than the ad-hoc approach of C++.


Thanks for this insightful answer.

About operator overloading, some languages have seemless bignums without allowing users to overload operators in their own classes. For containers, this could have been restricted to the index operator.


But it's not just about indexes or certain containers. Sure, C++ makes things unwieldy, but the solution is not to drop operator overloading in its entirety. Rust wants to take on C++ head to head. For graphics programming and certain applications, operator overloading makes life a lot easier, and is a very welcome addition.

Take a look at Scala for an arguably worse implementation of operator overloading. Though still, the IDE helps a lot there.


Surely "a + b" is nicer to the eye than "a.add(b)", but unless a and b are numbers, a method call with a meaningful name is more straightforward than any abuse of allowed operators.

> Take a look at Scala for an arguably worse implementation of operator overloading.

Indeed

> Though still, the IDE helps a lot there.

If I need an IDE to understand some code, and tend to stay away from that code/language.


What if a and b are numbers? What if they're matrices? What if they're quaternions -- or higher? What if they're finite fields? Additive groups? Points on an elliptic curve? Random variables?

Operators (+ - * / ^ & | ¬) come from mathematics. While I'm sure there are plenty of node jockeys who have little use for numbers outside of specifying ports, there are still plenty of us for whom operator overloading is a necessary good.


> Some languages do that for you. Allocating on the stack by default and falling back to the heap when it wouldn't be safe to allocate on the stack. e.g. if the object can outlive the current function call, it shouldn't be allocated on the stack.

> If the Rust compiled doesn't known how to spot unsafe stack allocations, then you don't have memory safety.

This seems like a weird thing to say given that the Rust compiler does fairly sophisticated analysis on the lifetime of data. (And yes, Rust has memory safety.)

As a low level language, the programmer decides explicitly what is allocated on the stack and what is on the heap.


Is there many cases where it's safe to allocate an object on the stack, but you would want to allocate it on the heap instead ? (Appart from the the object being too big.)


As I said, it's about making costs explicit. Otherwise, you're relying on the compiler's escape analysis to choose whether to allocate something on the heap or the stack. A programmer might not realize that something escapes, and thus, there is a heap allocation that the programmer thought was a stack allocation.

It's worth something to be able to say, "put this on the stack dammit" and if it can't go on the stack safely, require that the compiler yell at you.


We needed those features--explicit memory management, for example--to write a browser engine, and we know others need those features too. (For example, game developers are really not OK with a language that hides the distinction between the stack and the heap.)


It sounds to me like you don't want a low-level programming language. That's totally fine! Rust isn't going to be amazing for everything.


Depending on what I'm doing, I do want a low-level language. Still, Rust's memory management feels weird and painful.

But above that I'm criticising features such as operator overloading, overridable copy semantics, and traits.


Rust explicitly doesn't allow overriding `=`.

Rust doesn't have templates, but rather parametric polymorphism and traits are part of that, they are used exactly like typeclasses in Haskell.

Static typing means a dropped semicolon never introduces a bug (a meaningfully forgotten semicolon almost always results in a compile error, I've never met a problem).


> Rust explicitly doesn't allow overriding `=`.

In part 25 Copy and clone: "copied by default instead of moved, because these types implement the Copy trait"

So implementing the Copy trait allow to modify the semantics of assigning an object to a variable, or of passing the object around; am I right ? Feels a lot like C++'s copy constructor.

> Rust doesn't have templates, but rather parametric polymorphism and traits are part of that

This is just an other name for templates.

> Static typing means a dropped semicolon never introduces a bug

Using the last expression as return value feels weird in a language that makes everything so uber-explicit, like ownership, stack vs heap allocation, etc


Copy is a trait that is automatically implemented by the compiler (and cannot be manually overridden) that basically just says "semantically this type can be copied with memcpy", it doesn't actually control the runtime behaviour of =. Passing around a Copy type by-value leaves the source still usable ("a copy"), any other type leaves the source unusable at compile-time ("a move"); assignment is just a normal by-value use of the right-hand side. (The phrasing in that section isn't as clear as it could be.)

They are templates with checking at the declaration, not the instantiations, so you don't get the errors nested deep inside libraries with ridiculous chains of messages.

Don't knock the semicolon thing until you try it, it's actually pretty nice. :)


> Copy is a trait that is automatically implemented by the compiler (and cannot be manually overridden) that basically just says "semantically this type can be copied with memcpy", it doesn't actually control the runtime behaviour of =. (The phrasing in that section isn't as clear as it could be.)

That's a very good news. Indeed that section is not clear, it looks like user defined classes could implement the copy trait, which would be really bad.

Thanks for your answers.


(BTW, I edited some more details about copy vs. move into my previous comment just after you replied.)


I haven't dealt much with c++ templates but they are fully turing complete. I believe rust generics are weaker and more like java. In c++ templates try to see if a type can be used in a function. In rust you can only use a function if the type fulfils a trait which seems a lot like generic constraints in java/c#.

I don't think making things explicit is a goal of rust. Making things safe as possible by default while being fas is. A good example is that most local variables are type inferenced rather then declared.


Making _costs_ explicit is a goal of Rust. Stack allocation is syntactically cheaper than heap allocation, for example.


Sadly, operator overloading is not a really good way of making costs explicit.


What do people use to write Rust? Seems like it would really make the most of good editor/IDE support.


We have a lot of vim and emacs people, and an IDE crew too. I personally use vim. I think there's even a Kate file in the source tree?

There's been lots of effort to make sure Rust's grammar stays simple enough to have great IDE support eventually, so as the language matures, hopefully we'll see it supported in a lot of them.


Emacs for me.


Well that's exciting. I had been waiting for precisely such a tutorial for rust.


Rust looks like a marriage between Java and C. Very interesting.

There's some error on this page. https://rustbyexample.github.io/examples/lifetime/README.htm... The syntax highlight doesn't work. EDIT: And https://rustbyexample.github.io/examples/constants/README.ht... too


> Rust looks like a marriage between Java and C. Very interesting.

Where do you get Java from? It's more of a marriage between C and ML, but it has drawn inspiration from numerous other sources.


Generics mostly, the syntax is the same. Structs with associated methods are a rudimentary form of classes.

I have to say I'm not a programmer nor I've studied Computer Science, more a Script Kiddie, and functional languages are something esoteric that I understand on a very shallow way.


> Generics mostly, the syntax is the same.

That's the syntax for "generics in C-like languages" since C++, FWIW. So at its core, the inspiration there is probably C++ more than it is Java.


Well, you're not wrong--Java's generics and Rust's generics were very influenced by ML's. So really you're seeing the ML influence :)

(Though Rust's generics really borrow more from those of Haskell, since it has more fully-featured typeclasses as opposed to just eqtypes like SML.)



What kind of application is Rust well-suited for?


Pretty much everywhere where you see C/C++ i'd say. So not in your browser, but everywhere else.


>So not in your browser, but everywhere else.

Not in the browser now, but I think Rust will make a very nice compile-to-JS language with Emscripten. And this will likely be possible in the not-to-far future given how relative easy it will be to implement with LLVM.

That said, Rust's primary uses will probably be "systems programming", game dev, embedded programming, and other real-time programming.


Really naive question: might it be possible to bridge Rust to some older language's high content, well developed library?


Rust can use C libraries pretty easily, and there's a tool to autogenerate Rust `extern` declarations from C headers: http://static.rust-lang.org/doc/master/guide-ffi.html https://github.com/crabtw/rust-bindgen


I feel like they should have named the compiler 'rustic'.


Even better, 'crust'


All we need now is a GUI library and we'll be set.


does anyone know the coloscheme used in the snippets ?


It's using highlight.js, but doesn't seem to be one of the default styles. [0] Maybe it's custom?

[0]: http://highlightjs.org/static/test.html


By the way, this was done with what? It look great.



Is it only me or the comments are completely unreadable due to their color? I need to highlight them to read properly




Registration is open for Startup School 2019. Classes start July 22nd.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: