Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

A selection of some of my favorite aspects of this release:

1. The (yet-ongoing) removal of managed pointers, leaving us with one fewer pointer type. Final tally of built-in pointer types: unique pointers, mutable references, and immutable references.

2. The dead code detection pass (https://github.com/mozilla/rust/pull/10477), contributed by a student of the University of Virginia's Rust-based systems programming class (http://rust-class.org/pages/using-rust-for-an-undergraduate-...).

3. The `Any` trait, giving us on-demand dynamic typing (https://github.com/mozilla/rust/pull/9967).

4. The clean abstraction of green threads and native threads out into their own libraries (https://mail.mozilla.org/pipermail/rust-dev/2013-December/00...) such that any library that makes use of the stdlib will work regardless of which strategy the user selects.

We're not quite in the home stretch yet, but there are very few hard blockers left on 1.0. Here's the list that I can think of:

1. Dynamically-sized types (http://smallcultfollowing.com/babysteps/blog/2014/01/05/dst-...)

2. The extension of rvalue lifetimes (http://smallcultfollowing.com/babysteps/blog/2014/01/09/rval...)

3. Struct single (note that's single) inheritance (http://smallcultfollowing.com/babysteps/blog/2013/10/24/sing...)

4. Niceties and sugar to support custom smart pointer types to complete the excision of managed pointers

As far as I know, the devs are still aiming for a 1.0 release in 2014. The 1.0 release will not necessarily mean that the language is done evolving or ready for production use, but it will mean that the developers will begin honoring language-level and library-level backwards compatibility. I would expect at least two more unstable point releases (i.e. 0.10 and 0.11) before a 1.0 release occurs.



Excellent. It was the multitude of different pointer types that confused me the most, so it's great to hear that they are simplifying this.


My guide got merged in for this release: http://static.rust-lang.org/doc/0.9/guide-pointers.html

TL;DR: you don't need them as much as you may think, so don't let that scare you away!


Inheritance may not make 1.0.


I'm finding that my OO code style these days is very composition heavy with pretty much no inheritance use. I think given Rust's type system, I'm not going to miss inheritance much.


I believe Rust wants inheritance primarily for Servo, because the DOM is defined in terms of inheritance.


Right. Idiomatic Rust prefers composition over inheritance.


Every language in the universe prefers composition over inheritance =P


Not very true.

Some languages prefer inheritance to express is-a relationships and composition to express has-a relationships. Some languages try to shoe horn is-a into being equivalent to has-a, but they usually have trouble expressing non-structural subtyping.


I find that when refactoring code, I often redefine is-a to has-a anyway.


is-a vehicle --> has 4 wheels


Runtime error: Motorcycle lacks 4 wheels


The ones that don't blossom into interface factories which make factory adapters of abstract factories. (I'm looking at you, Java)


For the lack of a nail, throw new HorseshoeNailNotFoundException("no nails!");

For the lack of a horseshoe, EquestrianDoctor.getLocalInstance().getHorseDispatcher().shoot();

(...)

http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom...


If that is the only use case I would rather want another solution to keep the language minimal. Just like the garbage collection was moved to a library.


Can't really do it. I tried. The type checker just plain has to know about inheritance for it to work and be safe.

The good news is that's an extremely constrained sort of inheritance, very unlike traditional OO in that it doesn't have base classes--it's just a special extension to the trait (typeclass) system that allows you to require that structs begin with a certain set of fields. In fact, I don't even call it inheritance these days--I prefer the name "structural constraints".


ooh, is this like record subtyping? Have you seen ermine https://github.com/ermine-language or Ur/web? http://www.impredicative.com/ur/

[edit, on #rust it was explained to me that its only for pointers to structs, but thats fine by me]


If anyone is interested, the proposal for Rust is detailed in http://smallcultfollowing.com/babysteps/blog/2013/10/24/sing...


I think this is a good idea. It seems similar to Go's embedding: http://golang.org/doc/effective_go.html#embedding


The difference is that the base struct can call methods on the derived struct, whereas this is not possible with that kind of struct embedding. This is important for some use cases (e.g. the DOM or the render tree).


I see.


Thanks for the answer, and I think I like your solution to the problem.


I think that the core team thought about this long and hard, but it was decided that there was no other solution. A virtual method call to look up some property shared by all the DOM nodes was just too expensive: a constant offset field look up is far far faster.


Just because people have overused inheritance in the past doesn't mean it's completely useless.


Nobody has said it was useless.

Although with the right language support, it is useless, composition can stand for it (demo: Self)


By that reasoning most programming features are useless (demo: C)


I'm reasonably certain you completely misunderstood my comment, because C definitely isn't an illustration of it.


It's a question of performance more than composition.


Please elaborate?


Ah, news to me. I guess it can be introduced without breaking backwards-compatibility.


As someone who writes a lot of C++ and has played with Rust (ie, hello world) how does the language work when you remove shared pointers?

Say I have an early-generated state tracker for a whole bunch of events propagating in an event loop somewhere, that I want discarded when all the events finish. They are all separate tasks in different threads, so I either need to have some job that just checks if they all finish to clean up, or pass around shared data structures. How would you do that in Rust?


I actually make it a point to do most of my code without shared_ptr, opting instead for unique_ptr. There was a talk somewhere about the "best written library you should never use" and shared_ptr was the focus.

For the example you mentioned, you could have the parent object of those tasks responsible for cleanup of the shared object (e.g. each thread's destructor calls a finish function on the parent object). This is just one possible implementation. I don't encounter this as much because I prefer a shared-nothing approach where possible.

edit:typo


If the structure is immutable after you've produced it, you can use extra::arc::Arc<T> [0], and once all the references are dropped the memory will be deallocated. I haven't used C++, so this might be very similar to std::shared_ptr or not, but this is usually what one would use in Rust. (There's also extra::arc::RWArc<T> [1] when you need mutability, but that isn't used much in my experience.)

[0] http://static.rust-lang.org/doc/master/extra/arc/struct.Arc.... [1] http://static.rust-lang.org/doc/master/extra/arc/struct.RWAr...


Documenting Rust must be a major pain.


Disclaimer: I've written a bunch of it.

It's actually not too bad. The biggest problem with the docs currently is that it's a patched-together set of things people have written at random over the last few years. Mozilla has taken some concrete steps to address this, it'll be much better overall soon.


Sorry, I was making a joke about how Rust changes a lot. You guys do great work considering.


Ha, no worries. Thanks!


This release also heralds the ability for the built-in documentation generator to run any code examples, which has helped us keep the documentation up-to-date a lot.


Aren't unique pointer also scheduled for decommission?


No, not at all. Unique pointers are awesome and are the foundation for lots of other features.

Now, some of the syntax for using them might still change. That's yet to be decided. But it wouldn't be Rust without unique pointers.


Are "unique pointers" == "owned pointers"?


Sorry about the confusion, I just translate ~T as a Uniq<T> because they are unique (i.e. you can't use them without cloning) and they were called like that on a mailing list a few times (IIRC).


Yes, ~T.


Undecided. They will always be somewhat magical in that the "box" operator creates them by default. But the syntax for them may change, or be moved into the library.


You can put a pointer type into a library?


Everything except the two reference types (& and &mut) can be trivially implemented in libraries: Rust is a low level language.

E.g. the following is almost exactly identical to `~T`

  #[unsafe_no_drop_flag]
  struct Uniq<T> { priv ptr: *mut T }

  impl<T> Uniq<T> {
      fn new(value: T) -> Uniq<T> {
          unsafe {
              let ptr = malloc(size_of::<T>()) as *mut T;
              if ptr.is_null() { fail!("malloc failed"); }

              move_val_init(&mut *ptr, value);
              Uniq { ptr: ptr }
          }
      }

      fn borrow<'a>(&'a self) -> &'a T {
          unsafe {&*self.ptr}
      }
      fn borrow_mut<'a>(&'a mut self) -> &'a mut T {
          unsafe {&mut *self.ptr}
      }
      fn move(mut self) -> T {
          unsafe {
              let v = ptr::read_ptr(self.ptr as *T);
              free(self.ptr);
              self.ptr = 0;
              v
          }
      }
  }
  #[unsafe_destructor]
  impl<T> Drop for Uniq<T> {
      fn drop(&mut self) {
          unsafe {
              // this will free the pointer and run the 
              // destructor of the inner type
              replace(self, transmute(0)).move();
          }
      }
  }


Rc and Gc are now libraries you can import. A nice advantage is that Arc, MutexArc and any other reference types look and work the same way.




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

Search: