Re: [rust-dev] Implementation of traits in Rust: could it be dynamic?
Even if we could do a size/alignment-passing implementation like Patrick describes, would be it even be appropriate? It wouldn’t make sense for a systems language to transparently switch to a dramatically less efficient implementation mechanism without the programmer’s involvement. Is there any place where an unbounded number of dictionaries at runtime is actually appropriate for solving a real problem in Rust? Cameron On Jul 22, 2014, at 10:16 AM, Lionel Parreaux wrote: > Hi, > > So traits seem to be quite similar to Haskell's classes, being also used for > parametric polymorphism. Now, Haskell classes are usually implemented using > runtime dictionary passing. In general, code cannot be specialized for every > function call, since there may be an unbounded number of instances generated > for it, as is explained in this reddit answer: > http://www.reddit.com/r/haskell/comments/1ar642/what_type_of_binding_does_haskell_use/c94o2ju > > Knowing that Rust implements traits using monomorphization of code (much like > C++ templates), I was curious about how it handled such cases, and tried this: > > struct W { > f: T > } > > trait Show { > fn show(&self) -> int; > } > > impl Show for int { > fn show(&self) -> int { 666 } > } > impl Show for W { > fn show(&self) -> int { self.f.show()+1 } > } > impl Clone for W { > fn clone(&self) -> W { W{f:self.f.clone()} } > } > > fn foo(s: &S, n: int) { > let w = W{f:s.clone()}; > if n > 0 { foo(&w, n-1); } > } > > fn main() { > foo(&W{f:42i},42); > } > > > It gave me an "error: reached the recursion limit during monomorphization", > which... well, that's a possible solution :) > > I'm not sure whether this is a big problem in practice, but I was wondering > if it would be possible to switch to some runtime mechanism in cases like > this. Maybe we could make a special version of every generic functions, that > takes a dictionary at runtime and that would be able to handle types unknown > at compile-time. We would switch to this version when monomorphization does > not work. It could also allow dynamic linking of libraries with generic > functions, or it could be a way to compile some programs (or some parts of > programs) much faster. > I was thinking about, for example, an IDE where generic function calls to > types defined inside the files currently being edited use their dynamic > version, so that recompile times can be virtually inexistent (like Java). On > the other hand, the release build would of course monomorphize as much as > possible to make the perf optimal. > > Now the question is: would this conform to the current semantic of > monomorphization? Do special things happen during monomorphization that > cannot be reproduced at runtime? > This is the case in C++ (and one of the reasons why C++ templates are so > "bad"). Is it the case in Rust, which should already have all the required > info (type bounds) before monomorphization? > > I apologize if this has already been discussed. I could not find many > satisfying answers by googling. > > Cheers, > LP. > > > ___ > 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] Mutable files
On 23/07/14 07:10, Tobias Müller wrote: ... in C++. Not in Rust. That's because, unlike C++, Rust is designed from the ground up to support moves and copies in a first class way. It's just strange that you can change the semantic of an already existing operation just by adding new capabilities. Adding traits should define new operations with new semantics, not changing the semantics of existing operations. At least that's how it works for all other traits, and deviating from that is at least surprising. Hence the Opt-In Built-In Traits proposal Opt-In built-In traits makes things a bit better but my point is still valid. By adding Copy (implicitly or explicitly) you remove the possibility of move semantics from the type. Usually you don't work alone on a project and some coworker adding Copy to a type that I expected to be Move may be fatal. No other trait removed works like that. You can't just add Copy to anything: the contents has to be Copy itself, and, you can't have a destructor on your type (i.e. a Drop implementation removes the possibility to be Copy). Thus, almost all types for which by-value uses *should* invalidate the source (i.e. "move semantics") are automatically not Copy anyway. The only way one can get a fatal error due to an incorrect Copy implementation is if the type with the impl is using `unsafe` code internally. In this case, that whole API needs to be considered very carefully anyway, ensuring correctness by avoiding Copy is just part of it. I'll also note that an implementation of Copy just states the a byte-copy of a value is also a semantic copy, it doesn't offer any control over how the copy is performed. At runtime, by-value use of a Copy type is essentially identical to a by-value use of a non-Copy type (both are memcpy's of the bytes), the only major difference is the compiler statically prevents further uses of the source for non-Copy ones. Huon ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Mutable files
On Mon, Jul 21, 2014 at 2:45 PM, Patrick Walton wrote: > >> ... in C++. Not in Rust. That's because, unlike C++, Rust is designed > from the ground up to support moves and copies in a first class way. As a C++ dev, I feel the need to say THANK YOU for that. Rust being designed with first-class move support is a major feature for me; it's something I highlight when I talk about Rust with other C++ devs and it's universally applauded. > > > It's just strange that you can change the semantic of an already existing >> operation just by adding new capabilities. Adding traits should define new >> operations with new semantics, not changing the semantics of existing >> operations. At least that's how it works for all other traits, and >> deviating from that is at least surprising. >> > > Hence the Opt-In Built-In Traits proposal > > > Maybe the syntax was just too heavy? >> > > Any syntax at all is too much. I am convinced of that. > > Patrick > > > ___ > 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] Mutable files
Patrick Walton wrote: > On 7/21/14 2:22 PM, Tobias Müller wrote: >> We discussed this with Bartosz literally for weeks (him being a fan of >> auto_ptr for too long, later completely converted against it and I take >> credit for that :o)). With auto_ptr this was possible: >> >> auto_ptr a(new int); >> auto_ptr b = a; >> >> It would nullify a with copy syntax. That code won't compile with >> unique_ptr; you'd need an explicit move(a). >> >> It only got worse from there: passing into functions, member variables... >> >> MOVING WITH COPY SYNTAX DOES NOT WORK. >> >> It's cut and dried. Please don't snip the attribution, that was a quote! > ... in C++. Not in Rust. That's because, unlike C++, Rust is designed > from the ground up to support moves and copies in a first class way. > >> It's just strange that you can change the semantic of an already existing >> operation just by adding new capabilities. Adding traits should define new >> operations with new semantics, not changing the semantics of existing >> operations. At least that's how it works for all other traits, and >> deviating from that is at least surprising. > > Hence the Opt-In Built-In Traits proposal Opt-In built-In traits makes things a bit better but my point is still valid. By adding Copy (implicitly or explicitly) you remove the possibility of move semantics from the type. Usually you don't work alone on a project and some coworker adding Copy to a type that I expected to be Move may be fatal. No other trait removed works like that. >> Maybe the syntax was just too heavy? > > Any syntax at all is too much. I am convinced of that. I'm still not convinced but maybe my fear is unjustified. Time will tell. Tobi ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] A shiny test framework
One note on why there's no after_each: You cannot really make sure that the epilogue is being called, so if you need to do anything after your test case, use RAII in before_each. On Tue, Jul 22, 2014 at 8:10 PM, Benjamin Gudehus wrote: > Nice to see an RSpec-like test framework and Hamcrest assertions/matchers > for Rust! > > > On Tue, Jul 22, 2014 at 9:09 PM, Ilya Dmitrichenko < > errordevelo...@gmail.com> wrote: > >> Dude, that's pretty much rspec ;) sweet! >> On 22 Jul 2014 20:07, "Vladimir Pouzanov" wrote: >> >>> I've just published a tiny test framework: shiny at >>> https://github.com/farcaller/shiny. It's best used with hamcrest-rust. >>> >>> This library exists because I find it ugly to redefine all the >>> initialisation code in every test case and I can't simply move it to a >>> function due to problems with moving [T] out. >>> >>> Here's how shiny looks: >>> >>> #[cfg(test)] >>> mod test { >>> describe!( >>> before_each { >>> let awesome = true; >>> } >>> >>> it "is awesome" { >>> assert!(awesome); >>> } >>> >>> it "injects before_each into all test cases" { >>> let still_awesome = awesome; >>> assert!(still_awesome); >>> } >>> ) >>> } >>> >>> -- >>> Sincerely, >>> Vladimir "Farcaller" Pouzanov >>> http://farcaller.net/ >>> >>> ___ >>> 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 >> >> > -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] A shiny test framework
Nice to see an RSpec-like test framework and Hamcrest assertions/matchers for Rust! On Tue, Jul 22, 2014 at 9:09 PM, Ilya Dmitrichenko wrote: > Dude, that's pretty much rspec ;) sweet! > On 22 Jul 2014 20:07, "Vladimir Pouzanov" wrote: > >> I've just published a tiny test framework: shiny at >> https://github.com/farcaller/shiny. It's best used with hamcrest-rust. >> >> This library exists because I find it ugly to redefine all the >> initialisation code in every test case and I can't simply move it to a >> function due to problems with moving [T] out. >> >> Here's how shiny looks: >> >> #[cfg(test)] >> mod test { >> describe!( >> before_each { >> let awesome = true; >> } >> >> it "is awesome" { >> assert!(awesome); >> } >> >> it "injects before_each into all test cases" { >> let still_awesome = awesome; >> assert!(still_awesome); >> } >> ) >> } >> >> -- >> Sincerely, >> Vladimir "Farcaller" Pouzanov >> http://farcaller.net/ >> >> ___ >> 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] A shiny test framework
Dude, that's pretty much rspec ;) sweet! On 22 Jul 2014 20:07, "Vladimir Pouzanov" wrote: > I've just published a tiny test framework: shiny at > https://github.com/farcaller/shiny. It's best used with hamcrest-rust. > > This library exists because I find it ugly to redefine all the > initialisation code in every test case and I can't simply move it to a > function due to problems with moving [T] out. > > Here's how shiny looks: > > #[cfg(test)] > mod test { > describe!( > before_each { > let awesome = true; > } > > it "is awesome" { > assert!(awesome); > } > > it "injects before_each into all test cases" { > let still_awesome = awesome; > assert!(still_awesome); > } > ) > } > > -- > Sincerely, > Vladimir "Farcaller" Pouzanov > http://farcaller.net/ > > ___ > 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] A shiny test framework
I've just published a tiny test framework: shiny at https://github.com/farcaller/shiny. It's best used with hamcrest-rust. This library exists because I find it ugly to redefine all the initialisation code in every test case and I can't simply move it to a function due to problems with moving [T] out. Here's how shiny looks: #[cfg(test)] mod test { describe!( before_each { let awesome = true; } it "is awesome" { assert!(awesome); } it "injects before_each into all test cases" { let still_awesome = awesome; assert!(still_awesome); } ) } -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Implementation of traits in Rust: could it be dynamic?
On 7/22/14 10:16 AM, Lionel Parreaux wrote: I'm not sure whether this is a big problem in practice, but I was wondering if it would be possible to switch to some runtime mechanism in cases like this. Maybe we could make a special version of every generic functions, that takes a dictionary at runtime and that would be able to handle types unknown at compile-time. We would switch to this version when monomorphization does not work. It could also allow dynamic linking of libraries with generic functions, or it could be a way to compile some programs (or some parts of programs) much faster. The hard part about doing that is not the dictionary passing. The hard part is that generic types may have unknown size or alignment. In Haskell this is not a problem because the language is garbage-collected and lazy so values have a uniform representation. But in Rust this is not true. Old Rust used to try to use runtime dictionary passing, where the dictionary contained size and alignment information, and all size/alignment info was computed at runtime for generics. I cannot overstate how *fiendishly* complex this was. We never got all the bugs out. In many cases, the amount of runtime code generated to compute size and alignment outweighed the cost of just monomorphizing. I strongly feel that the current system, where you can use generic type parameters to get monomorphization or trait objects to get dictionary passing, is the sweet spot. Patrick ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Implementation of traits in Rust: could it be dynamic?
this remindes me of the issue i got when trying to implement finger trees in Rust so long ago https://github.com/rust-lang/rust/issues/8613 I suggested to let add a way to specify (in the code) how match functions do we want to generate and failing at runtime when the limit is reached. This made sense in my situation. 2014-07-22 18:23 UTC+01:00, Corey Richardson : > You can avoid monomorphization by using "trait objects", which erase > the precise implementing type through a vtable + pointer. > http://doc.rust-lang.org/tutorial.html#trait-objects-and-dynamic-method-dispatch > has some documentation. > > On Tue, Jul 22, 2014 at 10:16 AM, Lionel Parreaux > wrote: >> Hi, >> >> So traits seem to be quite similar to Haskell's classes, being also used >> for >> parametric polymorphism. Now, Haskell classes are usually implemented >> using >> runtime dictionary passing. In general, code cannot be specialized for >> every >> function call, since there may be an unbounded number of instances >> generated >> for it, as is explained in this reddit answer: >> http://www.reddit.com/r/haskell/comments/1ar642/what_type_of_binding_does_haskell_use/c94o2ju >> >> Knowing that Rust implements traits using monomorphization of code (much >> like C++ templates), I was curious about how it handled such cases, and >> tried this: >> >> struct W { >> f: T >> } >> >> trait Show { >> fn show(&self) -> int; >> } >> >> impl Show for int { >> fn show(&self) -> int { 666 } >> } >> impl Show for W { >> fn show(&self) -> int { self.f.show()+1 } >> } >> impl Clone for W { >> fn clone(&self) -> W { W{f:self.f.clone()} } >> } >> >> fn foo(s: &S, n: int) { >> let w = W{f:s.clone()}; >> if n > 0 { foo(&w, n-1); } >> } >> >> fn main() { >> foo(&W{f:42i},42); >> } >> >> >> It gave me an "error: reached the recursion limit during >> monomorphization", >> which... well, that's a possible solution :) >> >> I'm not sure whether this is a big problem in practice, but I was >> wondering >> if it would be possible to switch to some runtime mechanism in cases like >> this. Maybe we could make a special version of every generic functions, >> that >> takes a dictionary at runtime and that would be able to handle types >> unknown >> at compile-time. We would switch to this version when monomorphization >> does >> not work. It could also allow dynamic linking of libraries with generic >> functions, or it could be a way to compile some programs (or some parts >> of >> programs) much faster. >> I was thinking about, for example, an IDE where generic function calls to >> types defined inside the files currently being edited use their dynamic >> version, so that recompile times can be virtually inexistent (like Java). >> On >> the other hand, the release build would of course monomorphize as much as >> possible to make the perf optimal. >> >> Now the question is: would this conform to the current semantic of >> monomorphization? Do special things happen during monomorphization that >> cannot be reproduced at runtime? >> This is the case in C++ (and one of the reasons why C++ templates are so >> "bad"). Is it the case in Rust, which should already have all the >> required >> info (type bounds) before monomorphization? >> >> I apologize if this has already been discussed. I could not find many >> satisfying answers by googling. >> >> Cheers, >> LP. >> >> >> >> ___ >> Rust-dev mailing list >> Rust-dev@mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> > > > > -- > http://octayn.net/ > ___ > 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] Conflicting implementations of a trait
Am 22.07.2014 18:50, schrieb Allen Welkie: > Can there be two simultaneous implementations of a generic trait? I ask > because I want to extend the Complex class to allow for multiplication by > scalars, so that you can use "a * b" where "a" and "b" can be either > scalars or Complex. [snip] Something like this was my first attempt in Rust. I was able to define two own types (complex and imaginary) which I could mix with f64 for multiplication, addition, etc. But it required a kind of "double dispatch". Niko explained it here: http://smallcultfollowing.com/babysteps/blog/2012/10/04/refining-traits-slash-impls/ Unfortunately, given how these traits are defined now, design requires a bit of foresight. If you want to mix types like this for binary operations eventually, you should probably start this kind of dispatching early on. You can't do that with num's complex struct now. Its Add/Mul/etc impls weren't designed with double-dispatch in mind. For now, you would have to define your own types like I did. But there is a chance that the binary operator traits change. For a binary operator like + and * there is no clear "receiver" (an object you call an add function on). IMHO the operands should be treated equally. One approach that I saw mentioned by Niko (in another blog post I believe) was to use tuples for that: trait Add { fn add(self) -> Out; } impl Add> for (f64,Compex) { fn add((lhs, rhs) : (f64, Complex)) -> Complex { ... } } And this makes it much easier to extend the interface of certain types together. On the other hand, there still needs to go some thought into this with respect to passing operands by value or reference. You don't want unnecessary clones. And you probably don't want operands to be moved-from in some cases. And the way these kinds of traits are refined should work well together with generic code: fn foo(x: T, y: U) -> O where ???: Mul { x * y } Ideally, this should work for every type T and U that can be multiplied somehow. The question however is, how to write down the type bound? Should we write (&T,&U): Add to avoid moving? Should we write (T,U): Add for a nicer, more intuitive syntax perhaps? I don't know. If you have a good idea how to do that, I'm all ears. I'm very much interested in getting easily overloadable operators without the pain of double-dispatch and without the pain of clumsly type bounds for generic functions that only work for half the cases due to references and such. Cheers! sg ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Implementation of traits in Rust: could it be dynamic?
You can avoid monomorphization by using "trait objects", which erase the precise implementing type through a vtable + pointer. http://doc.rust-lang.org/tutorial.html#trait-objects-and-dynamic-method-dispatch has some documentation. On Tue, Jul 22, 2014 at 10:16 AM, Lionel Parreaux wrote: > Hi, > > So traits seem to be quite similar to Haskell's classes, being also used for > parametric polymorphism. Now, Haskell classes are usually implemented using > runtime dictionary passing. In general, code cannot be specialized for every > function call, since there may be an unbounded number of instances generated > for it, as is explained in this reddit answer: > http://www.reddit.com/r/haskell/comments/1ar642/what_type_of_binding_does_haskell_use/c94o2ju > > Knowing that Rust implements traits using monomorphization of code (much > like C++ templates), I was curious about how it handled such cases, and > tried this: > > struct W { > f: T > } > > trait Show { > fn show(&self) -> int; > } > > impl Show for int { > fn show(&self) -> int { 666 } > } > impl Show for W { > fn show(&self) -> int { self.f.show()+1 } > } > impl Clone for W { > fn clone(&self) -> W { W{f:self.f.clone()} } > } > > fn foo(s: &S, n: int) { > let w = W{f:s.clone()}; > if n > 0 { foo(&w, n-1); } > } > > fn main() { > foo(&W{f:42i},42); > } > > > It gave me an "error: reached the recursion limit during monomorphization", > which... well, that's a possible solution :) > > I'm not sure whether this is a big problem in practice, but I was wondering > if it would be possible to switch to some runtime mechanism in cases like > this. Maybe we could make a special version of every generic functions, that > takes a dictionary at runtime and that would be able to handle types unknown > at compile-time. We would switch to this version when monomorphization does > not work. It could also allow dynamic linking of libraries with generic > functions, or it could be a way to compile some programs (or some parts of > programs) much faster. > I was thinking about, for example, an IDE where generic function calls to > types defined inside the files currently being edited use their dynamic > version, so that recompile times can be virtually inexistent (like Java). On > the other hand, the release build would of course monomorphize as much as > possible to make the perf optimal. > > Now the question is: would this conform to the current semantic of > monomorphization? Do special things happen during monomorphization that > cannot be reproduced at runtime? > This is the case in C++ (and one of the reasons why C++ templates are so > "bad"). Is it the case in Rust, which should already have all the required > info (type bounds) before monomorphization? > > I apologize if this has already been discussed. I could not find many > satisfying answers by googling. > > Cheers, > LP. > > > > ___ > Rust-dev mailing list > Rust-dev@mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- http://octayn.net/ ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] Implementation of traits in Rust: could it be dynamic?
Hi, So traits seem to be quite similar to Haskell's classes, being also used for parametric polymorphism. Now, Haskell classes are usually implemented using runtime dictionary passing. In general, code cannot be specialized for every function call, since there may be an unbounded number of instances generated for it, as is explained in this reddit answer: http://www.reddit.com/r/haskell/comments/1ar642/what_type_of_binding_does_haskell_use/c94o2ju Knowing that Rust implements traits using monomorphization of code (much like C++ templates), I was curious about how it handled such cases, and tried this: struct W { f: T } trait Show { fn show(&self) -> int; } impl Show for int { fn show(&self) -> int { 666 } } impl Show for W { fn show(&self) -> int { self.f.show()+1 } } impl Clone for W { fn clone(&self) -> W { W{f:self.f.clone()} } } fn foo(s: &S, n: int) { let w = W{f:s.clone()}; if n > 0 { foo(&w, n-1); } } fn main() { foo(&W{f:42i},42); } It gave me an "error: reached the recursion limit during monomorphization", which... well, that's a possible solution :) I'm not sure whether this is a big problem in practice, but I was wondering if it would be possible to switch to some runtime mechanism in cases like this. Maybe we could make a special version of every generic functions, that takes a dictionary at runtime and that would be able to handle types unknown at compile-time. We would switch to this version when monomorphization does not work. It could also allow dynamic linking of libraries with generic functions, or it could be a way to compile some programs (or some parts of programs) much faster. I was thinking about, for example, an IDE where generic function calls to types defined inside the files currently being edited use their dynamic version, so that recompile times can be virtually inexistent (like Java). On the other hand, the release build would of course monomorphize as much as possible to make the perf optimal. Now the question is: would this conform to the current semantic of monomorphization? Do special things happen during monomorphization that cannot be reproduced at runtime? This is the case in C++ (and one of the reasons why C++ templates are so "bad"). Is it the case in Rust, which should already have all the required info (type bounds) before monomorphization? I apologize if this has already been discussed. I could not find many satisfying answers by googling. Cheers, LP. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] How to write Generic traits for enums
Hi Felix, Just now got a doubt. Since we know the type of enum during compile time, is it not possible to get the value from enum. Something like this.. enum MyTypes{ MyBool(bool), MyStr(String), MyInt(int) } let a = MyBool(true); a.get_value(); // trait for enum let b = MyInt(100); b.get_value(); Do you think it is possible to implement? On Tue, Jul 22, 2014 at 9:37 PM, Aravinda VK wrote: > Hi Felix, > > Thanks a lot for the detailed explanation. > > > On Tue, Jul 22, 2014 at 7:08 PM, Felix S. Klock II > wrote: > >> Aravinda (cc’ing rust-dev)- >> >> It seems like you are trying to program in Rust as if it were a >> dynamically-typed language, or one with runtime-type reflection (i.e. like >> Java). At least, that is my best guess at where your misunderstanding lies. >> >> All functions in Rust, even generic ones, need to have their types >> resolved at compile-time. A generic function can have different concrete >> types substituted in for its type parameters at different call-sites, but >> in the end, a particular call-site needs to resolve to a single type at >> compile-time; the type cannot be left for later resolution at program >> runtime. >> >> In a signature like your: >> >> fn get_value(settings:HashMap, key: &'static str) -> >> T; >> >> the particular instance of `MyTypes` that is returned will depend on >> which `key` is passed in; therefore, the `T` above could only be >> dynamically determined based on the runtime computation. It inherently >> cannot be resolved at compile-time, and therefore it is not statically >> typed. >> >> >> >> Rust is not alone in offering this kind of generic types; many >> programming languages use a similar logic for determining types at compile >> time. It just gets fuzzy if one is used to languages that maintain types >> at runtime and do not enforce restrictions like the one I outlined above. >> >> These type systems are often said to offer “parametric polymorphism”; I >> mention that solely to give you some guidance for a term to search for when >> goggling this subject. (Though I will say up front that a lot of the >> results you get on this topic can be very academic and language >> research-oriented.) >> >> Here is a tutorial that may help you get a handle on the concepts here: >> >> http://lucacardelli.name/Papers/BasicTypechecking.pdf >> >> (Yes, it is from 1987. I think that is why it probably one of the better >> descriptions I was able to find quickly: At that time, these ideas were not >> as widely popularized as they were today, so Cardelli took his time >> explaining the notions and assumed little about the audience.) >> >> rust-dev members: If others know of freely available introductions to >> this topic, I’m all ears; I just didn’t see any obvious winners in my >> searches. >> >> Cheers, >> -Felix >> >> >> On 22 Jul 2014, at 14:24, Aravinda VK wrote: >> >> Sorry for the incomplete mail. >> >> What I wanted is, >> get_value(MyStr("Rust".to_str())) returns String, >> get_value(MyBool(true)) returns bool and, >> get_value(MyInt(100)) returns int >> >> I was trying to store generic value in hashmap, as in the example below, >> >> use std::collections::hashmap::HashMap; >> >> #[deriving(Show)] >> enum MyTypes{ >> MyBool(bool), >> MyStr(String), >> MyInt(int) >> } >> >> fn main(){ >> let mut settings:HashMap = HashMap::new(); >> >> settings.insert("port".to_str(), MyInt(8000)); >> settings.insert("name".to_str(), MyStr("Rust".to_str())); >> settings.insert("enabled".to_str(), MyBool(true)); >> >> println!("{}", settings); >> } >> >> So to get the value out of hashmap, I need a generic function which >> checks the respective type and returns value. Some thing like >> >> fn get_value(settings:HashMap, key: &'static str) -> T{ >> match settings.get(&key) { >> MyBool(x) => x, >> MyStr(x) => x, >> MyInt(x) => x >> } >> } >> >> But I don't know how to make this work. >> >> Thanks. >> >> >> >> On Tue, Jul 22, 2014 at 4:55 PM, Felix S. Klock II >> wrote: >> >>> Aravinda (cc’ing rust-dev)- >>> >>> You didn’t show us exactly what you had tried to do to get your code to >>> work, nor did you really describe what it is you want here. >>> >>> E.g. you seem to want `get_value(MyBool(true))` to return a boolean, but >>> since `MyBool` belongs to the `MyTypes` enum, that implies that `get_value` >>> when applied to any variant of `MyTypes` (including `MyInt` or `MyStr`) >>> should also return a boolean … does that seem right to you? >>> >>> In any case, I suspect the missing piece of the puzzle for you is that >>> you need to write an `impl` for the type in question. I.e. something along >>> the lines of: >>> >>> impl MyTypes { >>> fn render(&self) -> String { >>> match *self { >>> MyBool(x) => format!("{:b}", x), >>> MyStr(ref x) => x.clone(), >>> MyInt(x) => format!("{:d}", x), >>> } >>> } >>> } >>> >>>
Re: [rust-dev] Conflicting implementations of a trait
Not right now. Extending the language to allow this is the subject of RFC 24: https://github.com/rust-lang/rfcs/blob/master/active/0024-traits.md On Tue, Jul 22, 2014 at 9:50 AM, Allen Welkie wrote: > Can there be two simultaneous implementations of a generic trait? I ask > because I want to extend the Complex class to allow for multiplication by > scalars, so that you can use "a * b" where "a" and "b" can be either scalars > or Complex. > > The Complex struct already has an implementation of the Mul trait. I wanted > to add another, so I added the implementation of Mul> for > Complex, and used the scale() function. But I get a compiler error saying > that there are conflicting implementations for trait 'core::ops::Mul'. > > Is it possible to simultaneously overload the Complex (*) operator scalars > and complex numbers? > > ___ > Rust-dev mailing list > Rust-dev@mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- http://octayn.net/ ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] Conflicting implementations of a trait
Can there be two simultaneous implementations of a generic trait? I ask because I want to extend the Complex class to allow for multiplication by scalars, so that you can use "a * b" where "a" and "b" can be either scalars or Complex. The Complex struct already has an implementation of the Mul trait. I wanted to add another, so I added the implementation of Mul> for Complex, and used the scale() function. But I get a compiler error saying that there are conflicting implementations for trait 'core::ops::Mul'. Is it possible to simultaneously overload the Complex (*) operator scalars and complex numbers? ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] How to write Generic traits for enums
Hi Felix, Thanks a lot for the detailed explanation. On Tue, Jul 22, 2014 at 7:08 PM, Felix S. Klock II wrote: > Aravinda (cc’ing rust-dev)- > > It seems like you are trying to program in Rust as if it were a > dynamically-typed language, or one with runtime-type reflection (i.e. like > Java). At least, that is my best guess at where your misunderstanding lies. > > All functions in Rust, even generic ones, need to have their types > resolved at compile-time. A generic function can have different concrete > types substituted in for its type parameters at different call-sites, but > in the end, a particular call-site needs to resolve to a single type at > compile-time; the type cannot be left for later resolution at program > runtime. > > In a signature like your: > > fn get_value(settings:HashMap, key: &'static str) -> > T; > > the particular instance of `MyTypes` that is returned will depend on which > `key` is passed in; therefore, the `T` above could only be dynamically > determined based on the runtime computation. It inherently cannot be > resolved at compile-time, and therefore it is not statically typed. > > > > Rust is not alone in offering this kind of generic types; many programming > languages use a similar logic for determining types at compile time. It > just gets fuzzy if one is used to languages that maintain types at runtime > and do not enforce restrictions like the one I outlined above. > > These type systems are often said to offer “parametric polymorphism”; I > mention that solely to give you some guidance for a term to search for when > goggling this subject. (Though I will say up front that a lot of the > results you get on this topic can be very academic and language > research-oriented.) > > Here is a tutorial that may help you get a handle on the concepts here: > > http://lucacardelli.name/Papers/BasicTypechecking.pdf > > (Yes, it is from 1987. I think that is why it probably one of the better > descriptions I was able to find quickly: At that time, these ideas were not > as widely popularized as they were today, so Cardelli took his time > explaining the notions and assumed little about the audience.) > > rust-dev members: If others know of freely available introductions to this > topic, I’m all ears; I just didn’t see any obvious winners in my searches. > > Cheers, > -Felix > > > On 22 Jul 2014, at 14:24, Aravinda VK wrote: > > Sorry for the incomplete mail. > > What I wanted is, > get_value(MyStr("Rust".to_str())) returns String, > get_value(MyBool(true)) returns bool and, > get_value(MyInt(100)) returns int > > I was trying to store generic value in hashmap, as in the example below, > > use std::collections::hashmap::HashMap; > > #[deriving(Show)] > enum MyTypes{ > MyBool(bool), > MyStr(String), > MyInt(int) > } > > fn main(){ > let mut settings:HashMap = HashMap::new(); > > settings.insert("port".to_str(), MyInt(8000)); > settings.insert("name".to_str(), MyStr("Rust".to_str())); > settings.insert("enabled".to_str(), MyBool(true)); > > println!("{}", settings); > } > > So to get the value out of hashmap, I need a generic function which checks > the respective type and returns value. Some thing like > > fn get_value(settings:HashMap, key: &'static str) -> T{ > match settings.get(&key) { > MyBool(x) => x, > MyStr(x) => x, > MyInt(x) => x > } > } > > But I don't know how to make this work. > > Thanks. > > > > On Tue, Jul 22, 2014 at 4:55 PM, Felix S. Klock II > wrote: > >> Aravinda (cc’ing rust-dev)- >> >> You didn’t show us exactly what you had tried to do to get your code to >> work, nor did you really describe what it is you want here. >> >> E.g. you seem to want `get_value(MyBool(true))` to return a boolean, but >> since `MyBool` belongs to the `MyTypes` enum, that implies that `get_value` >> when applied to any variant of `MyTypes` (including `MyInt` or `MyStr`) >> should also return a boolean … does that seem right to you? >> >> In any case, I suspect the missing piece of the puzzle for you is that >> you need to write an `impl` for the type in question. I.e. something along >> the lines of: >> >> impl MyTypes { >> fn render(&self) -> String { >> match *self { >> MyBool(x) => format!("{:b}", x), >> MyStr(ref x) => x.clone(), >> MyInt(x) => format!("{:d}", x), >> } >> } >> } >> >> (except revised from an Impl for the type to being an impl of some trait >> for the type). >> >> Here is a link to a playpen with your code, and with a couple of example >> `impl`s for enums (like the one above) tossed in, including an impl of one >> instance of your `Value` trait. >> >> http://is.gd/RofN9R >> >> There is more discussion of writing implementations that also provides an >> example with a simpler enum) in the Rust tutorial, see: >> >> http://doc.rust-lang.org/tutorial.html#methods >> >> Cheers, >> -Felix >> >> On 22 Jul 2014, at 11:45,
Re: [rust-dev] file logger missing?
It does not exist in tree. So far, liblog has the features used by rustc and stdlib, and naught else. A papercut with liblog is that you need to remember to set_logger inside every task you spawn, which currently just means it's easier to keep the default. On Jul 22, 2014 8:38 AM, "Diggory Hardy" wrote: > For some uses, yes. But I guess log rotation should also be a feature. > > My first point is why is there a seemingly complex logging framework > without > this? Does it already exist somewhere? > > > On Tuesday 22 Jul 2014 08:27:47 Steven Fackler wrote: > > Is a logger that synchronously writes to the filesystem and doesn't offer > > any type of rotation more useful than redirecting stderr? > > > > Steven Fackler > > > > On Tue, Jul 22, 2014 at 8:11 AM, Diggory Hardy > wrote: > > > Are you saying that liblog should be moved too? Because I don't see > why a > > > complex logging framework should be separated from a simple log-to-file > > > implementation (36 lines in my case, including doc, use statements, > etc). > > > > > > On Tuesday 22 Jul 2014 10:49:59 Steve Klabnik wrote: > > > > I think in general, especially now that Cargo exists, we don't really > > > > need to add a lot more to the tree. Publish a package for it instead! > > > > > > ___ > > > 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] file logger missing?
For some uses, yes. But I guess log rotation should also be a feature. My first point is why is there a seemingly complex logging framework without this? Does it already exist somewhere? On Tuesday 22 Jul 2014 08:27:47 Steven Fackler wrote: > Is a logger that synchronously writes to the filesystem and doesn't offer > any type of rotation more useful than redirecting stderr? > > Steven Fackler > > On Tue, Jul 22, 2014 at 8:11 AM, Diggory Hardy wrote: > > Are you saying that liblog should be moved too? Because I don't see why a > > complex logging framework should be separated from a simple log-to-file > > implementation (36 lines in my case, including doc, use statements, etc). > > > > On Tuesday 22 Jul 2014 10:49:59 Steve Klabnik wrote: > > > I think in general, especially now that Cargo exists, we don't really > > > need to add a lot more to the tree. Publish a package for it instead! > > > > ___ > > 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] file logger missing?
Is a logger that synchronously writes to the filesystem and doesn't offer any type of rotation more useful than redirecting stderr? Steven Fackler On Tue, Jul 22, 2014 at 8:11 AM, Diggory Hardy wrote: > Are you saying that liblog should be moved too? Because I don't see why a > complex logging framework should be separated from a simple log-to-file > implementation (36 lines in my case, including doc, use statements, etc). > > On Tuesday 22 Jul 2014 10:49:59 Steve Klabnik wrote: > > I think in general, especially now that Cargo exists, we don't really > > need to add a lot more to the tree. Publish a package for it instead! > ___ > 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] file logger missing?
Are you saying that liblog should be moved too? Because I don't see why a complex logging framework should be separated from a simple log-to-file implementation (36 lines in my case, including doc, use statements, etc). On Tuesday 22 Jul 2014 10:49:59 Steve Klabnik wrote: > I think in general, especially now that Cargo exists, we don't really > need to add a lot more to the tree. Publish a package for it instead! ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] file logger missing?
I think in general, especially now that Cargo exists, we don't really need to add a lot more to the tree. Publish a package for it instead! ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] file logger missing?
Isn't log:Logger missing some implementations? http://doc.rust-lang.org/log/trait.Logger.html If it's useful I can push my simple file logger to the Rust tree, but I don't know where it should live. Cheers Diggory ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] How to write Generic traits for enums
Aravinda (cc’ing rust-dev)- It seems like you are trying to program in Rust as if it were a dynamically-typed language, or one with runtime-type reflection (i.e. like Java). At least, that is my best guess at where your misunderstanding lies. All functions in Rust, even generic ones, need to have their types resolved at compile-time. A generic function can have different concrete types substituted in for its type parameters at different call-sites, but in the end, a particular call-site needs to resolve to a single type at compile-time; the type cannot be left for later resolution at program runtime. In a signature like your: fn get_value(settings:HashMap, key: &'static str) -> T; the particular instance of `MyTypes` that is returned will depend on which `key` is passed in; therefore, the `T` above could only be dynamically determined based on the runtime computation. It inherently cannot be resolved at compile-time, and therefore it is not statically typed. Rust is not alone in offering this kind of generic types; many programming languages use a similar logic for determining types at compile time. It just gets fuzzy if one is used to languages that maintain types at runtime and do not enforce restrictions like the one I outlined above. These type systems are often said to offer “parametric polymorphism”; I mention that solely to give you some guidance for a term to search for when goggling this subject. (Though I will say up front that a lot of the results you get on this topic can be very academic and language research-oriented.) Here is a tutorial that may help you get a handle on the concepts here: http://lucacardelli.name/Papers/BasicTypechecking.pdf (Yes, it is from 1987. I think that is why it probably one of the better descriptions I was able to find quickly: At that time, these ideas were not as widely popularized as they were today, so Cardelli took his time explaining the notions and assumed little about the audience.) rust-dev members: If others know of freely available introductions to this topic, I’m all ears; I just didn’t see any obvious winners in my searches. Cheers, -Felix On 22 Jul 2014, at 14:24, Aravinda VK wrote: > Sorry for the incomplete mail. > > What I wanted is, > get_value(MyStr("Rust".to_str())) returns String, > get_value(MyBool(true)) returns bool and, > get_value(MyInt(100)) returns int > > I was trying to store generic value in hashmap, as in the example below, > > use std::collections::hashmap::HashMap; > > #[deriving(Show)] > enum MyTypes{ > MyBool(bool), > MyStr(String), > MyInt(int) > } > > fn main(){ > let mut settings:HashMap = HashMap::new(); > > settings.insert("port".to_str(), MyInt(8000)); > settings.insert("name".to_str(), MyStr("Rust".to_str())); > settings.insert("enabled".to_str(), MyBool(true)); > > println!("{}", settings); > } > > So to get the value out of hashmap, I need a generic function which checks > the respective type and returns value. Some thing like > > fn get_value(settings:HashMap, key: &'static str) -> T{ > match settings.get(&key) { > MyBool(x) => x, > MyStr(x) => x, > MyInt(x) => x > } > } > > But I don't know how to make this work. > > Thanks. > > > > On Tue, Jul 22, 2014 at 4:55 PM, Felix S. Klock II > wrote: > Aravinda (cc’ing rust-dev)- > > You didn’t show us exactly what you had tried to do to get your code to work, > nor did you really describe what it is you want here. > > E.g. you seem to want `get_value(MyBool(true))` to return a boolean, but > since `MyBool` belongs to the `MyTypes` enum, that implies that `get_value` > when applied to any variant of `MyTypes` (including `MyInt` or `MyStr`) > should also return a boolean … does that seem right to you? > > In any case, I suspect the missing piece of the puzzle for you is that you > need to write an `impl` for the type in question. I.e. something along the > lines of: > > impl MyTypes { > fn render(&self) -> String { > match *self { > MyBool(x) => format!("{:b}", x), > MyStr(ref x) => x.clone(), > MyInt(x) => format!("{:d}", x), > } > } > } > > (except revised from an Impl for the type to being an impl of some trait for > the type). > > Here is a link to a playpen with your code, and with a couple of example > `impl`s for enums (like the one above) tossed in, including an impl of one > instance of your `Value` trait. > > http://is.gd/RofN9R > > There is more discussion of writing implementations that also provides an > example with a simpler enum) in the Rust tutorial, see: > > http://doc.rust-lang.org/tutorial.html#methods > > Cheers, > -Felix > > On 22 Jul 2014, at 11:45, Aravinda VK wrote: > > > Hi, > > > > I am trying to create a generic function to return value depending on the > > enum passed. But I don't know to create a generic trait for enum. > > > > In
Re: [rust-dev] How to write Generic traits for enums
Sorry for the incomplete mail. What I wanted is, get_value(MyStr("Rust".to_str())) returns String, get_value(MyBool(true)) returns bool and, get_value(MyInt(100)) returns int I was trying to store generic value in hashmap, as in the example below, use std::collections::hashmap::HashMap; #[deriving(Show)] enum MyTypes{ MyBool(bool), MyStr(String), MyInt(int) } fn main(){ let mut settings:HashMap = HashMap::new(); settings.insert("port".to_str(), MyInt(8000)); settings.insert("name".to_str(), MyStr("Rust".to_str())); settings.insert("enabled".to_str(), MyBool(true)); println!("{}", settings); } So to get the value out of hashmap, I need a generic function which checks the respective type and returns value. Some thing like fn get_value(settings:HashMap, key: &'static str) -> T{ match settings.get(&key) { MyBool(x) => x, MyStr(x) => x, MyInt(x) => x } } But I don't know how to make this work. Thanks. On Tue, Jul 22, 2014 at 4:55 PM, Felix S. Klock II wrote: > Aravinda (cc’ing rust-dev)- > > You didn’t show us exactly what you had tried to do to get your code to > work, nor did you really describe what it is you want here. > > E.g. you seem to want `get_value(MyBool(true))` to return a boolean, but > since `MyBool` belongs to the `MyTypes` enum, that implies that `get_value` > when applied to any variant of `MyTypes` (including `MyInt` or `MyStr`) > should also return a boolean … does that seem right to you? > > In any case, I suspect the missing piece of the puzzle for you is that you > need to write an `impl` for the type in question. I.e. something along the > lines of: > > impl MyTypes { > fn render(&self) -> String { > match *self { > MyBool(x) => format!("{:b}", x), > MyStr(ref x) => x.clone(), > MyInt(x) => format!("{:d}", x), > } > } > } > > (except revised from an Impl for the type to being an impl of some trait > for the type). > > Here is a link to a playpen with your code, and with a couple of example > `impl`s for enums (like the one above) tossed in, including an impl of one > instance of your `Value` trait. > > http://is.gd/RofN9R > > There is more discussion of writing implementations that also provides an > example with a simpler enum) in the Rust tutorial, see: > > http://doc.rust-lang.org/tutorial.html#methods > > Cheers, > -Felix > > On 22 Jul 2014, at 11:45, Aravinda VK wrote: > > > Hi, > > > > I am trying to create a generic function to return value depending on > the enum passed. But I don't know to create a generic trait for enum. > > > > In following example, print_value works but I don't know how I can write > a generic get_value function to get value from enum. > > > > #[deriving(Show)] > > enum MyTypes{ > > MyBool(bool), > > MyStr(String), > > MyInt(int) > > } > > > > fn print_value(arg: MyTypes){ > > match arg{ > > MyBool(x) => println!("Bool: {}", x), > > MyStr(x) => println!("String: {}", x), > > MyInt(x) => println!("Int: {}", x), > > } > > } > > > > > > fn main(){ > > print_value(MyBool(true)); > > > > // Following lines not working, how to write get_value func? > > // let a: bool = get_value(MyBool(true)); > > // println!("{}", a); > > } > > > > > > In case of struct it is simple, > > > > struct MyInt { > > value: int > > } > > > > struct MyBool{ > > value: bool > > } > > > > trait Value{ > > fn get(&self) -> S; > > } > > > > impl Value for MyInt{ > > fn get(&self) -> int{ > > self.value > > } > > } > > > > impl Value for MyBool{ > > fn get(&self) -> bool{ > > self.value > > } > > } > > > > fn get_value>(arg: T) -> S{ > > arg.get() > > } > > > > fn main(){ > > let a: bool = get_value(MyBool{value: true}); > > println!("{}", a); > > > > let b: int = get_value(MyInt{value: 100}); > > println!("{}", b); > > } > > > > Please help in writing generic function for enum. > > > > > > > > -- > > Regards > > Aravinda | ಅರವಿಂದ > > http://aravindavk.in > > ___ > > Rust-dev mailing list > > Rust-dev@mozilla.org > > https://mail.mozilla.org/listinfo/rust-dev > > -- Regards Aravinda | ಅರವಿಂದ http://aravindavk.in ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] How to write Generic traits for enums
Aravinda (cc’ing rust-dev)- You didn’t show us exactly what you had tried to do to get your code to work, nor did you really describe what it is you want here. E.g. you seem to want `get_value(MyBool(true))` to return a boolean, but since `MyBool` belongs to the `MyTypes` enum, that implies that `get_value` when applied to any variant of `MyTypes` (including `MyInt` or `MyStr`) should also return a boolean … does that seem right to you? In any case, I suspect the missing piece of the puzzle for you is that you need to write an `impl` for the type in question. I.e. something along the lines of: impl MyTypes { fn render(&self) -> String { match *self { MyBool(x) => format!("{:b}", x), MyStr(ref x) => x.clone(), MyInt(x) => format!("{:d}", x), } } } (except revised from an Impl for the type to being an impl of some trait for the type). Here is a link to a playpen with your code, and with a couple of example `impl`s for enums (like the one above) tossed in, including an impl of one instance of your `Value` trait. http://is.gd/RofN9R There is more discussion of writing implementations that also provides an example with a simpler enum) in the Rust tutorial, see: http://doc.rust-lang.org/tutorial.html#methods Cheers, -Felix On 22 Jul 2014, at 11:45, Aravinda VK wrote: > Hi, > > I am trying to create a generic function to return value depending on the > enum passed. But I don't know to create a generic trait for enum. > > In following example, print_value works but I don't know how I can write a > generic get_value function to get value from enum. > > #[deriving(Show)] > enum MyTypes{ > MyBool(bool), > MyStr(String), > MyInt(int) > } > > fn print_value(arg: MyTypes){ > match arg{ > MyBool(x) => println!("Bool: {}", x), > MyStr(x) => println!("String: {}", x), > MyInt(x) => println!("Int: {}", x), > } > } > > > fn main(){ > print_value(MyBool(true)); > > // Following lines not working, how to write get_value func? > // let a: bool = get_value(MyBool(true)); > // println!("{}", a); > } > > > In case of struct it is simple, > > struct MyInt { > value: int > } > > struct MyBool{ > value: bool > } > > trait Value{ > fn get(&self) -> S; > } > > impl Value for MyInt{ > fn get(&self) -> int{ > self.value > } > } > > impl Value for MyBool{ > fn get(&self) -> bool{ > self.value > } > } > > fn get_value>(arg: T) -> S{ > arg.get() > } > > fn main(){ > let a: bool = get_value(MyBool{value: true}); > println!("{}", a); > > let b: int = get_value(MyInt{value: 100}); > println!("{}", b); > } > > Please help in writing generic function for enum. > > > > -- > Regards > Aravinda | ಅರವಿಂದ > http://aravindavk.in > ___ > 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] How to write Generic traits for enums
Hi, I am trying to create a generic function to return value depending on the enum passed. But I don't know to create a generic trait for enum. In following example, print_value works but I don't know how I can write a generic get_value function to get value from enum. #[deriving(Show)] enum MyTypes{ MyBool(bool), MyStr(String), MyInt(int) } fn print_value(arg: MyTypes){ match arg{ MyBool(x) => println!("Bool: {}", x), MyStr(x) => println!("String: {}", x), MyInt(x) => println!("Int: {}", x), } } fn main(){ print_value(MyBool(true)); // Following lines not working, how to write get_value func? // let a: bool = get_value(MyBool(true)); // println!("{}", a); } In case of struct it is simple, struct MyInt { value: int } struct MyBool{ value: bool } trait Value{ fn get(&self) -> S; } impl Value for MyInt{ fn get(&self) -> int{ self.value } } impl Value for MyBool{ fn get(&self) -> bool{ self.value } } fn get_value>(arg: T) -> S{ arg.get() } fn main(){ let a: bool = get_value(MyBool{value: true}); println!("{}", a); let b: int = get_value(MyInt{value: 100}); println!("{}", b); } Please help in writing generic function for enum. -- Regards Aravinda | ಅರವಿಂದ http://aravindavk.in ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev