Re: [rust-dev] Thoughts on the Rust Roadmap
On 12/31/2013 08:06 AM, Carter Schonwald wrote: as a counter point, in strongly typed languages (of which rust is one), the type checker is a great aid in fixing breaking changes :). In fact it makes addressing such breakages quite easy. This is pretty notable in other strongly typed langs like haskell, when theres been breaking changes, its usually less than 30 minutes of work to fix any breakages in an entire code base, with the exception of libraries that (ab)use exotic experimental features in ways that are tricky to write otherwise. IN fact, one breaking change that is scheduled for next year in haskell actually had the most vocal support from industrial users, including several organizations that have financial trading systems using the language. point being, in a strongly statically typed language, when making (small/ thoughtful) breaking changes to core apis or type system details, its quite manageable to identify all the points of breakage in client code, and the main issue is moreso the quality of the error messages. (and theres always room for better error messages :) ). admittedly its always ideal to get the design right the first time, but sometimes its worth it to improve a tool at the expense of its users (happily) spending half an hour or so placating the type checker after the language update. happy new year! -Carter While I seriously doubt about 30 minutes for an entire code base (even small) (if only because one does not always maintain one's own code, or it's several people's code, or one has switched to other projects in the meantime), I do otherwise agree because I often break my own code intentionnally after rethinking, rewriting or just cleaning low-level utilities (an app's inner lib so to say). Usually a quick and easy fix, actually even in dynamically-typed langs (even with rather weak typing like Lua). I also share the last point sometimes it's worth it to improve. I would not count backward compatibility as important as, less so having precedence over, language quality (same about libs and tools). Either an envisioned improvement makes a significant difference in quality and we _ought to_ do it; or not. In any case, this does not prevent making the life of maintainers of existing code as nice and easy as possible, but let us not engrave design error in marble ;-) as if they were natural laws. [*] I know this is a very unpopular position thought ;-) Denis [*] Not to speak of design errors propagating from successful (lol!) languages to others. = for assignment and == for equality is still the source of my favorite syntactic mistake, after decades of programming mostly in mainstream languages that all implement that funny convention (let's use, say, if instead of try, and then have, say, switch or altern [or iff!] mean if as a replacement). ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] on quality success
On 12/31/2013 01:43 PM, Till Schneidereit wrote: Without responding to everything in your message, two quick points: For being written by someone afraid 'of the terrible level of violence, in [your] view, present in the programming community', your message is awfully condecending and dismissive of a huge amount of hard work by curageous people. The Rust designers have made it very clear that they don't share your views on how much the language should differ from pre-existing widely-used languages. You seem to say that that necessarily means that they're conformist cowards who only do their work for 'fame, honour, status, money, power' or '[t]o mentally masturbate on the idea of having made something sucessful'. Would you say that to someone's face? If not (actually, regardless), please don't do it on a mailing list. As for your main argument (as far as I understand it), that languages are designed too timidly, I quite simply don't believe that you don't see the argument that a language might not be adopted if it breaks with too many conventions that people have gotten used to. You're saying that you'll gladly try out languages that break with everything you learned before. That's commendable, but not something a language designer can expect of everyone in their target audience. Now you might disagree with the strategy of introducing enough change to make the language clearly superior to its competition, while keeping the learning curve bearable. Please don't dismiss it as madness you don't even need to argue against, though. You seem to reply to another message than mine. Or maybe it is (as often) my failure in expressing my thought. two quick points, as you say * This post is not about Rust, not at all in fact: it's sent to a mailing list about PL-design in general. I indicate (at start of post) that the reason for a copy here is the reflexion is inspired by a thread on rust-dev. (Also, I imagined some here may be interested.) * I don't have the impression to give the impression to be condescending or whatnot; in fact, instead of excluding myself (and though it was not done in purpose, rather just an illustration) I explicitely state not beeing brave enough. Anyway, anyone may receive anything as they will. Denis PS: As for the quotes you take, indeed they look agressive out of context. But they are questions in the original text and, at least I hope so, they mean something different in context, and with a different spirit as the one you expose. Also, again, this post is not about Rust's development (if it were so, I would not be interested in this language... why do I follow the mailing list rust-dev if I do not regard it as a good project?) Finally, since you attack me on this point: yes, I speak that way to people face to face (and they don't take it as you do, rather most people are grateful when one speaks truly; never mind). ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Thoughts on the Rust Roadmap
On 12/30/2013 05:29 PM, Patrick Walton wrote: In general I understand the concern, but there are also a huge number of people who just want the language to stabilize so that they can use it in production. The window for relevance is finite and we've been designing the language for a *long* time at this point. I understand and share this view, but see it as one side of the story: the other side beeing that the language has evolved pretty much in recent times, and this in part about several core features (pointer management, traits, basic data structures, error handling...). Obviously much remains unclear to the proto-user-base, and is felt as unstable and susceptible to drastic evolution still (maybe it's not for you, but maybe you are wrong on this ;-). I guess a significant number of people would prefere seeing the language go on evolving the time needed to have it reach a point where at least core constructs look like beeing close to as good as possible (considering the state of present knowledge about programming is or should be: read, probably much too few). I personly would cry when I see Rust ending up beeing yet another failed replacement for C (for the present, it would be so in part because it's much too difficult to use). Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Thoughts on the Rust Roadmap
On 12/30/2013 02:00 PM, Armin Ronacher wrote: Hi, I am not using Rust nearly as much as I wish I could, but I absolutely love playing around with it and seeing where it's heading. I think all things considered the language is going exactly where I want it to go. It's for the most part very pleasant to work with and it's getting better and better. But there is so much more work needed. Not just because the language is lacking things that are needed, but because many users of the language are not sure yet how to use it. The compiler and the standard library use widely different patterns and so do libraries written by other people. There are half a dozen ways to deal with errors now, there are different patterns of how to deal with Options and Results. There are vastly different ways to design whole APIs, how to deal with the traits and so forth. There are different patterns to interface with native libraries, different patterns to interface with task local data etc. The introduction of external iterators (which I found the most exciting change of the language) has shown a whole new area of shortcomings in the current feature set (lack decltype when returning composed iterators for instance, non sendable closures etc.). Not only did it show shortcomings in lacking features, it also put some emphasis on new patterns that are not widely deployed in the stdlib yet. I really hope there is left enough time to actually continue evolving the language and libraries before freezing anything. Especially now that the split into libnative and libgreen is happening it will be important to stay flexible for adjusting the design of the standard library so that we don't end up with two vastly different ways to do IO. It does not take a genius to realize that there is already some tension among developers with regards to where the language should be going, and at what pace. As an outside observer that is very much in love with Rust and where it's heading, I want to voice the wish that there will be enough time to continue evolving the language before racing to a 1.0 release. Especially now that there is a lot of interest in Rust and similar languages I believe this is necessary. As it stands right now, there are too many things that make Rust still frustrating because you program yourself into a corner. TL;DR: please don't rush a 1.0 release. +++ ; couldn't have said it better Question: what is the timeline, if any? Remark: we programmers have already waited for 40 years for a usable replacement for C: safe, meaningful, expressive (and I'm still waiting for it). Rust could be it (but not in present or near-future state: much too hard to use). 2, 3, 5 years more is nothing. Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Rust crates and the module system
On 12/14/2013 05:28 AM, Liigo Zhuang wrote: There is an official tool called rustpkg, and there is a attribute call pkgid, so you cann't just easily saying there is no package in rust. If no package, why not using rustcrate and crateid for consistency? (I do not think 'crate' is a good name, other languages tend to call it 'package' or 'library'.) Agreed. And library should be left alone as a set of packages, as in std lib. Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Rust crates and the module system
On 12/13/2013 11:43 AM, Diggory Hardy wrote: What would you do? Have no structure (no mod)? Or automatically create it from the file structure? I think this is a good possibility, make the module/crate organisation mirror the filesystem (or the opposite): * 1 module = 1 file of code * 1 package = 1 dir This may be limiting at times, possibility one may want multi-module files and multi-file modules. But this forms a good, simple base (anyway, we have mini maxi modules code files, whatever the logical physical organisations). Another point is that very often we have package (I mean crate ;-) sub-dirs which are not packages themselves. Then, as usual, we'd have a special code file representing a package at its top dir (the same name as the package, or a magic name like 'main'). Then, module sharing is code file sharing, and package management is dir management (trivially .zip-ed or .tar.gz-ed, and then the name package is here for something). Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Interface around SQL databases
On 12/11/2013 06:04 PM, Patrick Walton wrote: We aren't likely to block 1.0 on this. Instead of stabilizing all libraries once and for all in 1.0 like Go did, we're taking a gradual approach to libraries similar to that of node.js, in which 1.0 will have some library modules stable and some modules unstable, and releases 1.1, 1.2, and beyond will stabilize more and more libraries as time goes on. A good thing, I guess, especially in that the latest trend in Rust seems to be moving primitives into the library. Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Let’s avoid having both foo() and foo_opt()
On 12/09/2013 04:53 PM, Damien Radtke wrote: I have no idea if it would be feasible in the standard library, but wouldn't the ideal solution be having one function (e.g. from_utf8()) that could return two possible values, a bare result and an Option? Letting the compiler decide which version to use based on type inference like this: let result: ~str = from_utf8(...); let result: Option~str = from_utf8(...); Assuming both of them are passed invalid UTF8, then the first version would fail, but the second version would just return None. Again, I don't know if it's possible given the current implementation, but I do think it would be helpful to have a picture of the ideal, [...] This is indeed close to an ideal version ;-), isn't it? Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Let’s avoid having both foo() and foo_opt()
On 12/07/2013 10:53 AM, Simon Sapin wrote: On 07/12/2013 01:07, spir wrote: Maybe it's only me, but this not at at all clear to my eyes. My imagined soluton (for a totally different lang) was something like this, on the caller side: ucodes = s.utf8_decode()!// source should be correct, error on failure ucodes = s.utf8_decode()?// logical failure expected, return None or whatnot This is interesting, but I’d like to discuss what to do in this particular language, Rust that is trying to go to 1.0 and will probably not accept such syntax change :) You are right, indeed! ;-) But the issue exists anyway... dunno about solution. In fact we'd ned to invert the logic: instead of: x = foo() // Option element wrapping possible result x = foo().unwrap() // bare result think: x = foo().option() // Option element wrapping possible result x = foo().direct() // bare result or even x = foo() // bare result Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Let’s avoid having both foo() and foo_opt()
On 12/07/2013 02:08 AM, Jordi Boggiano wrote: On Sat, Dec 7, 2013 at 2:01 AM, spir denis.s...@gmail.com wrote: On 12/07/2013 01:12 AM, Gaetan wrote: I am in favor of two version of the api: from_str which has already done the unwrap, and a from_str_safe for instance that returns a Result or option. This provides the important semantic information (that I've evoked at the end end of a long earlier reply in this thread) of whether func failure is expected and belongs to the logic of the present app and we must deal with it, or not. But I'm still shared on this topic for finding it also annoying, like Simon, to have to duplicate whole catogories of such funcs (of which we cannot know in advance whther they'll fail or not), if only the interface as apparently proposed by Gaëtan. Syntax sugar like this would be nice: let str = std::str::from_utf8(Parse this optimistically, and fail otherwise); // str is a string or the task fails vs. let opt_str = std::str::from_utf?(Parse this if valid); // note the question mark if opt_str.is_some() { } That's it! This makes it clear whenever the anomalous case nevertheless belongs to the present application's logic (hopefully rare). Problem is, this sounds scary to implement at the compiler level, if it's possible at all :) I am just throwing it out there for others to judge. Yes. Requires certainly a bit of machinary, even if thought so from the beginning. But optional tasks exist, semantically, whether the language acknowledges them or not. And an Option type only solves half of the issues: namely the ones of functions properly speaking (which compute a value); what about actions (which perform an effect)? How can Option help the caller know, without failing (halting the program on error), whether one has been unable to perform its task? How can one know whether this data structure was properly updated, this visual object moved, this msg given to the user, this file extended, renamed, deleted...? There are also, semantically, optional data in function def input and type defs... very annoying in a statically typed language ;-) Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Let’s avoid having both foo() and foo_opt()
On 12/07/2013 12:57 PM, Devin Jeanpierre wrote: On Sat, Dec 7, 2013 at 3:33 AM, spir denis.s...@gmail.com wrote: But the issue exists anyway... dunno about solution. In fact we'd ned to invert the logic: instead of: x = foo() // Option element wrapping possible result x = foo().unwrap() // bare result think: x = foo().option() // Option element wrapping possible result x = foo().direct() // bare result In what way is this better? Seems to me it's a basically functionless layer of abstraction, and things that don't always have a usable result should always return option, and if you want them to fail, you can request failure via .unwrap(). If this is too verbose, then we should make it less verbose, e.g. `x = *foo()` or something. Or we can keep the status quo, which seems fine to me. I'm not really picky about verbosity. Possibly it's clear for you if you are used to the Option workaround, from other languages (I have been, in fact, from Ocaml). But with this solution the code does not say what it means (lol!), not to speak of idioms repeted everywhere in source as evoked by Gaetan (and similar to Java, in fact (lol bis!)). However, in my view, this is not a question of verbosity, but of having source code match (sic!) the semantics, what we actually mean. A solution would be to have such functions return either a bare result, or an Option wrapping a possible result, depending on how they are called (instead of '?', there may be a bool param, why not?). But not a functional either/or, this would doubly wrap the result! Instead really either one or the other. Indeed, this is not possible in standard in a statically typed language, reason for other solutions, such as one evoked in a previous mail: have an 'anomaly' flag somewhere, possibly a bare pointer for error data, and minimal syntactic support. In fact, simple error management (I don't mean exception handling) may require being taken into account in language design righ from the start, even more than testing debugging, for instance; but all 3 of those meta-programming dimensions are related anyway. Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Let’s avoid having both foo() and foo_opt()
On 12/06/2013 09:41 PM, Simon Sapin wrote: We have some functions and methods such as [std::str::from_utf8](http://static.rust-lang.org/doc/master/std/str/fn.from_utf8.html) that may succeed and give a result, or fail when the input is invalid. 1. Sometimes we assume the input is valid and don’t want to deal with the error case. Task failure works nicely. 2. Sometimes we do want to do something different on invalid input, so returning an `OptionT` works best. And so we end up with both `from_utf8` and `from_utf8`. This particular case is worse because we also have `from_utf8_owned` and `from_utf8_owned_opt`, to cover everything. Multiplying names like this is just not good design. I’d like to reduce this pattern. Getting behavior 1. when you have 2. is easy: just call `.unwrap()` on the Option. I think we should rename every `foo_opt()` function or method to just `foo`, remove the old `foo()` behavior, and tell people (through documentation) to use `foo().unwrap()` if they want it back? The downsides are that unwrap is more verbose and gives less helpful error messages on task failure. But I think it’s worth it. What do you think? (PS: I’m guilty of making this worse in #10828, but I’d like to discuss this before sending pull requests with invasive API changes.) [A bit long, sorry, this is a topic about which i have thought for a while.] There may be a more complicated general pattern, of all kinds of functions that may not be able to perform their nominal task, due to invalid input, but the client cannot know whether the input is valid without more or less reproducing said task. Checking utf8 validity is about the same job as decoding, for instance, to reuse your example. Compare with a function computing the average value of a collection of numbers (or the sum, product, std-dev, etc...) which is passed an empty collection: here the client can know, thus: 1. if this abnormal case does not belong to the app's logic, the client should just call the func stupidly so that the func failure is a signal of logical error on the app side 2. if instead this case belongs to the app's logic, the client should first check, and never call the func in this special case Thus, despite very possible failure, there should here be only one version of the func (no *_opt), one that stupidly fails, with a stupid error msg. Back to the cases where the client cannot know before calling. To this category belong a whole series of search/find functions, and many dealing with the file system, user input, input in general. In the latter case, a func's input is in fact not (all) provided by the client. But there is the same pattern of anomalous cases which may, or not, belong to the app logic (1. or 2. above): is it correct (if special or exceptional) that such file does not exist, or such collection does not hold the searched item? Meaning, should I deal with such cases? If not, if such a case does not belong to the application logic, again I should stupidly call a func that stupidly fails with a stupid error msg, so I am told, simply and early, of my logical errors. These are true errors (not so-called exceptions), and the failure is a symptom or signal, a good thing (if, indeed, what you want is making good software). I *want* it; and want it so! I'm in favor of simple funcs doing simple tasks simply, and just failing in anomalous cases, for these reasons. [1] Remains the situation combined of such funcs, of which the client cannot know whether they will be able to perform their task, and of abnormal cases belonging to the logic of the app (there are also whole categories of maintenance and safety modes here). For such situations, it looks somewhat logical to have 2 versions, I guess. Playing a bit with words: 1. when I ask to _find_ something, I take it for granted the thing is somewhere there, and expect a location in return 2. when I ask to _search_ something, I do not take anything for granted, and expect in return _either_ not there! or a location This duality applies both to the so-called real world (despite blur natural language word meanings) and software worlds, and extends to all cases, it seems. We can certainly find a way, using Option or another mean, to combine both categories of situations (1. or 2.) using a single tool, but this should be very well done, and ensure that: * In cases of category 1., developers are warned about their errors exactly as if they had called a stupidly failing func. * At the semantic (conceptual) level, the duality of categories remains somehow preserved, including in source code. About the latter, in particular it should be obvious in code, without knowledge of language arcanes or weird idioms, that (or whether) the caller expects a success unconditionally -- because (and in other words that) the anomalous case just does not belong to this app; this is critical information to the reader. How to do that right? PS: I take the
Re: [rust-dev] Let’s avoid having both foo() and foo_opt()
On 12/07/2013 01:12 AM, Gaetan wrote: I am in favor of two version of the api: from_str which has already done the unwrap, and a from_str_safe for instance that returns a Result or option. This provides the important semantic information (that I've evoked at the end end of a long earlier reply in this thread) of whether func failure is expected and belongs to the logic of the present app and we must deal with it, or not. But I'm still shared on this topic for finding it also annoying, like Simon, to have to duplicate whole catogories of such funcs (of which we cannot know in advance whther they'll fail or not), if only the interface as apparently proposed by Gaëtan. Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Let’s avoid having both foo() and foo_opt()
On 12/07/2013 01:55 AM, Simon Sapin wrote: On 07/12/2013 00:49, spir wrote: About the latter, in particular it should be obvious in code, without knowledge of language arcanes or weird idioms, that (or whether) the caller expects a success unconditionally -- because (and in other words that) the anomalous case just does not belong to this app; this is critical information to the reader. How to do that right? If my proposal is accepted (returning Option is favored), then calling .unwrap() is the way to express that success is expected. unwrap() causes task failure when called with None. Maybe it's only me, but this not at at all clear to my eyes. My imagined soluton (for a totally different lang) was something like this, on the caller side: ucodes = s.utf8_decode()! // source should be correct, error on failure ucodes = s.utf8_decode()? // logical failure expected, return None or whatnot (But maybe _this_ is obscure to your eyes?) Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Rust forum
On 12/03/2013 11:01 PM, Martin DeMello wrote: keeping up with email is a lot easier than pretty much everything else, though. the solution to keeping old messages around is mirroring the mailing list to a searchable archive, not moving to a forum en masse and sacrificing ease-of-conversation for ease-of-recall. Agreed. Plus, with emails everyone can *also* filter / categorise / search according to their own preferred rules on their preferret email client. [I have always hated forums for such reasons, plus they force one to explore, search, navigate, online, without any control.] Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Rust forum
On 12/03/2013 09:41 PM, Martin DeMello wrote: On Tue, Dec 3, 2013 at 12:32 PM, Thad Guidry thadgui...@gmail.com wrote: Users benefit from the developers list and vice-versa... splitting us apart would not be a wise choice. the only downside is that people are reluctant to ask newbie user questions on a list where people are talking about hacking on the compiler. Very true. Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Can traits define instance vars?
On 12/02/2013 11:12 AM, jeti...@web.de wrote: Hello, I lately had a look at Rust and really liked it in many ways. Rust has really everything I'm missing in Go ;-). There is something about traits I would like to ask I can't see from the manual. Question is whether you define instance variables in traits or abstract variables like Ceylon and Kotlin have them. Abstract traits vars in Kotlin look like this (sample code taken from here: http://blog.jetbrains.com/kotlin/2011/08/multiple-inheritance-part-2-possible-directions): trait Trait { val property : Int // abstract fun foo() { print(property) } } class C() : Trait { override val property : Int = 239 } Can something like this be done for traits in Rust as well? Then I would like to ask whether you are planning to have some Rust forum for users. The question I was asking in this mail on rust-dev really doesn't belong into the dev mailing list. So something like a google Rust-users newsgroup would be a good thing to have. I know several people that are interested in Rush. Think it would give Rust a little push if a Rust-user forum would exist. Regards, Oliver I would love it. Of the 2 cases of custom traits I have defined do far in Rust, one is only about 3 instance vars (thus ends up empty), the other about 1 vars and 1 method (thus holds only the latter). I find traits weird without vars, and annoying since the compiler does not know that the conforming types _do_ have such vars (thus one is forced to down-cast for no other reason that vars are absent from the trait def, or do i miss a point?). This, in addition to control of actual conformity of types to declared traits. Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Placement new and the loss of `new` to keywords
On 12/02/2013 09:43 AM, Eric Reed wrote: I think the 'new(place) expr' or 'box(place) expr' is pretty confusing syntax. To me, it's not at all clear that new(varA) varB means eval varB and put it into varA instead of eval varA and put it into varB. I'd much prefer syntax that makes it very clear which is the expression and which is the place. Personally, I like ~ so I'd like ~expr in place, but if people absolutely insist on scrapping ~ then I'd suggest put expr in place. In either case, I think keeping ~ as sugar for allocating on the exchange heap would be nice (i.e. ~expr is sugar for ~expr in Unique or put expr in Unique). I guess we could use new or box instead of put, but I like put over either. What about: box(place, expr) box(expr, place)# better for me box expr in/to place# pure syntactic magic ? The latter may seem weird, but anyway box or new or whatever aren't functions in the ordinary sense. Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Placement new and the loss of `new` to keywords
On 12/02/2013 11:57 AM, Kevin Ballard wrote: With @ going away another possibility is to leave ~ as the normal allocation operator and to use @ as the placement operator. So ~expr stays the same and placement looks either like `@place expr` or `expr@place` I like that, with expr@place. Does this give: let foo = ~ bar; let placed_foo = bar @ place; ? Yet another solution, just for fun, using the fact that pointers are supposed to point to: let foo = - bar; let placed_foo = bar - place; Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Rust forum
On 12/02/2013 07:15 PM, Kevin Ballard wrote: Personally, I’ve never met a forum that I cared for. Mailing lists are nice. I second the idea of a rust-users ML. Same for me. denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Placement new and the loss of `new` to keywords
On 11/30/2013 08:10 AM, Kevin Ballard wrote: As I said in the IRC channel, the reason why users often don't realize that `~T` is allocation, is not a failure of syntax, but a failure of documentation. The only reason why a user would know that `new Foo` allocates is because they've been exposed to that syntax from another language, one that actually documents the fact that it allocates. Users who haven't been exposed to `new Foo` from other languages will have no reason to understand that this allocates without being told that it allocates. As such, there is no reason why we cannot simply fix the documentation to explain that `~` is the allocation operator, and that when it's used in an expression it means it allocates a value. It was then explained to me that the real reason we needed `new` wasn't because of the issues with users understanding allocation, but because of a need for placement new. That is why I suggested some alternative syntaxes. Also, FWIW, `~(n + m)` makes sense, as a way of producing an allocated value from the result of `n + m`, but `new (n + m)` is pretty nonsensical. Since this issue is all about placing something into memory, why not use 'mem' ? Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Placement new and the loss of `new` to keywords
On 11/30/2013 11:24 AM, György Andrasek wrote: On 11/30/2013 09:34 AM, Patrick Walton wrote: IMHO sigils made sense back when there were a couple of ways to allocate that were built into the language and there was no facility for custom smart pointers. Now that we have moved all that stuff into the library, sigils seem to make less sense to me What really bugs me about `~` is that it conflates the idea of lifetime and ownership (which is a zero-cost annotation) with allocation (which is an actual expensive operation to stay away from). This wasn't a problem with `@`, but it's gone now. My choice would be to keep `~` in types, but use `new` for allocation: let foo: ~Foo = new Foo(bar); Looks quite nice :-) and nicely separates syntax items for kind of pointing and watch, runtime mem alloc ahead!. (However, as others have noted, 'new' in itself means nothing; for non-C++-ers like myself, a proper term would be better.) Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Mentoring + E-easy
On 11/26/2013 10:03 AM, Brandon Sanderson wrote: I'd definitely be in support of the change to easy tagging - I've seen quute a few issues where I've thought 'I could do this' but then realized I have no idea where to start. On 2013-11-26 12:59 AM, Corey Richardson co...@octayn.net wrote: Same for me. Even if it's obviously easy, even trivial, (1) there are usually some annoying, unknown points of the lang itself involved (2) we don't know the code base! People seem never to take the latter point into account when tagging the difficulty level of an issue to be solved, while in fact it is the main barrier; not the difficulty of correcting the issue itself. A trivial, 3 min, correction can require weeks of discovering, understanding, digesting, the relevant parts of the code base. Side-note: as a consequence, un-quality, in particular un-clarity, of a code base is for me the blocker #1 to participation. A possible good side-effect to this mentoring project is that it may help improve code clarity and overall quality: novices will stump on numerous code issues, and mentors themselves will feel uneasy when having to explain bad parts of the code. == amelioration Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] byval byref (was: The need for iterators that return by value)
On 11/22/2013 07:01 AM, Tommi wrote: Now, off-topic: I've been trying to post the following question to this mailing list for like 4 times, but no dice. I seem to have better luck when replying to posts, so here it goes: struct Value { n: int } impl Value { fn squared(mut self) - Value { self.n *= self.n; self } } fn main() { let x = Value{ n: 3 }; let y = x.squared(); println!({} {}, x.n, y.n); // prints 9 9 } self isn't being passed by value to squared, since x.n gets mutated as well. This must be a bug, right? That is not what I'd expect, in any case! ;-) PS: cannot run the code, get: _.rs:12:16: 12:19 error: found `self` in ident position _.rs:12 fn squared (mut self) - Value { ^~~ ??? (also, underlining looks wrong; unless the actual error is about mut?) Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Please simplify the syntax for Great Justice
On 11/20/2013 04:03 AM, Val Markovic wrote: Fair point. I give you guys a lot of credit though, Rust is a wonderful language in general. I also admire how willing core Rust devs are to admit ok that was a bad idea, let's try something else. I don't see that every day; Rust is better for it. Please continue being awesome. Agree. Thank you all very much for this effort, and for making it public good. Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Removing some autoref magic
On 11/20/2013 02:51 PM, Bill Myers wrote: Have you considered making deref the default instead and requiring moves to use an explicit move keyword? Basically, from this hypothetical syntax to current one: - x = x - mut x = mut x - move x = x One could even make the implicit in parameter types in function declarations unless the move keyword is used, so we would have (new = old syntax): - fn(self, ...) = fn(self, ...) - fn(mut self, ...) = fn(mut self, ...) - fn(move self, ...) = fn(self, ...) I like this proposal, because afaik it matches the common use case. Also, it would make things easier to learn, understand, and use, for people not used to move semantics (even less to it as default / implicit case). I do struggle with move; making it explicit would help (also when reading it other people's code). Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] list of all reserved keywords of the language
On 11/19/2013 12:09 PM, Daniel Micay wrote: The `loop` keyword still exists for the moment, but only for infinite loops. I'd prefer removing it and just using `while true { ... }`. My view on conditionned loop is something like: loop [while cond] { ... [continue if cond] ... [break if cond] ... } [until cond] An infinite loop is just when there is neither start, nore end condition. Or replace loop with do (only for brevity), continue with next or up, break with exit or out (the latter 2 for clarity). Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Please simplify the syntax for Great Justice
On 11/19/2013 10:12 AM, Jordi Boggiano wrote: Often there is an alternative to pooping sigils all over the code, but if you don't understand the concepts behind it it's hard to reason about what those alternatives could be. +++ This is what I'm asking for about pointer variety and memory management in Rust. What does this all mean? Semantics, please ;-) (I mean human semantics, no machine operations) Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Please simplify the syntax for Great Justice
On 11/19/2013 10:51 AM, Gaetan wrote: In the french presentation for rust 0.8 [1], the author gives the analogy with C++ semantics - ~ is a bit like unique_ptr - @ is an enhanced shared_ptrT - borrowed pointer works like C++ reference and I think it was very helpful to better understand them. I don't know if it is true or now, but this comparison helps a lot understanding the concepts.You can present them like this, and after, add more precision, and difference with the C++ counter parts. A tutorial to make would be Rust for C++ programmer :) [1] http://linuxfr.org/news/presentation-de-rust-0-8 This helped me too, even if I'm not a C++ programmer (can only read). However, it is still not enough to understand the meaning of each of those pointer varieties, imo (at least, _i_ still don't get it). What semantic kinds of pointed data should go to each variety? why? I would help at once improving the tutorial if I did understand. @Daniel: I would answer your questions if I did understand the *logic* of Rust's pointers and memory management. The tutorial, in my view, should precisely help on this. Instead, it tells us about machine-side issues without meaning (which are important and we need to know, but don't help in understanding). What is the semantic counter-part of all this? Why does it exist? The logic here is hidden or difficult. As a comparison, we don't need tons of explanations to understand the differences between a sequential collection (array, list) and, say, a set. The logic is nearly obvious, we easily get why both kinds exist. And in fact, the machine-side, implementation counterpart, while important, comes after, once we understand the meaning; then we get to know the price one has to pay for quick, direct access of given items, as opposed to access by index. Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Please simplify the syntax for Great Justice
On 11/19/2013 12:51 PM, Daniel Micay wrote: So in your opinion, what's wrong with the `Boxes` section? http://static.rust-lang.org/doc/master/tutorial.html#boxes I happen to think it does a pretty good job of explaining why `~` is required for recursive types, which is almost the only use case for it from a purely semantic perspective (not worrying about performance). If this is all true, that recursive structures are the main, almost the only use case of ~ pointers, then the tutorial is in my view rather ok on this point. But then, why does it seem there are ~ pointers in every corner of Rust code? Including numerous cases in the tutorial itself. Also, how would we explain and term this meaning? Indirection is not good enough (for we introduce indirections for other reasons, if only to have variable-size content). I'd say self-similarity is the right term here, and self-explaining (see wikipedia if you are not familiar with the idea). This is, in fact, the actual idea commonly termed recursivity in programming (wrongly, in my view, but this is yet another terminological issue). A rule about ~ pointers thus may be: Whenever one needs self-similarity, use a ~ pointer. This lets the language store the element through the kind of indirection that permits a self-similar structure. (I'm not happy of this formulation, neither, still obscure.) however, other comments on ~ pointers (eg comparisons with C++ unique_ptr, notes that it means owned or my) introduce ideas rather different from the one you suggest here, don't they? Say I manually create a kind of string or fix-size array: struct String { n_bytes : uint, bytes : ~[u8], } struct Array Item { n_items : uint, items : ~[Item], } Is it wrong here to ~ point to bytes or items? that's what I'd do, anyway... If it is right, maybe the actual meaning of ~ is something like proper content. Whenever a structure actually contains content which is actually proper to it, or more generally has (pointed) data participating to its description, then these contents or descriptive data should pointed with ~: because they belong / are proper to it. struct ComplexVisualForm { shape : ~ Shape, style : ~ Style, } This matches my distinction between things and data (properly speaking). Data, even when pointed (for technological rather than semantic reasons), still belong to whatever they are part of. Data are never referenced (properly speaking), it makes no sense. Things instead exist by themselves, are always ref'ed, never copied (or moved), it makes no sense. If the reasoning above about ~ pointers is more or less correct (i doubt it is), then we have in Rust the proper kind of pointer to point to data, properly speaking, meaning information about things. Now, to reference things from multiple points of view, we need something else, proper refs or links, and they cannot be ordinary pointers (especially not GC'ed): we need true refs, independant from the data (while pointers hold their addresses). Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] freeing of locals
Hello, say a function defines 4 pointed elements of data. Depending on logical conditions, one of them escapes the func to be assigned to some world variable (static or on heap), while another is returned. How does Rust determine which of those data are to be freed? Seems this can only be done dynamically, at runtime, or do I miss a relevant point? Is there a cheap algo to do this? (Also, those elements of data can be arbitrarily complex, and hold other pointed data which themselves may be placed there conditionally.) Thank you, denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] typed loop variables int num types
These are 2 points of secondary importance (or even less). What about the following pattern: for x:Type in expr { // proceed with x } as equivalent to: for y in expr { let x = y as Type; // proceed with x } both for iterator loops and range loops? Actually, my need is to have uint's or u8's in range loops, while the default is int. I'm also unhappy with let n = 1; yielding by default an int instead of an uint. I would suggest that if an int value is unsigned, the default type is uint. A signed int is, semantically, a difference, thus always signed: to get a default signed int, just write let n = +1;. Seems both logical and self-documenting, imo. Again, quite unimportant and definitely not of high priority. Just sending this for the record. Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] tutorial (bis)
I'm exploring the tutorial Rust for Rubyists at [http://www.rustforrubyists.com/book/book.html], which in fact is not (only) for rubyists, as stated in the introduction. Looks pretty good to me (just my opinion), should definitely be pointed to from the Rust Docs page at [https://github.com/mozilla/rust/wiki/Docs], and in good place. As a tutorial, it is in my view far better than the official one, and is up-to-date (Rust 0.8), so maybe even just replace it; with a warning note. The official tutorial is not a bad doc in itself (I guess) but is definitely not a _tutorial_: in fact, it requires quite a knowledge of Rust, its fundamental concepts and jargon. Rust for Rubyists certainly has room for improvement, but it _is_ for sure a tutorial. I would definitely suggest to start writing a new official tutorial by using Rust for Rubyists as raw material. A first pass may be to make it slightly more general, just requiring prior programming experience; Rust definitely is not a language for programming novices, anyway. Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] typed loop variables int num types
On 11/15/2013 01:27 PM, spir wrote: [...] Thank you Huon Daniel, your replies answer my needs. I supported the issue about removal of signed `int` as default (BAD! ;-). Actually like `for i in range(1u, 9u)` as an alternative for `for i:uint in range(1 ,9)`, but there also, there should be not int as default. Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] tutorial (bis)
On 11/15/2013 03:55 PM, Marijn Haverbeke wrote: As the author of the original tutorial I'm interested in what people hate so much about it. It appears to have slightly bit-rotted, in that the language moved on and people haphazardly updated stuff here and there, but the bulk of it still looks coherent. Can I get some concrete pointers? Very personal point of view: As I said elsewhere, I definitely don't find it bad as a document in itself. Rather, it is not a tutorial at all, in my view; quite the opposite. I would consider it as a spec summary, a useful reminder for someone having learned and used Rust once, then let it down for while and coming back to it. I'd read this doc to refresh my mind. That it also is outdated is a distinct issue (a more easily fixable one). Side-note: I read the (big) french article on Rust 0.8 [2] and found it rather good as well. With this, Marijn's doc, and Rust for Rubyist, we already have quite an amount of raw materiel to make a tutorial. The big, big remaining issue is the QoPaMM (Question of Pointers Memory Management ;-). I have not yet found any presentation satisfying *for me* (I insist: personal point of view). The problem is: how to make sense out of the mess? What does all that *mean*? Or: semantics, please! [1] The reason to choose this or that kind of pointer, or this or that kind od MM should be semantic: that they correspond to different kinds of elements in the app('s) model [3]. I have yet to find such a correspondance; until then, I find myself unable to write anything about that. Since now, I choose pointer kinds in a totally adhoc manner (except for as func input, the only situation where it makes sense for me). Denis [1] 'semantic' means 'about meaning', not 'about what the machine does' ;-) [2] [http://linuxfr.org/news/presentation-de-rust-0-8], pointed to at the bottom of the 'Blogs' section of the Rust Docs web page [https://github.com/mozilla/rust/wiki/Docs] [3] Questions of efficiency or such possibly coming in a later phase of development or thinking. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Implementation complexity
On 11/15/2013 05:52 AM, Patrick Walton wrote: * One of the BIG problems with D uptake is the split library problem referred to before. They could not get a comfortable standard library for a long time, despite some extremely bright and decently famous engineers working on D. My understanding is that it's mostly been solved now (after what, 10 years?). That'd be a disaster for Rust if things split badly at the interface level. I agree, and I would like to prevent divergence. Divergence of *implementation* is OK and probably inevitable if Rust succeeds; divergence of API for no reason can harm the ecosystem. If I may say a word on this (I have also been a D user), all this may well also be a human problem. People feel badly whenever decisions on points important for them are taken in opaque, rush, or uncooperative manners. D's first official stdlib was somewhat like that, and felt more or less undesigned (or unsufficiently); while the core language was already quite good, pleasant, strongly usable. I'd rather wait one or even two or three years more than expected for Rust 1.0 and get a design that most joyfully support or at least agree with... After all, we are waiting for a good static, systems programming language for, what, 40 years? (Please, don't rush for 1.0, take the time needed.) Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Rust docs
I completely share your views, Daniel. [Would have expressed them myself if I did not know (from experience) that constructive critics by me (in english) usually are mistaken or misunderstood: people just deny, argue, or reply violently. But you do a good job, here, in my opinion.] Denis On 11/14/2013 04:03 PM, Daniel Glazman wrote: Hello rust-dev, I would like to make a comment I feel is important about both the Rust tutorial and manual. Please don't misunderstand me, no flame here, I am sending this message to help. I think good docs are extremely important to increase the size of a community, and in particular make more people contribute to Servo (the reason why I'm here). If the Reference Manual for Rust tries to be complete and does not try to avoid language complexity, it can be from time to time hard to read because of one thing: examples are not well or often enough explained and are often too complex given the section they belong too. It's for instance difficult for the reader to understand an example of section n that uses notions explained only in section n+4. The Tutorial is the entry point for all people willing to investigate Rust and/or contribute to Servo. I think that document is super precious, super-important. Unfortunately, I don't think it is really a tutorial but only a lighter manual. Examples are here even more important than in the case of the Manual above. A good Tutorial is often built around one single programming task that becomes more and more complex as more features of the language are read and known. Furthermore, the Tutorial has clearly adopted the language complexity of the reference manual, something that I think should be in general avoided. I also think all examples should be buildable and produce a readable result on the console even if that result is a build or execution error. That would drastically help the reader. All in all, I think the Tutorial needs some love and probably a technical writer who is not working on the guts of Rust, someone who could vulgarize the notions of the Manual into an easy-to-read, simple-to-experiment, step-by-step tutorial and avoiding in general vocabulary inherited from programming language science. Best regards, /Daniel ___ 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] Rust docs
Could there be a kind of rust-tutorial-in-progress wiki page? (with required subscription to edit). Seems to me the easiest path to cooperative edition. Then, just have a single person responsible for regularly pushing the 'in progress' version as the 'offical' one, whenever its state is ok. Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] mutability cascade
Hello, I have an error cannot assign to immutable field. However, it is mutable as I understand according to inherited mutability rule exposed in the tutorial (section 'Structs'). The field in question is in a struct itself item of an array, itself field in a super-structure (lol!) which is self. All this happens in a method called on mut self. (And the compiler lets me change self elsewhere in the same method.) Thus, what is wrong? Or is it so that the mutability cascade is broken due to the array? How then restore it and be able to change a struct item's field? I guess arrays are mutable by default aren't they? (Or else, here it should due to inherited mutability, since it is a field of a mutable struct.) What do I miss? [Code below untested yet due to error.] fn expand (mut self) { // A mod table expands by doubling its list bucket capacity. // Double array of lists, initially filled with NO_CELL values. let NO_CELL : uint = -1 as uint;// flag for end-of-list self.n_lists *= 2; self.lists = vec::from_elem(self.n_lists, NO_CELL); // replace cells into correct lists according to new key modulo. let mut i_list : uint; let mut i_cell : uint = 0; for cell in self.cells.iter() { // Link cell at start of correct list. i_list = cell.key % self.n_lists; cell.i_next = self.lists[i_list]; // ERROR *** self.lists[i_list] = i_cell; i_cell += 1; } } I take the opportunity to ask whether there's an (i, item) iterator for arrays. Thank you, Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] mutability cascade
On 11/13/2013 02:06 PM, Huon Wilson wrote: On 13/11/13 23:55, spir wrote: Hello, I have an error cannot assign to immutable field. [...] You need to use the .mut_iter() method, [T].iter() yields T references, while the former yields mut T references (and can only be used on vectors that have mutable contents, like ~[T] in a mutable slot, or mut [T] or @mut [T]). http://static.rust-lang.org/doc/master/std/vec/trait.MutableVector.html#tymethod.mut_iter Right, that's it, i guess. PS: tested: works fine! (Unfortunately the docs are not good with respect to built-in types. Methods can only be implemented on built-ins via traits, and the indication that the built-ins implement a trait is only shown on the page for the trait itself.) Actually, the vec module's doc tells which traits are implemented [http://static.rust-lang.org/doc/0.8/std/vec/index.html]. However, it's just too much at once for newcomers, in my opinion. There may be a subset of simple, base functionality for vectors (but as someone said, the vec module needs reorganisation). I take the opportunity to ask whether there's an (i, item) iterator for arrays. You can use the .enumerate() method on iterators, so for (i, cell) in self.mut_iter().enumerate() { ... } http://static.rust-lang.org/doc/master/std/iter/trait.Iterator.html#method.enumerate Right what I needed! PS: tested: works fine! (Also, you will possibly meet with mutable borrow complaints (I'm not 100% sure of this), which you can address by destructuring self, so that the compiler knows all the borrows are disjoint: let StructName { lists: ref mut lists, cells: ref mut cells, n_lists: ref mut n_lists } = *self; and then use `lists`, `cells` and `n_lists` (they are just mut references pointing to the corresponding fields of self).) Huon Haven't met this issue yet, but I keep the pattern under the pillow for later usage. Thank you very much, Huon, for all this clear information. Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Please simplify the syntax for Great Justice
On 11/11/2013 09:46 PM, Corey Richardson wrote: I don't think Rust can succeed as a language if it massively differs, visually, from the language it intends to offset (C++). I don't think Rust can succeed as a language if it massively resembles the language it intends to offset (C++). Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Implementation Inheritance / mixins
On 11/11/2013 09:16 PM, Oren Ben-Kiki wrote: At any rate, I'm not claiming this is necessarily the best approach for Rust; I'm just wondering, what is the proposed way to address this use case? None of the manual approaches seems very appealing (unless there's a better one I missed). My preferred approach is explicite derivation. May look like: struct S1 { x1 : uint, x2 : uint, x3 : uint = 1, x4 : uint = 1, fn f1 () {...}, fn f2 () {...}, } struct S2 [: S1] { // optional subtyping for polymorphism x1 : uint, // same field x2 : uint = 2, // same field, with std value x3 : uint = 1, // same field, same std value x4 : uint = 2, // same field, diff std value x5 : uint, // new field x6 : uint = 2, // new field, with std value fn f1 () = S1.f1, // same func, same value (reuse) fn f2 () {...}, // same func, diff value (override) fn f3 () {...}, // new func } // more structs derived from S1 An advantage is that each new type is completely defined on place; except for the body of reused functions, but one still has the signature and knows where the body is to be found. This apparently brings no novel issue and avoids a few know problems due to conventional inductive or recursive inheritance. All methods are right here. In theory and practice, I guess, one can well reuse from various existing types any suitable method; or more generally any role, trait, in ordinary sense of the terms. In case of conflict, the user explicitely states which one is intended, and there is no diamond problem. But the main gain in my view is that this scheme provides very good auto-documentation, I guess. I have however no idea of how to implement that in a static lang, esp the subtyping aspect (but do think it's no more complicated, maybe even less) (I implemented it in Lua, rather easy). Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] linking to cells inside a data structure
Hello Rust people, A data structure holds (unpointed) cells in an array. Then, a number of linked lists part of the data structure link to those same cells. What is the right Rust way to do that? I cannot have the language accept the instruction establishing a link, whatever kind of pointer I use (both for self and for cells). Code and/or details on demand. Denis PS: It is in fact a hash table [1] which buckets are link lists as usually, but the cells are stored in an array instead of spread around the memory at the allocator's convenience ;-). First advantage is indeed entries are in order. (To move on in the meanwhile, I'll remove this aspect.) [1] Actually a mod table since keys are uints, there is no hash, only modulo. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] copying pointers
Hello, The ref manual speaks of copying pointers [http://static.rust-lang.org/doc/0.8/rust.html#pointer-types]: Managed pointers (@) These point to managed heap allocations (or boxes) in the task-local, managed heap. Managed pointers are written @content, for example @int means a managed pointer to a managed box containing an integer. Copying a managed pointer is a shallow operation: it involves only copying the pointer itself (as well as any reference-count or GC-barriers required by the managed heap). Dropping a managed pointer does not necessarily release the box it points to; the lifecycles of managed boxes are subject to an unspecified garbage collection algorithm. Owning pointers (~) These point to owned heap allocations (or boxes) in the shared, inter-task heap. Each owned box has a single owning pointer; pointer and pointee retain a 1:1 relationship at all times. Owning pointers are written ~content, for example ~int means an owning pointer to an owned box containing an integer. Copying an owned box is a deep operation: it involves allocating a new owned box and copying the contents of the old box into the new box. Releasing an owning pointer immediately releases its corresponding owned box. Borrowed pointers () These point to memory owned by some other value. Borrowed pointers arise by (automatic) conversion from owning pointers, managed pointers, or by applying the borrowing operator to some other value, including lvalues, rvalues or temporaries. Borrowed pointers are written content, or in some cases f/content for some lifetime-variable f, for example int means a borrowed pointer to an integer. Copying a borrowed pointer is a shallow operation: it involves only copying the pointer itself. Releasing a borrowed pointer typically has no effect on the value it points to, with the exception of temporary values, which are released when the last borrowed pointer to them is released. But what is the syntax to do that? I always get errors related to moving, which i don' twant to do. In particular, how does one establish or modify link list links? Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] copying pointers
PS: What would be, in fact, the rusty way for a simplissim linked list. I use Option~Cell for now, to have something clean (None) to end the list, since Rust looks rather functional. But as always with Option this way quite obscures and complicates the code (Some() expressions, match expressions...). I'd rather just use a NULL pointer, for here it is fully safe. But this does not look rusty at all, I guess. What is your view? Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] formats 'Standard' {} and 'Poly' {:?}
Hello, Well, I wonder if we could exchange those formats. Here is how they work: fn main () { struct P {i:uint, j:uint}; let (b, u, i, x, c, s, a, p) = (false, 1u, -1, -1.11, 'c', abc, [1,2,3], P{i:1,j:2}); let z : Optionuint = None; // Poly println!({:?} {:?} {:?} {:?} {:?} {:?} {:?} {:?} {:?}, b, u, i, x, c, s, a, p, z); // == false 1u -1 -1.11 'c' abc [1, 2, 3] main::P{i: 1u, j: 2u} // Standard println!({} {} {} {} {} {}, b, u, i, x, c, s); // == false 1 -1 -1.11 c abc } The format 'Poly {:?}: * works for all types, including app defined, does not require trait definition or declaration * just does the right thing, telling the programmer all what is needed in an exact and complete manner (except main:: is too much maybe) The format 'Standard' {}: * requires definition of trait 'Standard' for complex types (arrays, structs, enums), as well as its declaration for type variables * is ambiguous about chars and strings, as well integers (signed?) In other words, 'poly' gives us back the notation of data, as we (would) have noted them in code. Also, its tells us the type, if implicitely, except for the exact size of a number. This information is what we need in the general case for all kinds of feedback in program testing, diagnosis, debugging... The standard notation of data is not always the best possible form, but it always does the job and we are used to it. I guess we'll constantly use it for our own feedback. For this reason, I'd like to exchange the notations of these formats: have Poly be {} so that we are less annoyed at typing it. And call with a meaningful name, such as Notation, Literal or... Standard. I have no idea what the other format (the one currently noted {} and called Standard) is good for. I'd say it can be used as part of user output, but we already have good type-specific formats for that. Maybe this format is a polyvalent form of those specialised formats, so that we don't need to choose: then call *this one* poly... Also, noting this one {:?} would make sense. Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] returning an item from a collection
Hello, I am searching for the easy or standard way to return an item from a collection. Here is a fictional example showing the issue: struct CollItem { items : ~[Item] } implItem CollItem { fn first (self) - Item { // this line is for comments below: let it = self.items[0];// error return it; } } fn main () { let coll = Coll{items:~[1,2,3]}; println!(first : {:?}, coll.first()); } == _.rs:12:18: 12:30 error: cannot move out of dereference of pointer _.rs:12 let it = self.items[0]; I could not find any clue in docs. Have tried several approaches, finally succeeded with the following: implItem:Clone CollItem { fn first (self) - Item { let it = self.items[0].clone(); return it; } } I find that surprising. A few questions: * What does the error *mean* ? * Is this solution the right way? * What alternatives exist, if any? * What is the difference between copy and clone? * Why does clone work and not simple copy? About the latter 2 questions, well, for me, y = x just copies x into y [1]; and clone is just a synonym of copy. Where am I wrong? That we copy should remove any pointer safety question, shouldn't it? (This consideration was my lead to find a solution.) Again, where am I wrong? The doc of the module 'clone' reads: The Clone trait for types that cannot be implicitly copied In Rust, some simple types are implicitly copyable and when you assign them or pass them as arguments, the receiver will get a copy, leaving the original value in place. These types do not require allocation to copy and do not have finalizers (i.e. they do not contain owned boxes or implement Drop), so the compiler considers them cheap and safe to copy. For other types copies must be made explicitly, by convention implementing the Clone trait and calling the clone method. This is all good and makes sense for me. But then, in the first code example above, the compiler does not know anything about the copy-ability of Val specimens. How does it then interpret the line: let it = self.items[0]; The only way to make sense of that is to copy, isn't it? What else? Then, the language should require Val to declare the trait Clone, shouldn't it? And there should not be a need for an explicit copy via the clone method in my view... Again, what other sense but copying does the compiler assign to a simple assignment y=x ? Finally, is it so that for generic collections, item types must always be declared the Clone trait, else we just cannot read them? Same for generic struct fields? (If I add a field of type Item in Coll, I also cannot read it out without error.) Denis [1] shallow copy: the pointer, if x is a pointer, the façade struct is x is such an thing, etc... ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] formats 'Standard' {} and 'Poly' {:?}
On 11/11/2013 01:18 PM, Daniel Micay wrote: The reflection-based `{:?}` doesn't follow the privacy rules, so it will never be a format with a stable output. The low-level implementation details of a type aren't a sensible format for any application to be using. Provided it goes on doing the right thing, meaning ~ reproducing data notation, I'm happy with it. I don't think `std::reflect` and `std::repr` should even be available outside of debug builds because they're a huge backwards incompatibility hazard and prevent Rust from exposing a stable ABI for a reasonable subset of the standard library. It is for programmer feedback anyway. If 'poly' is removed, I cry. It promises to be the best and most common tool Rust provides to programmers. A way to solve that issue, preventing this format to be mis-used for app output, may be to have funcs specific for programmer feedback, which in standard use 'poly' [1]. Other writing funcs, for app output, would not normally use it. More generally, it may be a good idea to (more) clearly separate meta features for programmer help from app modelling features. I think the following is a great example: ``` use std::hashmap::HashMap; fn main() { let mut xs = HashMap::new(); xs.insert(5, 5); println!({:?}, xs); } ``` The output is not even usable for debugging, unless what you're debugging is the hash table implementation: You are right. But the reason for a programmer to print out a hashmap should be to debig it. Else, we should ask for different or more precise data (eg, its size, or the buckets). ``` std::hashmap::HashMapint,int{k0: 16592526953366606085u64, k1: 12349690536349946653u64, resize_at: 24u, size: 1u, buckets: ~[None, None, None, None, None, None, None, None, Some(std::hashmap::Bucketint,int{hash: 10818539429618494536u, key: 5, value: 5}), None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]} ``` Any type containing a hash table or a tree is going to have totally unusable output too. It quickly becomes unusable for anything that's not a thin wrapper around primitive types. As said, it cannot be perfect in all cases. At times, we will need custom formats even for programmer feedback. Alternative: change the 'poly' format for hashtables. (But as it is, is looks good to me: it says what we need, and can barely be made more compact or readable.) What I would change is presenting structs (maybe arrays as well) in multiline format whenever some of their fields (items) are complex. This would give: std::hashmap::HashMapint,int { k0: 16592526953366606085u64, k1: 12349690536349946653u64, resize_at: 24u, size: 1u, buckets: ~[None, None, None, None, None, None, None, None, Some(std::hashmap::Bucketint,int{hash: 10818539429618494536u, key: 5, value: 5}), None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None] } Denis [1] When the language lets me do it, such a programmfeedback func is the first utility I write. I call it note (as they write data notation) or note* when I can have several of them. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] returning an item from a collection
On 11/11/2013 02:47 PM, Felix Klock wrote: Denis (cc'ing rust-dev)- Thank you very much, Felix, for this clear and exhaustive reply. How does it then interpret the line: let it = self.items[0]; The only way to make sense of that is to copy, isn't it? What else? An assignment expression can denote either a copy or a *move* of the right-hand-side into the left-hand-side. Note that your goal (returning an item from a collection) is unclear, in that I cannot tell whether you want to move item out of the collection, or make a copy of it, or provide a shared reference to the item in the collection (but without removing it from the collection). All right. Seems 'move' is to be understood quite literally, no? The datum so-to-say ceases to exist at its original place? I want to copy because (or so it seels to me) it is the standard need: we want something equivalent. (By copy I do not mean deep copy or copy of contents or of target, for a data structure, collection, or pointer. Just the façade.) Anyway, the error message says cannot move out of dereference of pointer In this case, the assignment expression is being interpreted as an attempt to move content out of self.items[0]. But you cannot move the item out of the l-value denoted by that expression, for a couple different reasons (such as: `self` is an immutable borrow, so you cannot modify it; and also, even if you changed the borrow to be a mutable borrow, you still could not use the expression you want to extract the first item, since the vector needs something to replace the content that was removed). More or less what I understood, but thank to you clearer. Maybe you are more used to languages like Java/Scheme/ML/Haskell/etc, where a parameter or local variable denotes a *reference* to the value in question, and thus can be freely copied? To get that effect in Rust, and thus allow multiple references to some shared piece of state, you need to use some explicit pointer/reference type. Here is some code to illustrate what I'm saying. Note that you should probably favor a data-structure representation where you can call the vec `pop()` method rather than `shift()`; compare the source code for each in vec.rs to see why. ```rust struct CollItem { items : ~[Item] } implItem CollItem { // *Moves* the first element out of self. // (Doing so requires that we mutably-borrow self.) fn first (mut self) - Item { // ^^^ this is new let it = self.items.shift(); // ^ so is this return it; } // Provides reference to first element of self. fn first_ref'a ('a self) - 'a Item { // Note: The lifetime 'a tells us that the reference will // survive only as long as the immutable-borrow of self. let it = 'a self.items[0]; return it; } } fn main () { let mut coll = Coll{items:~[1,2,3]}; // ^^^ this is also new. { // This {} block acts effectively as the lifetime 'a for the // call to first_ref. // First lets take a reference, `fref`, into coll... let fref = coll.first_ref(); println!(first ref : {:?}, fref); println!(coll : {:?}, coll); // ... which will only live until here... } // ... which is important, because we need to *mutably* // borrow `coll` in order to invoke `first()` here. println!(first : {:?}, coll.first()); println!(coll : {:?}, coll); } ``` All right! I'll keep this code aside for whenever I need these alternatives (ref or move). I conclude that for reading or returning an item by copy, using clone is the right way to go (if the item type is a variable). Correct? Also, what does let y = x; mean in Rust if x's type is constant (as opposed to a generic type var)? Does it depend on the exact type? and specifically what happens in the case of simple, atomic, type? Cheers, -Felix ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] About owned pointer
On 11/09/2013 06:43 AM, Kevin Ballard wrote: On Nov 8, 2013, at 9:38 PM, Daniel Micay danielmi...@gmail.com wrote: On Sat, Nov 9, 2013 at 12:36 AM, Kevin Ballard ke...@sb.org wrote: On Nov 8, 2013, at 2:21 PM, Patrick Walton pcwal...@mozilla.com wrote: I know that many people don't like the fact that, syntactically, vectors and strings have a sigil in front of them, but please consider that there are many design constraints here. What works for another language may not work for Rust, because of these constraints. Personally, I find it great that they have a sigil in front of them. It reminds me that they're stored in the heap. -Kevin Since library containers, smart pointers and other types don't have them, I don't think it's helpful in that regard. Well no, you can't assume that the absence of a sigil means the absence of heap storage. But for types that are possibly not stored on the heap, such as str (which can be 'static str) and [T] (which can be a fixed-size stack-allocated vector), the ~ is a useful distinction. -Kevin Can we, then, even consider the opposite: having a sigil for static data (mainly literal strings stored in static mem, I'd say) or generally non-heap data (thus including eg static arrays stored on stack)? The advantage is that this restores coherence between all heap of heap data. I'd use '$'! (what else can this sign be good for, anyway? ;-) [But where should the sigil go? In front of the data literal, as in let stst = $Hello, world!; let nums = $[1,2,3]; or in front of the type, or of the id itself?] Also, is it at all possible, in the long term maybe, to consider letting the compiler choose where to store, in cases where a possible pointer is meaningless, that is it does not express a true reference (shared object, that a.x is also b.y), instead is used for technical or efficiency reasons (that memory is not elastic!, for avoiding copy, etc...)? Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] About owned pointer
On 11/09/2013 08:36 PM, Niko Matsakis wrote: See my other e-mail about choosing a representation for `*T`. I am currently thinking that the representation of `~T`, `T`, and `*T` should be the same for all `T`. I think this addresses a number of issues and opens up new capabilities, though it does mean an unused capacity word for `[T]` and `*[T]`. See issue #10295. Well, you may need it in fact. When I did implement slices for a trial (more or inspired by and copying D), I used this free word as a flag (with value 0) saying that extension is not allowed: one cannot push items into or concatenate a slice. Otherwise, arrays and slices are the same kind of thing; and in my case, there was a single type, as in D, arrays just are original slices, slices are arrays, except one cannot extend them. The remaining issue is, as in D again, the case of an array, of which slices exist, that later gets extended: in the general case (where extension requires realloc elsewhere), this invalids slices. Reason why I ended up concluding slices should only exist for fix-size thingies; anyway it's the case in practice afaik, since slices are extensively used (and a huge efficiency gain) on strings mainly. The D design, as I see it, thus brings a low level of safety; but their goal, on this point, is not to reach a level as high as Rust aims, I guess. Would be happy to read your thoughts on such topics. Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] About owned pointer
On 11/08/2013 05:47 PM, Igor Bukanov wrote: C++'s `string` and `vectorT` are objects containing two or three pointers. For that one pays performance penalty in C++ as string and vector instances are passed by references resulting in double indirection when accessing the elements. I suppose it could help to think about strings in Rust similar to variable-sized structs in C like: struct MyString { unsigned int bytelength; unsigned int data[]; }; As in Rust such struct cannot be instantiated and one typically uses malloc/alloca to allocate instances and then just pass around the resulting pointers. I like this version precisely for the reason it avoids double indirection. I use it whenever I need weighted strings in C (strings that know their weight, Pascal strings in fact) [1]. It works fine, is easy on the implementation side, just terribly annoying w/o syntactic support. Same for arrays, both fixed (but variable, in the sense of not predefined) and dynamic size. It's all fine in my view for a language like Rust, provided it remains an implementation choice. Meaning, whether the representation of say a static array is a {p, n} struct or such a variable-sized structs is transparent on the language side. What are the present implementations of strings and arrays in Rust? And what about fixed size (esp for strings)? Denis [1] Actually, I rather just use a pointer, with the size written before the first string byte or array item, like true Pascal strings, but the result is the same. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] About owned pointer -- explicit specification
On 11/08/2013 09:43 AM, Gaetan wrote: I agree, I don't understand the syntax here. Look at the Url class: pub struct Url { scheme: ~str, user: OptionUserInfo, host: ~str, port: Option~str, path: ~str, query: Query, fragment: Option~str } pub type Query = ~[(~str, ~str)]; fn split_char_first(s: str, c: char) - (~str, ~str) { ... if index+mat == len { return (s.slice(0, index).to_owned(), ~); } } Isn't simpler, and easier to read, if we write it pub struct Url { scheme: str, user: OptionUserInfo, host: str, port: Optionstr, path: str, query: Query, fragment: Optionstr } pub type Query = [(str, str)]; fn split_char_first(s: str, c: char) - (str, str) { ... if index+mat == len { return (s.slice(0, index).to_owned(), ); } } KISS ! - Gaetan Sure! I'd strongly support that (exactly the changes you propose). But I thought the obligation to explicitely specify the pointer type was a side-effect of the variety of pointer kinds in Rust: If in Rust one is to able to choose which kind of pointer is used, then, well, we must write it down somewhere somehow, no? Some of the strings or arrays above (or more generally structured data), may be shared, referenced from other structured thingies, in which case we'd need a non-owned pointer (probably @). Or do I misunderstand? Somewhat related but distinct, I thought we could get rid of specifying the pointer type for function input: seems to be always , no? Or mut when changed inside the func, but the compiler can probably tell that; also, if the param is not changed, having mut does not affect the semantics anyway... Or, if pointed function input is not always / mut, systematically, in current Rust code, could it be anyway, without exaggerated semantic constraint or efficiency loss? Still related but distinct, what other uses for (and mut) than function input? Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] About owned pointer
On 11/08/2013 09:53 AM, Daniel Micay wrote: It couldn't be called `str`, because `str` is a slice. Why couldn't str be slices? (eg somewhat like arrays are slices in D) Also, i don't understand literals in Rust currently. Same for static arrays. Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] About owned pointer
On 11/08/2013 07:20 PM, Patrick Walton wrote: Because then `str` would not be a dynamically sized type. (I'm not convinced --yet-- strings *must* have dynamic size at all, as I never need this feature even if I do quite a lot of text processing. When generating runtime produced strings, I'd rather concat all bits at once at the very end, thus knowing the final size. No support for this is needed: one never writes into a growable string buffer, instead always concat all at once. But this may be another, distinct story. And there may be use cases I'm unaware of, even common ones.) Please read the blog posts on dynamically sized types. All right, I'll do. PS: Except I cannot find them. Don't seem listed in the list of blog post at https://github.com/mozilla/rust/wiki/Docs Also not in the archives of your own blog at: http://pcwalton.github.io/blog/archives/ Denis spir denis.s...@gmail.com wrote: On 11/08/2013 09:53 AM, Daniel Micay wrote: It couldn't be called `str`, because `str` is a slice. Why couldn't str be slices? (eg somewhat like arrays are slices in D) Also, i don't understand literals in Rust currently. Same for static arrays. Denis ___ 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] the inter-play of struct type impl, traits, type params
Hello, New to Rust. Is there (already) a list for mutual help in the usage of Rust? If not, I guess it may be worth having one, distinct from the dev list, even if the language is a moving target, even for people who rather intend, at terms, to participate in the development. It is in fact even more needed due precisely to the constant change of the lang, to the fact it is mostly unknown, and to the state of the docs. In the meanwhile... see below. Also please pardon wrong ideas or statements: I am presently discovering the language. (Also, english is a foreign lang for me.) As an exercise in learning the language, I am trying various ways to implement sparse arrays (association list, trie, modulo table = hash table w/o hash), the aim being to determine the nr of entries from which it is worth switching to a more complicated version. But I'm far from there yet, stumbling on diverse issues right for the simplest bits of code. Below, I'm talking of the interrelation between struct type declaration impl, type params, and traits. type Key = uint; struct PairListVal { ... } implVal:fmt::Default PairListVal { ... } implVal PairListVal for Iterable { ... } === trait implementation === A first point which I find annoying is the splitting of impl for traits a struct explicitely implements. This means that each time we need to use a generic func for the *usage* of an *instance* of a type, we have to modify this type's *definition* with a new impl section for the corresponding trait(s) required by the generic feature. Or do I misunderstand? (This, even if the the trait is actually implemented, I mean the methods exist, or am I wrong again?) I find that exagerated. Why not just add a declaration of the trait at the top of the struct type def? struct PairListVal : Iterable { === impl itself === As a side note, I also do not understand the purpose of the impl section altogether. I would be happy with: * either the methods inside the struct def: struct PairListVal { fn push (self, key:Key, val:Val) {...} } * or a simple form outside the struct def: fn PairList.push (self, key:Key, val:Val) {...} It is stated somewhere that the impl section nicely separates the fields from the implementation, but this is a question of taste: one could trivially reply this section invents a strange notion of implementation (after all, data fields also are implementation, or rather also definition), and forces to tell apart things that logically fit together. Anyway, it's a question of perspective... I'd vote for the second form above, because it is a kind of intermediate choice. Another advantage is it gives a name to the method (PairList.push). === the meaning of impl for trait sections === Also, I'm not clear about whether impl for trait sections form a kind of namespace. Can there be methods with equal names in diverse such sections (and/or in in th impl section or section not related to traits)? If yes, then it would be in my view a bad idea. Instead, make a kind of standard naming scheme for trait methods. Else, what do such sections mean? === impl type params === As shown above, for a struct type with type params, we have to repeat the said type params in the impl section's headline, and this in fact twice! (I had a hard time with that point.) These repetitions make no sense, in my view, since the type param belongs to the struct type anyway, esp the one after impl; but this one repetition precisely is where to declare traits on type params... see below. I could live with the repetition after the struct type name, as if the type param belonged to the name of the struct type: impl PairListVal { (but as said I would happily forget about impl sections altogether) === traits used === For programmer feedback (read: debug) I need to write out pair-lists (indeed). An issue is that the Val type is a parameter. Since any form of structured output itself requires a format (if only '?') and such formats are traits (! why?), I need to declare this trait (fmt::Default) as belonging to Val --yes, the type param... But where? I had to search for a while before stepping on the right place: as written above right after impl itself. The logical place to make this declaration would be the concerned method, here 'write'. But the said method does not take any Val instance as input, just self: so that there is no place there to declare that Val implements fmt::Default. Or how are we to do it? === universal traits === A distinct but related issue is this trait fmt::Default is supposed universal. Could type params have those universal traits? so that we don't have to declare them. Or better, they are not traits. === everything is a trait === Apparently, in the latest dev of Rust, about everything becomes a trait. This gets crazy ;-). I guess it is wrong in that it over-complicates the language, and there is no limit. Moreover, these layers of
Re: [rust-dev] the inter-play of struct type impl, traits, type params
On 11/05/2013 06:17 PM, Patrick Walton wrote: On 11/5/13 2:44 AM, spir wrote: That you very much for this complete answer, Patrick. Things are clearer. Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] struct def
I can write this: struct Points {xs:~[uint], ys:~[uint]} fn main () { let mut ps = Points{xs:~[1u], ys:~[1u]}; ... } But I cannot write that: struct PointsT {xs:~[T], ys:~[T]} fn main () { let mut ps = Pointsuint{xs:~[1u], ys:~[1u]}; ... } In the second case, I get the error: sparse_array.rs:106:31: 106:32 error: expected one of `; }` but found `:` sparse_array.rs:106let mut ps = Pointsuint{xs:~[1u], ys:~[1u]}; ^ Sorry to bother you with that, I find myself unable to find the right syntactic schema (and could not find any example in any doc online). I'm blocked, stupidly. spir@ospir:~$ rust -v rust 0.8 host: x86_64-unknown-linux-gnu Also, I have a general problem with writing struct instances with the type apart; meaning, without any type param, I get the same error: struct Points {xs:~[uint], ys:~[uint]} fn main () { let mut ps : Points = {xs:~[1], ys:~[1]}; ... } == parse_array.rs:106:28: 106:29 error: expected one of `; }` but found `:` sparse_array.rs:106let mut ps : Points = {xs:~[1], ys:~[1]}; ^ More generally, I don't know why there are 2 syntactic schemas to define vars. I would be happy with the latter alone (despite the additional pair of spaces) since it is more coherent and more general in allowing temporalily uninitialised declarations. Denis ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev