Re: [rust-dev] Question about lifetime analysis (a 0.5 transition question)

2013-01-10 Thread Steve Jenson
On Sun, Dec 30, 2012 at 1:16 PM, Niko Matsakis  wrote:

> Oh, one other thing:
>
> Your each() method does not obey the for protocol!  When the callback
> returns false, you should abort iteration altogether.  This presumably
> means you need to do the recursion in a helper method that itself returns
> bool so that you can detect when to carry on and when to abort.
>

Thanks for pointing that out, I didn't realize. I'm working on making each
abortable but noticed that I'm not able to call a function defined in an
anonymous impl from this method, there's an interaction with &self here
that I don't understand.

Here is the error:

red_black_tree.rs:107:8: 107:32 error: type
`&self/red_black_tree::RBMap<'a,'b>` does not implement any method in scope
named `real_each`
red_black_tree.rs:107 self.real_each(f, true);

Here is the call site:
https://github.com/stevej/rustled/blob/master/red_black_tree.rs#L107

And here is the definition of the function real_each:
https://github.com/stevej/rustled/blob/master/red_black_tree.rs#L61

Do you understand what is going on here?

Thanks,
Steve
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Question about lifetime analysis (a 0.5 transition question)

2012-12-28 Thread Steve Jenson
On Thu, Dec 27, 2012 at 3:16 PM, Niko Matsakis  wrote:

> I'm sorry for not replying more quickly, I was not checking e-mail over
> xmas break.  I do not know of any general problems with @ and borrowing.
> In any event, this is a misdiagnosis.
>

No problem with reply timing.



>  The problem is this: the declaration of iter looks like this:
>
>  impl RBMap: iter::BaseIter<(&K, &V)>
>
> In the context of a type declaration, an & means `&self`, where `self` is
> the lifetime parameter associated with the type/impl/whatever (just as the
> impl has two type parameters K and V, it also has an implicit lifetime
> parameter `self`).  So, this declaration written out more explicitly would
> be:
>
> impl RBMap: iter::BaseIter<(&self/K,
> &self/V)>
>
> However, your method declaration is:
>
> pure fn each(&self, f: fn(&(&K, &V)) -> bool) { ... }
>
> In the context of a function declaration, & means "a fresh lifetime".  So
> this winds up being short for a declaration life this:
>
> pure fn each(&self, f: fn(&a/(&a/K, &a/V)) -> bool) { ... }
>
> However, the trait declares that `each` should have this type:
>
> pure fn each(&self, f: fn(&a/(&self/K, &self/V)) -> bool) { ... }
>
> So I think that if you change your declaraiton of `each()` to:
>
> pure fn each(&self, f: fn(&(&self/K, &self/V)) -> bool) { ... }
>
> It will work just fine.  I apologize for the cryptic error message.
> Working on it.
>

Unfortunately not but a much more interesting set of error messages about
lifetimes is coming out now: http://pastebin.com/SYwCw1ac

And here is a link to the each method again (I pushed this broken version
to github so I can share the exact changes I made)

https://github.com/stevej/rustled/blob/master/red_black_tree.rs#L96

Thanks a bunch for all of your clarifying comments and blog posts.

Steve
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Question about lifetime analysis (a 0.5 transition question)

2012-12-23 Thread Steve Jenson
That explanation makes sense, it seems like the lifetime analysis improved
from 0.4 (where this code worked) to 0.5?

Since it seems that you can't use borrowed pointers to shared heap items in
an arglist, I went ahead and created a new type of iter called BareIter.

trait BareIter {
  pure fn each(&self, blk: fn(v: A) -> bool);
}

and converted my use of BaseIter to BareIter.

On Sat, Dec 22, 2012 at 10:42 AM, Lucian Branescu  wrote:

> I think the problem is the compiler can't guarantee the managed box will
> survive, so it won't allow a borrowed pointer.
>
> I think there are problems in general with @ and borrowing.
>  I've converted the red-black tree I wrote to use iter::BaseIter but am
> now fighting with lifetime analysis with the switch to 0.5.
>
> https://github.com/stevej/rustled/blob/master/red_black_tree.rs#L91
>
> And the error I'm getting with 0.5 is:
>
> http://pastebin.com/YK8v7EdA
>
> I've read the docs on lifetimes several times now but it's not quite
> enough to get me over this hurdle.
>
>
> Thanks!
> Steve
>
> ___
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>
>
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Request for feedback

2012-12-23 Thread Steve Jenson
On Fri, Dec 7, 2012 at 12:54 PM, Patrick Walton  wrote:

> On 12/7/12 11:58 AM, Steve Jenson wrote:
>
>> Hi rust gurus,
>>
>> Today I ported the purely functional Pairing Heap found in Okasaki's
>> Purely Functional Data Structures to Rust. I was hoping that some of you
>> might take a look at it and give me feedback on where I could be using
>> Rust's idioms better.
>>
>> https://github.com/stevej/**rustled/blob/master/pairing_**heap.rs<https://github.com/stevej/rustled/blob/master/pairing_heap.rs>
>>
>> The code I wrote is a little longer than Okasaki's example, mostly due
>> to Standard ML's more concise pattern matching. (see page 54 for
>> comparison) Is there a way to do pattern matching in argument lists as
>> in Haskell or SML?
>>
>
> Yes, in Rust 0.5 this works.
>
> I noticed several things:
>
> * Using explicit self (&self) will help make your levels of indirection
> consistent between `self` and `other` in a few functions. This works better
> in 0.5 than it does in 0.4.
>
> * Braces aren't necessary after the => in patterns unless you want
> multiple statements.
>
> * I'm confused as to why you need an @record as your type in PairingHeap_
> (note that records are deprecated in favor of structs). In Rust 0.5 you can
> say
>
> pub enum PairingHeap {
> Empty,
> PairingHeapCell {
> head: E,
> rest: @List>
> }
> }
>
> * You can use "self" as the return value in a trait.
>
> * In 0.5 you can use #[deriving_eq] for your enum to avoid writing the Eq
> definition, although I'm not sure that works for struct-like enum variants
> as in PairingHeapCell above (I should check this).
>

Unfortunately, deriving_eq doesn't work for this enum (the same error is
reported 3 times):

rustc -g -o bin/algorithms --lib crate.rc
pairing_heap.rs:14:0: 15:3 error: instantiating a type parameter with an
incompatible type (needs `copy`, got ``, missing `copy`)
pairing_heap.rs:14 #[deriving_eq]
pairing_heap.rs:15 pub enum PairingHeap {
pairing_heap.rs:14:0: 15:3 error: instantiating a type parameter with an
incompatible type (needs `copy`, got ``, missing `copy`)
pairing_heap.rs:14 #[deriving_eq]
pairing_heap.rs:15 pub enum PairingHeap {
pairing_heap.rs:14:0: 15:3 error: instantiating a type parameter with an
incompatible type (needs `copy`, got ``, missing `copy`)
pairing_heap.rs:14 #[deriving_eq]
pairing_heap.rs:15 pub enum PairingHeap {
error: aborting due to 3 previous errors
make: *** [all] Error 101

Best,
Steve
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] how to call closures stored in struct slots (a 0.5 question)

2012-12-22 Thread Steve Jenson
Yes, that's it!

Are these migration-related questions suited for this list or should I use
github issues?

thanks again,
steve


On Sat, Dec 22, 2012 at 10:28 AM, Tim Chevalier wrote:

> On Sat, Dec 22, 2012 at 10:27 AM, Steve Jenson 
> wrote:
> > In 0.4, I had a struct that stored a fn that I later called as if it
> were a
> > method. In 0.5, this has ceased. what is the new syntax for calling
> > functions stored in slots?
> >
> > Here's the small code example (please excuse how naive it is):
> >
> > https://github.com/stevej/rustled/blob/master/lazy.rs#L28
> >
> > and here is the 0.5 compiler error I receive:
> >
> > lazy.rs:28:21: 28:33 error: type `lazy::Lazy<'a>` does not implement any
> > method in scope named `code`
> > lazy.rs:28 let result = self.code();
>
> (Warning: not tested.) I believe the way to do this is to write:
>
> let result = (self.code)();
>
> Cheers,
> Tim
>
>
>
> --
> Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt
> "We know there'd hardly be no one in prison / If rights to food,
> clothes, and shelter were given." -- Boots Riley
>
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Question about lifetime analysis (a 0.5 transition question)

2012-12-22 Thread Steve Jenson
I've converted the red-black tree I wrote to use iter::BaseIter but am now
fighting with lifetime analysis with the switch to 0.5.

https://github.com/stevej/rustled/blob/master/red_black_tree.rs#L91

And the error I'm getting with 0.5 is:

http://pastebin.com/YK8v7EdA

I've read the docs on lifetimes several times now but it's not quite enough
to get me over this hurdle.


Thanks!
Steve
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] how to call closures stored in struct slots (a 0.5 question)

2012-12-22 Thread Steve Jenson
In 0.4, I had a struct that stored a fn that I later called as if it were a
method. In 0.5, this has ceased. what is the new syntax for calling
functions stored in slots?

Here's the small code example (please excuse how naive it is):

https://github.com/stevej/rustled/blob/master/lazy.rs#L28

and here is the 0.5 compiler error I receive:

lazy.rs:28:21: 28:33 error: type `lazy::Lazy<'a>` does not implement any
method in scope named `code`
lazy.rs:28 let result = self.code();

Thanks,
Steve
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] purely function red-black tree

2012-12-18 Thread Steve Jenson
On Sat, Dec 15, 2012 at 7:15 PM, Patrick Walton  wrote:

> On 12/15/12 4:38 PM, Steve Jenson wrote:
>
>> I could use advice here. Is it possible for me to write a single trait
>> that can be used by both users that want to use managed boxes and people
>> who wish otherwise? IOW, what is the best way to abstract away the @sign
>> in this trait?
>>
>
> It depends on how you implement the red-black tree. With your current
> implementation, I think you're probably going to have to expose the GC to
> the user, because that implementation of red-black trees doesn't do manual
> memory management. There's no real way to abstract over methods of
> automatic storage reclamation in general (and adding such a mechanism would
> be pretty complex).
>
> If you're OK with having get() copy out the value instead of returning a
> reference to it, then you could avoid exposing the GC to the user, at the
> cost of copying every value you put in (which is not as bad as it sounds,
> since the cost of a copy of an @ box is practically zero). However, if you
> modify the algorithm to use unique pointers throughout, then your methods
> like get() can probably return a borrowed pointer instead.


I'll tackle this within the next few days, once I understand send_map
better. Thanks!
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] purely function red-black tree

2012-12-18 Thread Steve Jenson
On Mon, Dec 17, 2012 at 11:28 AM, Graydon Hoare  wrote:

>
> Nice! The only things I'd ask are:
>
>   - I can't tell at a glance (sorry, RB-trees are always very subtle)
> whether this is an LLRB. If not, could you make it so? It's likely
> just a simplification to a couple of the functions.
>

I rewrote it to be left-leaning and was able to remove a bunch of code.
Thanks for the suggestion.

  - Would you mind, once all feedback is incorporated, if we pull this
> into the stdlib? We have a bug open discussing cleanup and
> (re)organization of the container types, fwiw, over here:
>
> https://github.com/mozilla/rust/issues/3863
>
> Thanks for taking an interest in this.
>

I'd be thrilled for that. Plenty of feedback to accept first, though.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] purely function red-black tree

2012-12-18 Thread Steve Jenson
On Mon, Dec 17, 2012 at 11:46 AM, Graydon Hoare  wrote:

> On 12-12-17 11:28 AM, Graydon Hoare wrote:
> > On 12-12-14 03:51 PM, Steve Jenson wrote:
> >> I recently ported Matt Might's Scala port of Okasaki's purely functional
> >> red-black tree to Rust and am looking for some feedback.
> >>
> >> https://github.com/stevej/rustled/blob/master/red_black_tree.rs
> >>
> >> I've written this for 0.4 and will update it with other feedback I've
> >> received for 0.5 when that lands.
> >
> > Nice! The only things I'd ask are:
> >
> >   - I can't tell at a glance (sorry, RB-trees are always very subtle)
> > whether this is an LLRB. If not, could you make it so? It's likely
> > just a simplification to a couple of the functions.
>
> Er, except of course, there's also:
>
>   https://github.com/fawek/llrbt.rs
>
> I think we need some better coordination of library development :)
>

That's a mutable LLRB tree whereas mine is immutable.

Since the language provides optional mutability, is it a goal to have both
pure functional and mutable versions of common data structures and traits?
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] purely function red-black tree

2012-12-18 Thread Steve Jenson
Thanks, I started with this definition and implemented BaseIter for my
RBTree.

https://github.com/stevej/rustled/commit/85cf4340eb1c0b985e27a48fe2603e6b75ffcb45

size_hint returns None as I'm not tracking size. I think that's ok? It's
hard to tell from the BaseIter documentation.


On Mon, Dec 17, 2012 at 1:34 PM, Erick Tryzelaar
wrote:

> Is it important for `traverse` to pass along an option type? Is it
> important to inform end users that a key has been deleted? Or is that
> implementation specific? If so, I suggest rewriting `traverse` to something
> like this (assuming this actually works):
>
>
>
> impl RBMap: iter::BaseIter<(&K, &V)> {
>
>
>   pure fn each(f: fn(&(&K, &V))) {
> match *self {
>
>
>   Leaf => (),
>   Tree(_, left, ref key, maybe_value, right) => {
>
>
> left.traverse(f);
> match maybe_value {
>
>
>   Some(ref value) => f(&(key, value)),
>   None => {},
>
>
> }
> right.traverse(f);
>   }
>
>
>
> }
>   }
> }
>
>
>
>
> On Mon, Dec 17, 2012 at 11:46 AM, Graydon Hoare wrote:
>
>> On 12-12-17 11:28 AM, Graydon Hoare wrote:
>> > On 12-12-14 03:51 PM, Steve Jenson wrote:
>> >> I recently ported Matt Might's Scala port of Okasaki's purely
>> functional
>> >> red-black tree to Rust and am looking for some feedback.
>> >>
>> >> https://github.com/stevej/rustled/blob/master/red_black_tree.rs
>> >>
>> >> I've written this for 0.4 and will update it with other feedback I've
>> >> received for 0.5 when that lands.
>> >
>> > Nice! The only things I'd ask are:
>> >
>> >   - I can't tell at a glance (sorry, RB-trees are always very subtle)
>> > whether this is an LLRB. If not, could you make it so? It's likely
>> > just a simplification to a couple of the functions.
>>
>> Er, except of course, there's also:
>>
>>   https://github.com/fawek/llrbt.rs
>>
>> I think we need some better coordination of library development :)
>>
>> -Graydon
>>
>> ___
>> Rust-dev mailing list
>> Rust-dev@mozilla.org
>> https://mail.mozilla.org/listinfo/rust-dev
>>
>
>
> ___
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>
>
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] purely function red-black tree

2012-12-18 Thread Steve Jenson
On Sat, Dec 15, 2012 at 7:02 PM, Nathan  wrote:

>  > Also, traverse should probably belong in its own trait.
> >
>
> It seems like traversal over keys *and* values is quite useful,
> because it's common for applications to need both, and doing a
> separate lookup when a traversal is already "close to" the value would
> be a shame (changing asymptotic bounds on some applications).
>
> There is already an Iter trait.  Is traversal simply an Iter over
> either K or (K, V) ?


Thanks, I converted my code to implement BaseIter (although my
implementation of size_hint  is a little hacky since I'm not tracking the
size of the tree)


> > The private methods are part of the RBMap specialization of the Map trait
> > and are required to reduce boilerplate. They don't belong in a Map trait
> > proper.
> >
>
> The rust way to do this is to have the trait methods call helper
> functions which are in scope, but not attached to the trait, I
> believe.


Aha, that helps things click for me.

Thanks again,
Steve
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] purely function red-black tree

2012-12-15 Thread Steve Jenson
On Sat, Dec 15, 2012 at 8:58 AM, Benjamin Striegel
wrote:

> Would this trait:
>
> pub trait Map {
>   pure fn get(k: K) -> @Option;
>   pure fn put(k: K, v: V) -> self;
>   pure fn delete(k: K) -> self;
>   pure fn traverse(f: fn((&K), (@Option)));
> }
>
> be something that ought to live somewhere in the standard library?
>

I just renamed it to PersistentMap as a mutable Map would not typically
return itself on modification, that's a hallmark of a functional persistent
data structure.

Also, traverse should probably belong in its own trait.



> I also see that you have an impl of this trait in which you also define a
> bunch of methods that don't belong to the trait. I didn't even know that
> was possible! If you feel that those methods (blacken, modifiedWith,
> balance, modWith) don't belong in the Map trait, perhaps split their
> definitions off into a separate "anonymous" impl for now, and then when 0.5
> rolls around you can define a trait that inherits from the Map trait and
> requires those additional methods.
>

The private methods are part of the RBMap specialization of the Map trait
and are required to reduce boilerplate. They don't belong in a Map trait
proper.

There's a design choice here about implementations of traits that isn't
clear to me. Why restrict any given implementation of them to publicly
defined methods?

Also, can you show me an example of using an anonymous trait? That seems
neat.

Best,
Steve
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] purely function red-black tree

2012-12-15 Thread Steve Jenson
On Sat, Dec 15, 2012 at 11:46 AM, Patrick Walton wrote:

> On 12/15/12 8:58 AM, Benjamin Striegel wrote:
>
>> Would this trait:
>>
>>  pub trait Map {
>>pure fn get(k: K) -> @Option;
>>pure fn put(k: K, v: V) -> self;
>>pure fn delete(k: K) -> self;
>>pure fn traverse(f: fn((&K), (@Option)));
>>  }
>>
>> be something that ought to live somewhere in the standard library?
>>
>
> Yes, probably, although it shouldn't have @s in it for the benefit of
> those who don't want to use the garbage collector.


I could use advice here. Is it possible for me to write a single trait that
can be used by both users that want to use managed boxes and people who
wish otherwise? IOW, what is the best way to abstract away the @sign in
this trait?


>  I also see that you have an impl of this trait in which you also define
>> a bunch of methods that don't belong to the trait. I didn't even know
>> that was possible!
>>
>
> It's not possible in 0.5.


What is the rationale for making this impossible?

Thanks,
Steve
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] purely function red-black tree

2012-12-14 Thread Steve Jenson
I recently ported Matt Might's Scala port of Okasaki's purely functional
red-black tree to Rust and am looking for some feedback.

https://github.com/stevej/rustled/blob/master/red_black_tree.rs

I've written this for 0.4 and will update it with other feedback I've
received for 0.5 when that lands.

Thanks!
Steve
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Request for feedback

2012-12-08 Thread Steve Jenson
On Fri, Dec 7, 2012 at 12:54 PM, Patrick Walton  wrote:

> On 12/7/12 11:58 AM, Steve Jenson wrote:
>
>> Hi rust gurus,
>>
>> Today I ported the purely functional Pairing Heap found in Okasaki's
>> Purely Functional Data Structures to Rust. I was hoping that some of you
>> might take a look at it and give me feedback on where I could be using
>> Rust's idioms better.
>>
>> https://github.com/stevej/**rustled/blob/master/pairing_**heap.rs<https://github.com/stevej/rustled/blob/master/pairing_heap.rs>
>>
>> The code I wrote is a little longer than Okasaki's example, mostly due
>> to Standard ML's more concise pattern matching. (see page 54 for
>> comparison) Is there a way to do pattern matching in argument lists as
>> in Haskell or SML?
>>
>
> Yes, in Rust 0.5 this works.
>
> I noticed several things:
>
> * Using explicit self (&self) will help make your levels of indirection
> consistent between `self` and `other` in a few functions. This works better
> in 0.5 than it does in 0.4.
>
> * Braces aren't necessary after the => in patterns unless you want
> multiple statements.
>
> * I'm confused as to why you need an @record as your type in PairingHeap_
> (note that records are deprecated in favor of structs).


I'm still learning how things are done in Rust, I cribbed the @record
inside an enum variant from libcore/dlist.rs (see DList). The library code
has been a treasure trove of ideas but the downside is that it can be hard
to form a coherent picture of how things are meant to be used in the latest
version of the language.

I switched to PairingHeapCell(E, @List>) which has the
benefit of working better with pattern matching.


In Rust 0.5 you can say
>
> pub enum PairingHeap {
> Empty,
> PairingHeapCell {
> head: E,
> rest: @List>
> }
> }
>

That looks much nicer.


* You can use "self" as the return value in a trait.
>

Oh, that's just what I wanted!


> * In 0.5 you can use #[deriving_eq] for your enum to avoid writing the Eq
> definition, although I'm not sure that works for struct-like enum variants
> as in PairingHeapCell above (I should check this).
>
> * @ signs are required for pattern matching because pattern matching never
> dereferences through pointers implicitly.
>


> * You have a bunch of "return" expressions in which "return" can be left
> off.
>

Tom pointed out to me that a semi-colon at the end of an expression turns
it into a statement which is why I had switched to return statements. I'm
glad to see I can leave off both the semi-colon and the return and just use
an expression.



> * Some of your if statements could be replaced with pattern guards.
>
> * is_empty() could just be:
>
>pure fn is_empty(&self) -> bool { *self == Empty_ }
>

Great, thanks a bunch for all this useful feedback, both to you and
Benjamin. Anything that worked with 0.4 I switched to, the rest I'll do
after 0.5 lands.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Request for feedback

2012-12-07 Thread Steve Jenson
Hi rust gurus,

Today I ported the purely functional Pairing Heap found in Okasaki's Purely
Functional Data Structures to Rust. I was hoping that some of you might
take a look at it and give me feedback on where I could be using Rust's
idioms better.

https://github.com/stevej/rustled/blob/master/pairing_heap.rs

The code I wrote is a little longer than Okasaki's example, mostly due to
Standard ML's more concise pattern matching. (see page 54 for comparison)
Is there a way to do pattern matching in argument lists as in Haskell or
SML?

Thanks!
Steve
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Questions about rust's OO.

2012-08-26 Thread Steve Jenson
On Sun, Aug 26, 2012 at 6:45 PM, Tim Chevalier  wrote:
> On Sun, Aug 26, 2012 at 6:33 PM, Steve Jenson  wrote:
>> Hi rustics,
>>
>> I spent some time this weekend going over the rust tutorial and
>> documentation for 0.3.1. I thought a fun exercise would be writing an
>> xUnit testing framework[1] in a "classic" OO style. I ran into a few
>> problems:
>>
>> 1) xUnit historically relies on inheritance but it's not clear to me
>> how to model an is-a relationship in Rust. For instance, define an
>> abstract base class (TestSuite) and an implementation that tests a set
>> of functions (say, a calculator).
>>
>
> Hi, Steve --
>
> The way to do this in Rust would be to define a trait TestSuite, and
> impls that implement that trait for various types. Patrick's tutorial
> should be helpful:
>
> http://pcwalton.github.com/blog/2012/08/08/a-gentle-introduction-to-traits-in-rust/

Based on that, I came up with a super naive attempt. I realize this is
basically trying to write Java in rust so I apologize in advance.

trait TestSuite {
fn setup();
fn teardown();
}

struct Calculator {
fn add(m: int, n: int) -> int {
return m + n;
}
}

impl CalculatorTest : TestSuite { // error: use of undeclared type
name `CalculatorTest`
// without this, I have nothing to call
//let calculator = Calculator();

fn setup() {}
fn teardown() {}

fn test_addition() -> bool {
return true;
}
}

Based on my experience in Haskell, there's a number of ways I could
tackle this problem but I think it's safe to say that most people who
think of themselves as 'systems programmers' would attempt the above
first and wonder why rust's OO is 'weird'?

I'm also curious what a rust-oriented solution to this problem would look like.

>> 2) How to colocate state and behavior in impls. Embedding lets in my
>> impls results in errors.
>
> impls don't talk about state, and we don't have plans to change that
> as far as I know. As shown in Patrick's tutorial, you define all your
> fields in struct definitions, and then provide impls that implement
> various traits for a particular struct. This doesn't preclude
> anything: you can always define methods on a struct that get/set its
> fields.
>
>>
>> 3) Reflection. I have no documented way to iterate over the functions
>> in an impl and call them. (I'm sure this is on the way and I'm just
>> early to the party)
>>
>
> I don't know of any plans to do this. I'm not sure why you would want
> to; if you can give an example, it might help.

In a traditional xUnit framework, your test suite subclasses have
methods that are prefixed with 'test' and you use reflection to
iterate over the methods and call each method whose name starts with
'test', calling setup() and teardown() around each invocation.

In a BDD framework, you build tests as anonymous functions and you can
register them and call them without resorting to reflection. In rust,
this would look something like:

describe('add two numbers', fun () -> bool { assertEqual(calc.add(1, 1), 2) });

>> I also think I'm approaching this from the wrong direction and that
>> Rust's OO with typeclasses are different from how I'm using to
>> building software in another language with typeclasses (Scala). I'm
>> still looking for the zen of Rust OO.
>>
>> I ran into some old blog posts that discuss a class keyword but I
>> wasn't able to make those examples run in 0.3.1. Do we only have impls
>> now?
>
> The class keyword is deprecated; struct replaces class.
>
> Feel free to ask again if you have more questions (or visit #rust on IRC).

Thanks again! I hope this is helpful and doesn't seem like I'm trolling.

steve
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Questions about rust's OO.

2012-08-26 Thread Steve Jenson
Hi rustics,

I spent some time this weekend going over the rust tutorial and
documentation for 0.3.1. I thought a fun exercise would be writing an
xUnit testing framework[1] in a "classic" OO style. I ran into a few
problems:

1) xUnit historically relies on inheritance but it's not clear to me
how to model an is-a relationship in Rust. For instance, define an
abstract base class (TestSuite) and an implementation that tests a set
of functions (say, a calculator).

2) How to colocate state and behavior in impls. Embedding lets in my
impls results in errors.

3) Reflection. I have no documented way to iterate over the functions
in an impl and call them. (I'm sure this is on the way and I'm just
early to the party)

I also think I'm approaching this from the wrong direction and that
Rust's OO with typeclasses are different from how I'm using to
building software in another language with typeclasses (Scala). I'm
still looking for the zen of Rust OO.

I ran into some old blog posts that discuss a class keyword but I
wasn't able to make those examples run in 0.3.1. Do we only have impls
now?

I realize that Rust is young and moving quickly but I'm struggling to
build something that's more than a few functions and an enum.

Thanks a bunch,
Steve

[1] http://en.wikipedia.org/wiki/XUnit
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev