From corey at octayn.net Mon Jul 1 05:32:24 2013 From: corey at octayn.net (Corey Richardson) Date: Mon, 1 Jul 2013 08:32:24 -0400 Subject: [rust-dev] Remove `float` from the language Message-ID: This is a copy of https://github.com/mozilla/rust/issues/7525, here for broader discussion. I propose to remove the float type from the language. float is defined by the manual as "the largest floating-point type that is directly supported by hardware on the target machine," but this isn't actually true (x87 supports 80-bit floats). I've seen it advertised as the "fastest float for the target," but performance also needs to include cache and bus pressure as well, not just speed of manipulation, and often the "fasted" in terms of manipulation is going to be some SIMD type using a coprocessor, and the situation gets even trickier if/when we have Rust being used for GPGPU kernels (LLVM has an R600 (AMD GPU) backend) or accelerator chips (a la Epiphany (parallella)). Furthermore it can cause confusion for incoming C/C++ programmers who would expect float to be an f32. Variable width floating point code is also dangerous - frequently code has implicit assumptions about accuracy. Using floating point correctly is already hard enough, introducing variable width types makes it even harder. I would remove float entirely, instead using f32 and f64 exclusively, also removing the f suffix for float literals. This allows user code to typedef float to what they want. From corey at octayn.net Mon Jul 1 11:51:18 2013 From: corey at octayn.net (Corey Richardson) Date: Mon, 1 Jul 2013 14:51:18 -0400 Subject: [rust-dev] Benchmarking data + call to help Message-ID: Hi all, I've set up a box to run the simple benchmark of compiling librustc with the stage2 rustc. The data is landing in http://hnn.mrsd.org/~cmr/, I don't know what to do with it, hopefully someone else does! (dbaupp expressed interest in integrating it into IRFY). Each commit is its own directory, mem.json is the output of my memory profiling script (https://github.com/cmr/rust-bench/blob/master/mem-bench.py), and time.txt is the output of GNU time on a separate run of it (to avoid the skew caused by the memory profiling script). I'll be going through src/tests/bench for good benchmarks to also profile, and I will start storing generated IR for some of them too. However, we have few good, solid benchmarks that stress a single part of the codegen or libraries to be able to easily spot regressions. Writing these should be easy, and would be a wonderful project for anyone looking to contribute to Rust. I've opened https://github.com/mozilla/rust/issues/7532 about it. From jeaye at arrownext.com Mon Jul 1 20:57:25 2013 From: jeaye at arrownext.com (jeaye at arrownext.com) Date: Mon, 01 Jul 2013 21:57:25 -0600 Subject: [rust-dev] Remove `float` from the language In-Reply-To: References: Message-ID: <7e5644dc2e0ca609b35fbaf5185a4f56@arrownext.com> I remember having some nasty bugs interfacing with OpenGL before I realized 'float' was 64bits; I'd like to add this may be a source of confusion for programmers coming from C and C++. I find myself always explicitly naming the size of the type (i32, u8, f32, etc), so I wonder how much 'int' is needed, given your argument to remove 'float'. Should we only have fixed-width types, or still leave some ambiguity? J On 2013-07-01 06:32, Corey Richardson wrote: > This is a copy of https://github.com/mozilla/rust/issues/7525, here > for broader discussion. > > I propose to remove the float type from the language. > > float is defined by the manual as "the largest floating-point type > that is directly supported by hardware on the target machine," but > this isn't actually true (x87 supports 80-bit floats). I've seen it > advertised as the "fastest float for the target," but performance also > needs to include cache and bus pressure as well, not just speed of > manipulation, and often the "fasted" in terms of manipulation is going > to be some SIMD type using a coprocessor, and the situation gets even > trickier if/when we have Rust being used for GPGPU kernels (LLVM has > an R600 (AMD GPU) backend) or accelerator chips (a la Epiphany > (parallella)). Furthermore it can cause confusion for incoming C/C++ > programmers who would expect float to be an f32. > > Variable width floating point code is also dangerous - frequently code > has implicit assumptions about accuracy. Using floating point > correctly is already hard enough, introducing variable width types > makes it even harder. > > I would remove float entirely, instead using f32 and f64 exclusively, > also removing the f suffix for float literals. This allows user code > to typedef float to what they want. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From pwalton at mozilla.com Mon Jul 1 21:07:10 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Mon, 01 Jul 2013 21:07:10 -0700 Subject: [rust-dev] Remove `float` from the language In-Reply-To: References: Message-ID: <51D251EE.5020309@mozilla.com> On 7/1/13 5:32 AM, Corey Richardson wrote: > Variable width floating point code is also dangerous - frequently code > has implicit assumptions about accuracy. Using floating point > correctly is already hard enough, introducing variable width types > makes it even harder. I proposed this in the past, and Graydon objected on the principle that it's similar to `int` in that `float` is the size of a register, and it leaves the door open for 128-bit floats if CPU manufacturers ever go to that. I'd still personally be OK with it though: C doesn't have a concept of "floating point type as big as a register" (rather float is de-facto 32-bit and double is de-facto 64-bit). As far as I know it will probably never acquire such a thing, so it seems best to me to just follow C here and only support fixed length floating point types. Patrick From robert at ocallahan.org Mon Jul 1 22:09:16 2013 From: robert at ocallahan.org (Robert O'Callahan) Date: Tue, 2 Jul 2013 17:09:16 +1200 Subject: [rust-dev] Remove `float` from the language In-Reply-To: <51D251EE.5020309@mozilla.com> References: <51D251EE.5020309@mozilla.com> Message-ID: On Tue, Jul 2, 2013 at 4:07 PM, Patrick Walton wrote: > On 7/1/13 5:32 AM, Corey Richardson wrote: > >> Variable width floating point code is also dangerous - frequently code >> has implicit assumptions about accuracy. Using floating point >> correctly is already hard enough, introducing variable width types >> makes it even harder. >> > > I proposed this in the past, and Graydon objected on the principle that > it's similar to `int` in that `float` is the size of a register, and it > leaves the door open for 128-bit floats if CPU manufacturers ever go to > that. I'd still personally be OK with it though: C doesn't have a concept > of "floating point type as big as a register" (rather float is de-facto > 32-bit and double is de-facto 64-bit). As far as I know it will probably > never acquire such a thing, so it seems best to me to just follow C here > and only support fixed length floating point types. > Seems to me you could quantify the performance impact of variable-width types. E.g. try making 'int' 32-bit on a 64-bit architecture and see how much it hurts. I'm suspicious they're a premature optimization. Rob -- Jtehsauts tshaei dS,o n" Wohfy Mdaon yhoaus eanuttehrotraiitny eovni le atrhtohu gthot sf oirng iyvoeu rs ihnesa.r"t sS?o Whhei csha iids teoa stiheer :p atroa lsyazye,d 'mYaonu,r "sGients uapr,e tfaokreg iyvoeunr, 'm aotr atnod sgaoy ,h o'mGee.t" uTph eann dt hwea lmka'n? gBoutt uIp waanndt wyeonut thoo mken.o w * * -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Mon Jul 1 23:07:29 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Tue, 2 Jul 2013 02:07:29 -0400 Subject: [rust-dev] Remove `float` from the language In-Reply-To: References: <51D251EE.5020309@mozilla.com> Message-ID: On Tue, Jul 2, 2013 at 1:09 AM, Robert O'Callahan wrote: > Seems to me you could quantify the performance impact of variable-width > types. E.g. try making 'int' 32-bit on a 64-bit architecture and see how > much it hurts. I'm suspicious they're a premature optimization. > > Rob The int and uint types match the pointer size, and if they aren't the same size the existing standard library (including things like vectors) won't work. From abhijeet.gaiha at gmail.com Tue Jul 2 06:26:03 2013 From: abhijeet.gaiha at gmail.com (Abhijeet Gaiha) Date: Tue, 2 Jul 2013 18:56:03 +0530 Subject: [rust-dev] Static initialisation of LinearMap Message-ID: Hi Folks, Is there a way to statically initialise a LinearMap in code? Something like you can do with a vector. Any other suggestions to save time for inserting a fixed set of values into a hash map? Thanks, Abhijeet -- Abhijeet Gaiha http://about.me/abhijeet.gaiha -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Tue Jul 2 06:40:00 2013 From: corey at octayn.net (Corey Richardson) Date: Tue, 2 Jul 2013 09:40:00 -0400 Subject: [rust-dev] Static initialisation of LinearMap In-Reply-To: References: Message-ID: On Tue, Jul 2, 2013 at 9:26 AM, Abhijeet Gaiha wrote: > Hi Folks, > > Is there a way to statically initialise a LinearMap in code? Something like > you can do with a vector. > Any other suggestions to save time for inserting a fixed set of values into > a hash map? > LinearMap is now std::hashmap::HashMap (in 0.7 and in master). There is no way to have a *static* hashmap, I think (`static h: HashMap = HashMap::new()`, would be immutable and useless), but you could write a macro that expands to a bunch of inserts into a hashmap. Not sure, though. From abhijeet.gaiha at gmail.com Tue Jul 2 06:46:01 2013 From: abhijeet.gaiha at gmail.com (Abhijeet Gaiha) Date: Tue, 2 Jul 2013 19:16:01 +0530 Subject: [rust-dev] Static initialisation of LinearMap In-Reply-To: References: Message-ID: <94EA10297F3C42F290DC62DCB41F5B9F@gmail.com> If I did write a macro, that would amount to the same thing as doing the inserts at run-time (I think). I was looking for something like: static h:HashMap = {(K,V),(K,V).....}. Is this possible at all? Any potential equivalents in the std/ext library to just writing a custom map of my own to do the same? -- Abhijeet Gaiha http://about.me/abhijeet.gaiha On Tuesday, 2 July 2013 at 7:10 PM, Corey Richardson wrote: > On Tue, Jul 2, 2013 at 9:26 AM, Abhijeet Gaiha wrote: > > Hi Folks, > > > > Is there a way to statically initialise a LinearMap in code? Something like > > you can do with a vector. > > Any other suggestions to save time for inserting a fixed set of values into > > a hash map? > > > > > LinearMap is now std::hashmap::HashMap (in 0.7 and in master). There > is no way to have a *static* hashmap, I think (`static h: HashMap V> = HashMap::new()`, would be immutable and useless), but you could > write a macro that expands to a bunch of inserts into a hashmap. Not > sure, though. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From thadguidry at gmail.com Tue Jul 2 06:55:05 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Tue, 2 Jul 2013 08:55:05 -0500 Subject: [rust-dev] Remove `float` from the language In-Reply-To: References: <51D251EE.5020309@mozilla.com> Message-ID: History lesson, The correct term to use is really "floating point register". But the idea of a "float" that is being tossed in this discussion is really a "float variable". This is what Graydon is talking about I pretty sure: http://www.gnu.org/software/gsl/manual/html_node/Examining-floating-point-registers.html There is a difference in terminology depending on WHAT you are really talking about, but it appears that Graydon "rocks it old school", as we all should when discussing the "register" capabilities themselves of the hardware (in years past an FPU... in current architectures a SIMD "capable" processor.) Besides all these terms are in the IEEE standards anyways http://en.wikipedia.org/wiki/IEEE_floating-point_standard (class dismissed) ;-) On Tue, Jul 2, 2013 at 1:07 AM, Daniel Micay wrote: > On Tue, Jul 2, 2013 at 1:09 AM, Robert O'Callahan > wrote: > > Seems to me you could quantify the performance impact of variable-width > > types. E.g. try making 'int' 32-bit on a 64-bit architecture and see how > > much it hurts. I'm suspicious they're a premature optimization. > > > > Rob > > The int and uint types match the pointer size, and if they aren't the > same size the existing standard library (including things like > vectors) won't work. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- -Thad Thad on Freebase.com Thad on LinkedIn -------------- next part -------------- An HTML attachment was scrubbed... URL: From pnathan at vandals.uidaho.edu Tue Jul 2 07:44:06 2013 From: pnathan at vandals.uidaho.edu (Paul Nathan) Date: Tue, 2 Jul 2013 07:44:06 -0700 Subject: [rust-dev] Remove `float` from the language In-Reply-To: References: Message-ID: <4337FAD4-F540-4BE4-BD6A-37013CA8EA42@vandals.uidaho.edu> On Jul 1, 2013, at 5:32 AM, Corey Richardson wrote: > This is a copy of https://github.com/mozilla/rust/issues/7525, here > for broader discussion. > > I propose to remove the float type from the language. > > [snip] > Variable width floating point code is also dangerous - frequently code > has implicit assumptions about accuracy. Using floating point > correctly is already hard enough, introducing variable width types > makes it even harder. > > I would remove float entirely, instead using f32 and f64 exclusively, > also removing the f suffix for float literals. This allows user code > to typedef float to what they want. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > It's very common to typedef u8,u16, etc to the correct C type when doing embedded work. While there are reasons why C's int length is variable, having the variability can be confusing and can cause bugs.. I would reckon tightening up Rusts floating point types to have a obviously specific FP width to be a good thing. It also linguistically allows for f80 or f128 if so desired. I suppose I should point out that some modern chips don't have a FP unit. Pretty sure that's not relevant in this thread, but it might be worth taking up elsewhere( what to do when your chip betrays you). -paul From alex at crichton.co Tue Jul 2 08:29:32 2013 From: alex at crichton.co (Alex Crichton) Date: Tue, 2 Jul 2013 08:29:32 -0700 Subject: [rust-dev] Static initialisation of LinearMap In-Reply-To: <94EA10297F3C42F290DC62DCB41F5B9F@gmail.com> References: <94EA10297F3C42F290DC62DCB41F5B9F@gmail.com> Message-ID: > I was looking for something like: static h:HashMap = > {(K,V),(K,V).....}. > Is this possible at all? Unfortunately this is more difficult than it seems. One of the nice things about the standard HashMap implementation is that it keys the hashes with random values (stored in each hash map). If this were a compile-time constant, that randomness would be lost (along with the randomness having to be generated at compile time). The more pressing issue, however, is that there is no "initialization phase" in rust, there are only compile-time constants. If you can't calculate the actual layout in memory of a static struct (as in it requires a function call), then currently there's no way to stick it in a global. Similarly, internally hash maps use ~ vectors which are allocated on the heap, another value which is currently not able to be allocated at compile time. > Any potential equivalents in the std/ext library to > just writing a custom map of my own to do the same? You would have to write your own version, but remember that it would have to be a compile-time constant. Each of the key/value pairs would have to be constant, and you would have to use slices instead of allocated vectors. What you probably want is a long-lived HashMap that it initialized somewhere in your code and maybe passed around. One other option would be to use thread local storage to squirrel away the hash map after your program initializes and then to read it from there. And the last other option you may wish to pursue is to put the map in a `static mut` slot. This would require unsafe code to both access/read, and it would also require unsafe code to cast the hash map to a store-able value in a static mut (which also has to be statically initialized). You could wrap this all in a safe-interface most likely, but it's not guaranteed. From mneumann at ntecs.de Tue Jul 2 08:45:29 2013 From: mneumann at ntecs.de (Michael Neumann) Date: Tue, 02 Jul 2013 17:45:29 +0200 Subject: [rust-dev] Static initialisation of LinearMap In-Reply-To: References: <94EA10297F3C42F290DC62DCB41F5B9F@gmail.com> Message-ID: <51D2F599.8070607@ntecs.de> Am 02.07.2013 17:29, schrieb Alex Crichton: >> I was looking for something like: static h:HashMap = >> {(K,V),(K,V).....}. >> Is this possible at all? What would be much easier is to use a sorted array and binary search for lookup. But sorting at compile time seams to be tricky, for simple values ok, but for more complex keys I think it's impossible. Regards, Michael From pwalton at mozilla.com Tue Jul 2 09:15:21 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Tue, 02 Jul 2013 09:15:21 -0700 Subject: [rust-dev] Static initialisation of LinearMap In-Reply-To: <51D2F599.8070607@ntecs.de> References: <94EA10297F3C42F290DC62DCB41F5B9F@gmail.com> <51D2F599.8070607@ntecs.de> Message-ID: <51D2FC99.3050004@mozilla.com> On 7/2/13 8:45 AM, Michael Neumann wrote: > Am 02.07.2013 17:29, schrieb Alex Crichton: >>> I was looking for something like: static h:HashMap = >>> {(K,V),(K,V).....}. >>> Is this possible at all? > > What would be much easier is to use a sorted array and binary search for > lookup. > But sorting at compile time seams to be tricky, for simple values ok, > but for more > complex keys I think it's impossible. A procedural macro (what we call a syntax extension) could do it. I've been thinking for a while that we should have such a syntax extension in the compiler. This is needed in Servo for "pre-interned identifiers": think well-known DOM attributes like "id" or HTML elements like "img". Patrick From graydon at mozilla.com Tue Jul 2 13:00:17 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 02 Jul 2013 13:00:17 -0700 Subject: [rust-dev] Remove `float` from the language In-Reply-To: References: Message-ID: <51D33151.5040707@mozilla.com> On 13-07-01 05:32 AM, Corey Richardson wrote: > This is a copy of https://github.com/mozilla/rust/issues/7525, here > for broader discussion. > > I propose to remove the float type from the language. > > float is defined by the manual as "the largest floating-point type > that is directly supported by hardware on the target machine," but > this isn't actually true (x87 supports 80-bit floats). I've seen it > advertised as the "fastest float for the target," but performance also > needs to include cache and bus pressure as well, not just speed of > manipulation, and often the "fasted" in terms of manipulation is going > to be some SIMD type using a coprocessor, and the situation gets even > trickier if/when we have Rust being used for GPGPU kernels (LLVM has > an R600 (AMD GPU) backend) or accelerator chips (a la Epiphany > (parallella)). Furthermore it can cause confusion for incoming C/C++ > programmers who would expect float to be an f32. The largest supported _of the rust types_; I didn't (and don't) intend to have rust support f80 at all, since: - It's not an ieee754 basic format. - It's not a storage format; x87 loads and stores 32/64 bit values, it's just an intermediate state during calculation on x87 stack. You can't meaningfully observe it. It's an operating mode / codegen thing. - It doesn't exist on any non-x86 hardware anyways, and is deprecated (for over a decade now) on x86. SSE2 is mandated in x64. The reason for float, though, was: if you want to write "best effort" code that's portable between targets with different best-precision, and don't want to duplicate your code. Yes, you lose the ability to reason as as closely as you might concerning precision, but most of the time we use approx_eq and epsilon and get on without considering that exactly anyways. That said, I've done some meandering through architecture manuals and I can't find any serious / living architectures that "only" support 32bit fp. They all have modes that pair 32bit fp registers and support double precision mode (arm vfp, mips, etc.) So the 32/64 angle isn't really ... as pressing as I expected. So I assume anyone who's "writing f32 code" is doing so intentionally these days. I.e. they don't _need_ it for hardware reasons, they just _want_ it, for speed or interop. The one other thing 'float' may help with is the (possible) future shift to f128 that's a supported basic format in the revised 754-2008 spec. I can't really speculate on how likely that shift is; f64 has held up pretty well since the 80s. > Variable width floating point code is also dangerous - frequently code > has implicit assumptions about accuracy. Using floating point > correctly is already hard enough, introducing variable width types > makes it even harder. I don't believe it changes the difficulty. Surely you do not regularly look at decimal literals you type in and eyeball whether they overflow 23 bits of significand vs. 52 bits. You know they're inaccurate and you have to do things like approximate comparisons in various circumstances, and organize your arithmetic to avoid precision-loss the same way. > I would remove float entirely, instead using f32 and f64 exclusively, > also removing the f suffix for float literals. This allows user code > to typedef float to what they want. This doesn't make sense to me. You generally don't want to typedef a platform-agnostic type to a platform-variable type if you can avoid it: it makes the "will it build?" question platform-specific. By keeping float _type-disjoint_ from f32 and f64, you put in all the relevant conversions at library boundaries (though some of them will compile to no-ops). The only other option here would be to introduce silent coercions between fp widths, which sounds ghastly. I think if we can find use cases for writing "float" in your code (i.e. "best effort" or "don't care") then we should keep the concept. But if not, maybe you're right and it should go. I'm curious how much weight the f128 argument holds with people. Or if there were f32-only architectures I overlooked. -Graydon From danielmicay at gmail.com Tue Jul 2 13:06:47 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Tue, 2 Jul 2013 16:06:47 -0400 Subject: [rust-dev] Remove `float` from the language In-Reply-To: <51D33151.5040707@mozilla.com> References: <51D33151.5040707@mozilla.com> Message-ID: On Tue, Jul 2, 2013 at 4:00 PM, Graydon Hoare wrote: > I think if we can find use cases for writing "float" in your code (i.e. > "best effort" or "don't care") then we should keep the concept. But if > not, maybe you're right and it should go. I'm curious how much weight > the f128 argument holds with people. Or if there were f32-only > architectures I overlooked. It could just be a `type float = f64` in prelude though as long as the standard library uses methods and generic functions instead of free functions in f32/f64. From gmaxwell at gmail.com Tue Jul 2 13:26:31 2013 From: gmaxwell at gmail.com (Gregory Maxwell) Date: Tue, 2 Jul 2013 13:26:31 -0700 Subject: [rust-dev] Remove `float` from the language In-Reply-To: <51D33151.5040707@mozilla.com> References: <51D33151.5040707@mozilla.com> Message-ID: On Tue, Jul 2, 2013 at 1:00 PM, Graydon Hoare wrote: > The largest supported _of the rust types_; I didn't (and don't) intend > to have rust support f80 at all, since: > - It's not an ieee754 basic format. > - It's not a storage format; x87 loads and stores 32/64 bit values, > it's just an intermediate state during calculation on x87 stack. Hm? $ cat a.c #include void main(void) { long double q[100]; int i; for(i=0;i<100;i++)q[i]=i; printf("%d\n",sizeof(q[0])); } $ gcc -o a.s -S a.c -m32 $ cat a.s | grep fstpt fstpt (%eax) $ ./a 12 At least ten years ago, I knew people who were doing numerical work where they were still purchasing itanium hardware on the basis of long double performance. I suppose now most of those people would spend more cycles getting their algorithms to behave well with doubles? considering the performance gaps... so it it indeed may be irrelevant. But 80 bit floating point is certainly a real, if non-standard, thing! (and absent people saying they need it, it isn't like it would be the sort of thing that would be hard to add to a later version of the language) From graydon at mozilla.com Tue Jul 2 14:07:19 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 02 Jul 2013 14:07:19 -0700 Subject: [rust-dev] Remove `float` from the language In-Reply-To: References: <51D33151.5040707@mozilla.com> Message-ID: <51D34107.3030201@mozilla.com> On 13-07-02 01:26 PM, Gregory Maxwell wrote: > $ gcc -o a.s -S a.c -m32 > $ cat a.s | grep fstpt > fstpt (%eax) > $ ./a > 12 > > At least ten years ago, I knew people who were doing numerical work > where they were still purchasing itanium hardware on the basis of long > double performance. I suppose now most of those people would spend > more cycles getting their algorithms to behave well with doubles? > considering the performance gaps... so it it indeed may be irrelevant. > But 80 bit floating point is certainly a real, if non-standard, thing! Huh. My mistake! I thought 'long double' usually mapped to f128, with softfp when it wasn't supported in hardware. Shows how much numerical code I write. https://en.wikipedia.org/wiki/Long_double Quite the variety of representations. I thought they never reified f80 into a first class memory type. Bummer. Yup, there it is: FSTP mem32real D9 /3 FSTP mem64real DD /3 FSTP mem80real DB /7 How unfortunate. > (and absent people saying they need it, it isn't like it would be the > sort of thing that would be hard to add to a later version of the > language) No, it's conceivable, just .. sigh. I would not want to go there. I guess it makes sense on pre-SSE x86 targets also, however long those live on. Anyway, seeing as how you have more insight and experience here, perhaps you can settle the broader question: does it actually ever make sense to code "best effort" floating point and let the compiler pick the best precision it can get on the target? -Graydon From corey at octayn.net Tue Jul 2 14:25:49 2013 From: corey at octayn.net (Corey Richardson) Date: Tue, 2 Jul 2013 17:25:49 -0400 Subject: [rust-dev] Remove `float` from the language In-Reply-To: <51D34107.3030201@mozilla.com> References: <51D33151.5040707@mozilla.com> <51D34107.3030201@mozilla.com> Message-ID: On Tue, Jul 2, 2013 at 5:07 PM, Graydon Hoare wrote: >> (and absent people saying they need it, it isn't like it would be the >> sort of thing that would be hard to add to a later version of the >> language) > > No, it's conceivable, just .. sigh. I would not want to go there. I > guess it makes sense on pre-SSE x86 targets also, however long those > live on. > doomlord in irc said f16 (llvm's `half` type) would be very useful for graphics. LLVM already exposes fp128 for f128, so it /shouldn't/ be that difficult to support. Going farther into the land of f256 would be quite difficult though. From graydon at mozilla.com Tue Jul 2 15:48:45 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 02 Jul 2013 15:48:45 -0700 Subject: [rust-dev] Remove `float` from the language In-Reply-To: References: <51D33151.5040707@mozilla.com> <51D34107.3030201@mozilla.com> Message-ID: <51D358CD.4090604@mozilla.com> On 13-07-02 02:25 PM, Corey Richardson wrote: > On Tue, Jul 2, 2013 at 5:07 PM, Graydon Hoare wrote: >>> (and absent people saying they need it, it isn't like it would be the >>> sort of thing that would be hard to add to a later version of the >>> language) >> >> No, it's conceivable, just .. sigh. I would not want to go there. I >> guess it makes sense on pre-SSE x86 targets also, however long those >> live on. >> > > doomlord in irc said f16 (llvm's `half` type) would be very useful for > graphics. LLVM already exposes fp128 for f128, so it /shouldn't/ be > that difficult to support. Going farther into the land of f256 would > be quite difficult though. Yeah, f16 shows up in image formats. Might consider trying to support it. I believe both it and f128 always map to softfp at this point, that no hardware supports it. f256 is not specified as a basic format in 754-2008, I wouldn't worry about it. -Graydon From giles at thaumas.net Tue Jul 2 16:27:56 2013 From: giles at thaumas.net (Ralph Giles) Date: Tue, 02 Jul 2013 16:27:56 -0700 Subject: [rust-dev] Remove `float` from the language In-Reply-To: <51D358CD.4090604@mozilla.com> References: <51D33151.5040707@mozilla.com> <51D34107.3030201@mozilla.com> <51D358CD.4090604@mozilla.com> Message-ID: <51D361FC.40104@thaumas.net> On 13-07-02 3:48 PM, Graydon Hoare wrote: > I believe both it and f128 always map to softfp at this point, that > no hardware supports it. GPUs certainly support it, and there are llvm back-ends for GPUs. Maybe not relevant to rust at this point. -r From graydon at mozilla.com Tue Jul 2 16:42:34 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 02 Jul 2013 16:42:34 -0700 Subject: [rust-dev] Static initialisation of LinearMap In-Reply-To: <51D2FC99.3050004@mozilla.com> References: <94EA10297F3C42F290DC62DCB41F5B9F@gmail.com> <51D2F599.8070607@ntecs.de> <51D2FC99.3050004@mozilla.com> Message-ID: <51D3656A.1030306@mozilla.com> On 13-07-02 09:15 AM, Patrick Walton wrote: > On 7/2/13 8:45 AM, Michael Neumann wrote: >> Am 02.07.2013 17:29, schrieb Alex Crichton: >>>> I was looking for something like: static h:HashMap = >>>> {(K,V),(K,V).....}. >>>> Is this possible at all? >> >> What would be much easier is to use a sorted array and binary search for >> lookup. >> But sorting at compile time seams to be tricky, for simple values ok, >> but for more >> complex keys I think it's impossible. > > A procedural macro (what we call a syntax extension) could do it. I've > been thinking for a while that we should have such a syntax extension in > the compiler. This is needed in Servo for "pre-interned identifiers": > think well-known DOM attributes like "id" or HTML elements like "img". Yeah. Though you might also want a static hash table combined with gperf[1]-like functionality. For keyword sets and static lookup tables, it's quite reasonable. I've assumed we'd grow a syntax extension for this for a while. I imagine the hashmap code could be abstracted some to handle lookups over bucket-iterators, in which case it could be recycled between static and dynamic hashmaps. -Graydon [1] https://www.gnu.org/software/gperf/manual/gperf.html From banderson at mozilla.com Tue Jul 2 20:14:46 2013 From: banderson at mozilla.com (Brian Anderson) Date: Tue, 02 Jul 2013 20:14:46 -0700 Subject: [rust-dev] Rust 0.7 prerelease testing Message-ID: <51D39726.4000403@mozilla.com> Oh look at this! It's a 0.7 release candidate! http://static.rust-lang.org/dist/rust-0.7.tar.gz sha256: 0b88b8a4489382e0a69214eaab88e2e7c316ec33c164af0d3b53630b17590df0 http://static.rust-lang.org/dist/rust-0.7-install.exe sha256: 919fb016611888a139c8b451c8553b7695fe85596ad45764b8d4656a47c2e0f6 This is _not_ a signed release, just a candidate. If you have some spare cycles please give this an install and report whether it does what you expect. We want to prove that the install works on platforms we tend to support (OS X 10.6+, various Linuxes, and Windows 7 & 2008) and the compiler generally behaves as expected, considering the various known issues. Testing on under-represented platforms is particularly welcome. Note that I've heard that Rust doesn't currently work on Mac OS 10.9, but further confirmation couldn't hurt. -Brian From graydon at mozilla.com Tue Jul 2 20:26:05 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 02 Jul 2013 20:26:05 -0700 Subject: [rust-dev] Rust 0.7 prerelease testing In-Reply-To: <51D39726.4000403@mozilla.com> References: <51D39726.4000403@mozilla.com> Message-ID: <51D399CD.7080904@mozilla.com> All test pass on ubuntu 12.04 LTS. I've disabled the util-doc builder for the night so we have a doc tree we can snapshot along with the RC, if it turns out to be the one we want. Bors I've left running, as there's a long queue to drain. -Graydon From echochamber at gmail.com Tue Jul 2 21:53:45 2013 From: echochamber at gmail.com (MIURA Masahiro) Date: Wed, 3 Jul 2013 13:53:45 +0900 Subject: [rust-dev] Rust 0.7 prerelease testing In-Reply-To: <51D39726.4000403@mozilla.com> References: <51D39726.4000403@mozilla.com> Message-ID: 'make check' stops with segfault on Fedora 18 x86_64: $ make check failures: net_tcp::test::tcp_ipv4_server_and_client_test::impl64::test_gl_tcp_server_and_client_ipv4 result: FAILED. 482 passed; 1 failed; 22 ignored rust: task failed at 'Some tests failed', /home/miura/Desktop/Rust-0.7RC/rust-0.7/src/libextra/test.rs:106 rust: domain main @0x23391b0 root task failed rust: task failed at 'killed', /home/miura/Desktop/Rust-0.7RC/rust-0.7/src/libstd/pipes.rs:282 rust: task failed at 'killed', /home/miura/Desktop/Rust-0.7RC/rust-0.7/src/libstd/pipes.rs:282 rust: task failed at 'killed', /home/miura/Desktop/Rust-0.7RC/rust-0.7/src/libstd/pipes.rs:282 /bin/sh: line 1: 19855 Segmentation fault (core dumped) x86_64-unknown-linux-gnu/stage2/test/extratest-x86_64-unknown-linux-gnu --logfile tmp/check-stage2-T-x86_64-unknown-linux-gnu-H-x86_64-unknown-linux-gnu-extra.log make: *** [tmp/check-stage2-T-x86_64-unknown-linux-gnu-H-x86_64-unknown-linux-gnu-extra.ok] Error 139 $ -- MIURA Masahiro echochamber at gmail.com From laden at csclub.uwaterloo.ca Tue Jul 2 22:24:02 2013 From: laden at csclub.uwaterloo.ca (Luqman Aden) Date: Wed, 3 Jul 2013 01:24:02 -0400 Subject: [rust-dev] Rust 0.7 prerelease testing In-Reply-To: References: <51D39726.4000403@mozilla.com> Message-ID: I'm guessing that's because you have something already listening on port 8888. I'm not sure why it decides to segfault because of that test failure though. On Wed, Jul 3, 2013 at 12:53 AM, MIURA Masahiro wrote: > 'make check' stops with segfault on Fedora 18 x86_64: > > $ make check > > failures: > net_tcp::test::tcp_ipv4_server_and_client_test::impl64::test_gl_tcp_server_and_client_ipv4 > > result: FAILED. 482 passed; 1 failed; 22 ignored > > rust: task failed at 'Some tests failed', > /home/miura/Desktop/Rust-0.7RC/rust-0.7/src/libextra/test.rs:106 > rust: domain main @0x23391b0 root task failed > rust: task failed at 'killed', > /home/miura/Desktop/Rust-0.7RC/rust-0.7/src/libstd/pipes.rs:282 > rust: task failed at 'killed', > /home/miura/Desktop/Rust-0.7RC/rust-0.7/src/libstd/pipes.rs:282 > > rust: task failed at 'killed', > /home/miura/Desktop/Rust-0.7RC/rust-0.7/src/libstd/pipes.rs:282 > /bin/sh: line 1: 19855 Segmentation fault (core dumped) > x86_64-unknown-linux-gnu/stage2/test/extratest-x86_64-unknown-linux-gnu > --logfile tmp/check-stage2-T-x86_64-unknown-linux-gnu-H-x86_64-unknown-linux-gnu-extra.log > make: *** [tmp/check-stage2-T-x86_64-unknown-linux-gnu-H-x86_64-unknown-linux-gnu-extra.ok] > Error 139 > $ > > -- > MIURA Masahiro > echochamber at gmail.com > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From pnathan at vandals.uidaho.edu Tue Jul 2 22:37:05 2013 From: pnathan at vandals.uidaho.edu (Paul Nathan) Date: Tue, 2 Jul 2013 22:37:05 -0700 Subject: [rust-dev] Rust 0.7 prerelease testing In-Reply-To: <51D39726.4000403@mozilla.com> References: <51D39726.4000403@mozilla.com> Message-ID: <51D3B881.9070500@vandals.uidaho.edu> On 7/2/13 8:14 PM, Brian Anderson wrote: > Oh look at this! It's a 0.7 release candidate! > > http://static.rust-lang.org/dist/rust-0.7.tar.gz > sha256: 0b88b8a4489382e0a69214eaab88e2e7c316ec33c164af0d3b53630b17590df0 > http://static.rust-lang.org/dist/rust-0.7-install.exe > sha256: 919fb016611888a139c8b451c8553b7695fe85596ad45764b8d4656a47c2e0f6 > > This is _not_ a signed release, just a candidate. If you have some spare > cycles please give this an install and report whether it does what you > expect. We want to prove that the install works on platforms we tend to > support (OS X 10.6+, various Linuxes, and Windows 7 & 2008) and the > compiler generally behaves as expected, considering the various known > issues. Testing on under-represented platforms is particularly welcome. > Note that I've heard that Rust doesn't currently work on Mac OS 10.9, > but further confirmation couldn't hurt. > > -Brian > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > . > OK on OSX 10.8.2 (kernel info below) Make check gives: summary of 24 test runs: 5227 passed; 0 failed; 313 ignored $ uname -a Darwin elendil.local 12.2.0 Darwin Kernel Version 12.2.0: Sat Aug 25 00:48:52 PDT 2012; root:xnu-2050.18.24~1/RELEASE_X86_64 x86_64 The compiler seems to be working normally for my wee sillynesses. Tangentially, the colorized warnings are an EXTREMELY nice touch. -- Regards, Paul From rust-dev at tomlee.co Tue Jul 2 23:15:44 2013 From: rust-dev at tomlee.co (Tom Lee) Date: Tue, 2 Jul 2013 23:15:44 -0700 Subject: [rust-dev] Rust 0.7 prerelease testing In-Reply-To: <51D39726.4000403@mozilla.com> References: <51D39726.4000403@mozilla.com> Message-ID: LGTM on latest Debian Testing: Linux desktop 3.9-1-amd64 #1 SMP Debian 3.9.6-1 x86_64 GNU/Linux Didn't run the full test suite, but a few simple smoke tests are looking good. Cheers, Tom On Tue, Jul 2, 2013 at 8:14 PM, Brian Anderson wrote: > Oh look at this! It's a 0.7 release candidate! > > http://static.rust-lang.org/dist/rust-0.7.tar.gz > sha256: 0b88b8a4489382e0a69214eaab88e2e7c316ec33c164af0d3b53630b17590df0 > http://static.rust-lang.org/dist/rust-0.7-install.exe > sha256: 919fb016611888a139c8b451c8553b7695fe85596ad45764b8d4656a47c2e0f6 > > This is _not_ a signed release, just a candidate. If you have some spare > cycles please give this an install and report whether it does what you > expect. We want to prove that the install works on platforms we tend to > support (OS X 10.6+, various Linuxes, and Windows 7 & 2008) and the compiler > generally behaves as expected, considering the various known issues. Testing > on under-represented platforms is particularly welcome. Note that I've heard > that Rust doesn't currently work on Mac OS 10.9, but further confirmation > couldn't hurt. > > -Brian > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -- Tom Lee / http://tomlee.co / @tglee From echochamber at gmail.com Tue Jul 2 23:23:33 2013 From: echochamber at gmail.com (MIURA Masahiro) Date: Wed, 3 Jul 2013 15:23:33 +0900 Subject: [rust-dev] Rust 0.7 prerelease testing In-Reply-To: References: <51D39726.4000403@mozilla.com> Message-ID: On Wed, Jul 3, 2013 at 2:24 PM, Luqman Aden wrote: > I'm guessing that's because you have something already listening on > port 8888. I'm not sure why it decides to segfault because of that > test failure though. Your guess was right, thanks! I freed the port 8888, and the test completed with no failure. -- MIURA Masahiro echochamber at gmail.com From rustdevlist at korapaty.com Wed Jul 3 00:12:16 2013 From: rustdevlist at korapaty.com (Vijay Korapaty) Date: Wed, 03 Jul 2013 00:12:16 -0700 Subject: [rust-dev] Rust 0.7 prerelease testing In-Reply-To: References: Message-ID: <51D3CED0.3000604@korapaty.com> Ran the installer on Windows 7 (64-bit) and came across 2 problems so far. The first was when trying the 'rustc' command from cmd.exe, I got an error 'libpthread-2.dll is not found'. If tried in PowerShell, there is no output or error, just a new prompt. Following the 'Troubleshooting Windows environment setups' section here https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust, and dumping the dll into the Rust installation directory (C:\Program Files(x86)\Rust\bin) fixed that error. (I would note that I have no idea where that lzma command line program mentioned in the Notes page comes from. Tried http://www.7-zip.org/sdk.html that, and that was a rabbit hole of confusion. It was much simpler to use the 7-zip GUI to extract the dll from the .tar.lzma package.) The second problem is with 'rusti', https://github.com/mozilla/rust/issues/7499 was happening for me. From markus.prinz at nuclearsquid.com Wed Jul 3 03:19:26 2013 From: markus.prinz at nuclearsquid.com (Markus Prinz) Date: Wed, 3 Jul 2013 12:19:26 +0200 Subject: [rust-dev] Rust 0.7 prerelease testing In-Reply-To: <51D39726.4000403@mozilla.com> References: <51D39726.4000403@mozilla.com> Message-ID: On 03.07.2013, at 05:14, Brian Anderson wrote: > Oh look at this! It's a 0.7 release candidate! > > http://static.rust-lang.org/dist/rust-0.7.tar.gz > sha256: 0b88b8a4489382e0a69214eaab88e2e7c316ec33c164af0d3b53630b17590df0 > http://static.rust-lang.org/dist/rust-0.7-install.exe > sha256: 919fb016611888a139c8b451c8553b7695fe85596ad45764b8d4656a47c2e0f6 > > This is _not_ a signed release, just a candidate. If you have some spare cycles please give this an install and report whether it does what you expect. We want to prove that the install works on platforms we tend to support (OS X 10.6+, various Linuxes, and Windows 7 & 2008) and the compiler generally behaves as expected, considering the various known issues. Testing on under-represented platforms is particularly welcome. Note that I've heard that Rust doesn't currently work on Mac OS 10.9, but further confirmation couldn't hurt. On OS X 10.8.4: $ make check [?] summary of 24 test runs: 5227 passed; 0 failed; 313 ignored $ uname -a Darwin durandal.local 12.4.0 Darwin Kernel Version 12.4.0: Wed May 1 17:57:12 PDT 2013; root:xnu-2050.24.15~1/RELEASE_X86_64 x86_64 g, Markus From ben.striegel at gmail.com Wed Jul 3 06:14:48 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Wed, 3 Jul 2013 09:14:48 -0400 Subject: [rust-dev] Rust 0.7 prerelease testing In-Reply-To: <51D39726.4000403@mozilla.com> References: <51D39726.4000403@mozilla.com> Message-ID: All works on most recent Linux Mint, assuming that the correct git revision is a2db7c15ce9f586164cabb15d83fb3f6bbeb3cf5. On Tue, Jul 2, 2013 at 11:14 PM, Brian Anderson wrote: > Oh look at this! It's a 0.7 release candidate! > > http://static.rust-lang.org/**dist/rust-0.7.tar.gz > sha256: 0b88b8a4489382e0a69214eaab88e2**e7c316ec33c164af0d3b53630b1759** > 0df0 > http://static.rust-lang.org/**dist/rust-0.7-install.exe > sha256: 919fb016611888a139c8b451c8553b**7695fe85596ad45764b8d4656a47c2** > e0f6 > > This is _not_ a signed release, just a candidate. If you have some spare > cycles please give this an install and report whether it does what you > expect. We want to prove that the install works on platforms we tend to > support (OS X 10.6+, various Linuxes, and Windows 7 & 2008) and the > compiler generally behaves as expected, considering the various known > issues. Testing on under-represented platforms is particularly welcome. > Note that I've heard that Rust doesn't currently work on Mac OS 10.9, but > further confirmation couldn't hurt. > > -Brian > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hdd86 at qq.com Wed Jul 3 07:45:47 2013 From: hdd86 at qq.com (=?gb18030?B?aHVkbw==?=) Date: Wed, 3 Jul 2013 22:45:47 +0800 Subject: [rust-dev] Rust-dev Digest, Vol 37, Issue 5 Message-ID: rust installer missing some dlls of gcc, what is the difference compile their own ------------------ Original ------------------ From: "rust-dev-request"; Date: 2013?7?3?(???) ??6:19 To: "rust-dev"; Subject: Rust-dev Digest, Vol 37, Issue 5 Send Rust-dev mailing list submissions to rust-dev at mozilla.org To subscribe or unsubscribe via the World Wide Web, visit https://mail.mozilla.org/listinfo/rust-dev or, via email, send a message with subject or body 'help' to rust-dev-request at mozilla.org You can reach the person managing the list at rust-dev-owner at mozilla.org When replying, please edit your Subject line so it is more specific than "Re: Contents of Rust-dev digest..." Today's Topics: 1. Re: Rust 0.7 prerelease testing (Graydon Hoare) 2. Re: Rust 0.7 prerelease testing (MIURA Masahiro) 3. Re: Rust 0.7 prerelease testing (Luqman Aden) 4. Re: Rust 0.7 prerelease testing (Paul Nathan) 5. Re: Rust 0.7 prerelease testing (Tom Lee) 6. Re: Rust 0.7 prerelease testing (MIURA Masahiro) 7. Rust 0.7 prerelease testing (Vijay Korapaty) 8. Re: Rust 0.7 prerelease testing (Markus Prinz) ---------------------------------------------------------------------- Message: 1 Date: Tue, 02 Jul 2013 20:26:05 -0700 From: Graydon Hoare To: Brian Anderson , "rust-dev at mozilla.org" Subject: Re: [rust-dev] Rust 0.7 prerelease testing Message-ID: <51D399CD.7080904 at mozilla.com> Content-Type: text/plain; charset=ISO-8859-1 All test pass on ubuntu 12.04 LTS. I've disabled the util-doc builder for the night so we have a doc tree we can snapshot along with the RC, if it turns out to be the one we want. Bors I've left running, as there's a long queue to drain. -Graydon ------------------------------ Message: 2 Date: Wed, 3 Jul 2013 13:53:45 +0900 From: MIURA Masahiro To: Brian Anderson Cc: rust-dev at mozilla.org Subject: Re: [rust-dev] Rust 0.7 prerelease testing Message-ID: Content-Type: text/plain; charset=ISO-8859-1 'make check' stops with segfault on Fedora 18 x86_64: $ make check failures: net_tcp::test::tcp_ipv4_server_and_client_test::impl64::test_gl_tcp_server_and_client_ipv4 result: FAILED. 482 passed; 1 failed; 22 ignored rust: task failed at 'Some tests failed', /home/miura/Desktop/Rust-0.7RC/rust-0.7/src/libextra/test.rs:106 rust: domain main @0x23391b0 root task failed rust: task failed at 'killed', /home/miura/Desktop/Rust-0.7RC/rust-0.7/src/libstd/pipes.rs:282 rust: task failed at 'killed', /home/miura/Desktop/Rust-0.7RC/rust-0.7/src/libstd/pipes.rs:282 rust: task failed at 'killed', /home/miura/Desktop/Rust-0.7RC/rust-0.7/src/libstd/pipes.rs:282 /bin/sh: line 1: 19855 Segmentation fault (core dumped) x86_64-unknown-linux-gnu/stage2/test/extratest-x86_64-unknown-linux-gnu --logfile tmp/check-stage2-T-x86_64-unknown-linux-gnu-H-x86_64-unknown-linux-gnu-extra.log make: *** [tmp/check-stage2-T-x86_64-unknown-linux-gnu-H-x86_64-unknown-linux-gnu-extra.ok] Error 139 $ -- MIURA Masahiro echochamber at gmail.com ------------------------------ Message: 3 Date: Wed, 3 Jul 2013 01:24:02 -0400 From: Luqman Aden To: MIURA Masahiro Cc: rust-dev at mozilla.org Subject: Re: [rust-dev] Rust 0.7 prerelease testing Message-ID: Content-Type: text/plain; charset=ISO-8859-1 I'm guessing that's because you have something already listening on port 8888. I'm not sure why it decides to segfault because of that test failure though. On Wed, Jul 3, 2013 at 12:53 AM, MIURA Masahiro wrote: > 'make check' stops with segfault on Fedora 18 x86_64: > > $ make check > > failures: > net_tcp::test::tcp_ipv4_server_and_client_test::impl64::test_gl_tcp_server_and_client_ipv4 > > result: FAILED. 482 passed; 1 failed; 22 ignored > > rust: task failed at 'Some tests failed', > /home/miura/Desktop/Rust-0.7RC/rust-0.7/src/libextra/test.rs:106 > rust: domain main @0x23391b0 root task failed > rust: task failed at 'killed', > /home/miura/Desktop/Rust-0.7RC/rust-0.7/src/libstd/pipes.rs:282 > rust: task failed at 'killed', > /home/miura/Desktop/Rust-0.7RC/rust-0.7/src/libstd/pipes.rs:282 > > rust: task failed at 'killed', > /home/miura/Desktop/Rust-0.7RC/rust-0.7/src/libstd/pipes.rs:282 > /bin/sh: line 1: 19855 Segmentation fault (core dumped) > x86_64-unknown-linux-gnu/stage2/test/extratest-x86_64-unknown-linux-gnu > --logfile tmp/check-stage2-T-x86_64-unknown-linux-gnu-H-x86_64-unknown-linux-gnu-extra.log > make: *** [tmp/check-stage2-T-x86_64-unknown-linux-gnu-H-x86_64-unknown-linux-gnu-extra.ok] > Error 139 > $ > > -- > MIURA Masahiro > echochamber at gmail.com > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev ------------------------------ Message: 4 Date: Tue, 2 Jul 2013 22:37:05 -0700 From: Paul Nathan To: Subject: Re: [rust-dev] Rust 0.7 prerelease testing Message-ID: <51D3B881.9070500 at vandals.uidaho.edu> Content-Type: text/plain; charset="ISO-8859-1"; format=flowed On 7/2/13 8:14 PM, Brian Anderson wrote: > Oh look at this! It's a 0.7 release candidate! > > http://static.rust-lang.org/dist/rust-0.7.tar.gz > sha256: 0b88b8a4489382e0a69214eaab88e2e7c316ec33c164af0d3b53630b17590df0 > http://static.rust-lang.org/dist/rust-0.7-install.exe > sha256: 919fb016611888a139c8b451c8553b7695fe85596ad45764b8d4656a47c2e0f6 > > This is _not_ a signed release, just a candidate. If you have some spare > cycles please give this an install and report whether it does what you > expect. We want to prove that the install works on platforms we tend to > support (OS X 10.6+, various Linuxes, and Windows 7 & 2008) and the > compiler generally behaves as expected, considering the various known > issues. Testing on under-represented platforms is particularly welcome. > Note that I've heard that Rust doesn't currently work on Mac OS 10.9, > but further confirmation couldn't hurt. > > -Brian > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > . > OK on OSX 10.8.2 (kernel info below) Make check gives: summary of 24 test runs: 5227 passed; 0 failed; 313 ignored $ uname -a Darwin elendil.local 12.2.0 Darwin Kernel Version 12.2.0: Sat Aug 25 00:48:52 PDT 2012; root:xnu-2050.18.24~1/RELEASE_X86_64 x86_64 The compiler seems to be working normally for my wee sillynesses. Tangentially, the colorized warnings are an EXTREMELY nice touch. -- Regards, Paul ------------------------------ Message: 5 Date: Tue, 2 Jul 2013 23:15:44 -0700 From: Tom Lee To: Brian Anderson Cc: "rust-dev at mozilla.org" Subject: Re: [rust-dev] Rust 0.7 prerelease testing Message-ID: Content-Type: text/plain; charset=ISO-8859-1 LGTM on latest Debian Testing: Linux desktop 3.9-1-amd64 #1 SMP Debian 3.9.6-1 x86_64 GNU/Linux Didn't run the full test suite, but a few simple smoke tests are looking good. Cheers, Tom On Tue, Jul 2, 2013 at 8:14 PM, Brian Anderson wrote: > Oh look at this! It's a 0.7 release candidate! > > http://static.rust-lang.org/dist/rust-0.7.tar.gz > sha256: 0b88b8a4489382e0a69214eaab88e2e7c316ec33c164af0d3b53630b17590df0 > http://static.rust-lang.org/dist/rust-0.7-install.exe > sha256: 919fb016611888a139c8b451c8553b7695fe85596ad45764b8d4656a47c2e0f6 > > This is _not_ a signed release, just a candidate. If you have some spare > cycles please give this an install and report whether it does what you > expect. We want to prove that the install works on platforms we tend to > support (OS X 10.6+, various Linuxes, and Windows 7 & 2008) and the compiler > generally behaves as expected, considering the various known issues. Testing > on under-represented platforms is particularly welcome. Note that I've heard > that Rust doesn't currently work on Mac OS 10.9, but further confirmation > couldn't hurt. > > -Brian > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -- Tom Lee / http://tomlee.co / @tglee ------------------------------ Message: 6 Date: Wed, 3 Jul 2013 15:23:33 +0900 From: MIURA Masahiro To: Luqman Aden Cc: rust-dev at mozilla.org Subject: Re: [rust-dev] Rust 0.7 prerelease testing Message-ID: Content-Type: text/plain; charset=ISO-8859-1 On Wed, Jul 3, 2013 at 2:24 PM, Luqman Aden wrote: > I'm guessing that's because you have something already listening on > port 8888. I'm not sure why it decides to segfault because of that > test failure though. Your guess was right, thanks! I freed the port 8888, and the test completed with no failure. -- MIURA Masahiro echochamber at gmail.com ------------------------------ Message: 7 Date: Wed, 03 Jul 2013 00:12:16 -0700 From: Vijay Korapaty To: rust-dev at mozilla.org Subject: [rust-dev] Rust 0.7 prerelease testing Message-ID: <51D3CED0.3000604 at korapaty.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Ran the installer on Windows 7 (64-bit) and came across 2 problems so far. The first was when trying the 'rustc' command from cmd.exe, I got an error 'libpthread-2.dll is not found'. If tried in PowerShell, there is no output or error, just a new prompt. Following the 'Troubleshooting Windows environment setups' section here https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust, and dumping the dll into the Rust installation directory (C:\Program Files(x86)\Rust\bin) fixed that error. (I would note that I have no idea where that lzma command line program mentioned in the Notes page comes from. Tried http://www.7-zip.org/sdk.html that, and that was a rabbit hole of confusion. It was much simpler to use the 7-zip GUI to extract the dll from the .tar.lzma package.) The second problem is with 'rusti', https://github.com/mozilla/rust/issues/7499 was happening for me. ------------------------------ Message: 8 Date: Wed, 3 Jul 2013 12:19:26 +0200 From: Markus Prinz To: Brian Anderson Cc: rust-dev at mozilla.org Subject: Re: [rust-dev] Rust 0.7 prerelease testing Message-ID: Content-Type: text/plain; charset=windows-1252 On 03.07.2013, at 05:14, Brian Anderson wrote: > Oh look at this! It's a 0.7 release candidate! > > http://static.rust-lang.org/dist/rust-0.7.tar.gz > sha256: 0b88b8a4489382e0a69214eaab88e2e7c316ec33c164af0d3b53630b17590df0 > http://static.rust-lang.org/dist/rust-0.7-install.exe > sha256: 919fb016611888a139c8b451c8553b7695fe85596ad45764b8d4656a47c2e0f6 > > This is _not_ a signed release, just a candidate. If you have some spare cycles please give this an install and report whether it does what you expect. We want to prove that the install works on platforms we tend to support (OS X 10.6+, various Linuxes, and Windows 7 & 2008) and the compiler generally behaves as expected, considering the various known issues. Testing on under-represented platforms is particularly welcome. Note that I've heard that Rust doesn't currently work on Mac OS 10.9, but further confirmation couldn't hurt. On OS X 10.8.4: $ make check [?] summary of 24 test runs: 5227 passed; 0 failed; 313 ignored $ uname -a Darwin durandal.local 12.4.0 Darwin Kernel Version 12.4.0: Wed May 1 17:57:12 PDT 2013; root:xnu-2050.24.15~1/RELEASE_X86_64 x86_64 g, Markus ------------------------------ _______________________________________________ Rust-dev mailing list Rust-dev at mozilla.org https://mail.mozilla.org/listinfo/rust-dev End of Rust-dev Digest, Vol 37, Issue 5 *************************************** -------------- next part -------------- An HTML attachment was scrubbed... URL: From pazaconyoman at gmail.com Wed Jul 3 08:41:23 2013 From: pazaconyoman at gmail.com (Viktor Dahl) Date: Wed, 3 Jul 2013 17:41:23 +0200 Subject: [rust-dev] Rust 0.7 prerelease testing Message-ID: Two failures on OpenSUSE 12.3. Both for rustpkg. $ uname -a Linux datoraki 3.7.10-1.16-default #1 SMP Fri May 31 20:21:23 UTC 2013 (97c14ba) x86_64 x86_64 x86_64 GNU/Linux failures: tests::test_install_url tests::test_package_version 2013/7/3 Brian Anderson > Oh look at this! It's a 0.7 release candidate! > > http://static.rust-lang.org/**dist/rust-0.7.tar.gz > sha256: 0b88b8a4489382e0a69214eaab88e2**e7c316ec33c164af0d3b53630b1759** > 0df0 > http://static.rust-lang.org/**dist/rust-0.7-install.exe > sha256: 919fb016611888a139c8b451c8553b**7695fe85596ad45764b8d4656a47c2** > e0f6 > > This is _not_ a signed release, just a candidate. If you have some spare > cycles please give this an install and report whether it does what you > expect. We want to prove that the install works on platforms we tend to > support (OS X 10.6+, various Linuxes, and Windows 7 & 2008) and the > compiler generally behaves as expected, considering the various known > issues. Testing on under-represented platforms is particularly welcome. > Note that I've heard that Rust doesn't currently work on Mac OS 10.9, but > further confirmation couldn't hurt. > > -Brian > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Wed Jul 3 08:42:24 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 03 Jul 2013 08:42:24 -0700 Subject: [rust-dev] Rust 0.7 prerelease testing In-Reply-To: <51D39726.4000403@mozilla.com> References: <51D39726.4000403@mozilla.com> Message-ID: <51D44660.8040304@mozilla.com> Win7 pro SP1 x64, smoketest of download, install, compile and run test program (using std and extra::base64), opt and non-opt, works ok. (Assuming the laborious and sadly not-made-any-better-in-this-release dependency-meeting procedure on windows) -Graydon From banderson at mozilla.com Wed Jul 3 12:02:58 2013 From: banderson at mozilla.com (Brian Anderson) Date: Wed, 03 Jul 2013 12:02:58 -0700 Subject: [rust-dev] Rust 0.7 released Message-ID: <51D47562.5040108@mozilla.com> Mozilla and the Rust community are pleased to announce version 0.7 of the Rust compiler and tools. Rust is a systems programming language with a focus on safety, performance and concurrency. This release had a markedly different focus from previous releases, with fewer language changes and many improvements to the standard library. The highlights this time include a rewrite of the borrow checker that makes working with borrowed pointers significantly easier and a comprehensive new iterator module (std::iterator) that will eventually replace the previous closure-based iterators. The brief release notes are included in this announcement, and there is further explanation in the detailed release [notes] on the wiki. Documentation and all the links in this email are available on the [website]. As usual, version 0.7 should be considered an alpha release, suitable for early adopters and language enthusiasts. Please file [bugs] and join the [fun]. [website]: http://www.rust-lang.org [notes]: https://github.com/mozilla/rust/wiki/Doc-detailed-release-notes [bugs]: https://github.com/mozilla/rust/issues [fun]: https://github.com/mozilla/rust/wiki/Note-guide-for-new-contributors This release is available as both a tarball and a Windows installer: * http://static.rust-lang.org/dist/rust-0.7.tar.gz http://static.rust-lang.org/dist/rust-0.7.tar.gz.asc SHA256 (of .tar.gz): 0b88b8a4489382e0a69214eaab88e2e7c316ec33c164af0d3b53630b17590df0 * http://static.rust-lang.org/dist/rust-0.7-install.exe http://static.rust-lang.org/dist/rust-0.7-install.exe.asc SHA256 (of .exe): 919fb016611888a139c8b451c8553b7695fe85596ad45764b8d4656a47c2e0f6 Thanks to everyone who contributed! Regards, The Rust Team Version 0.7 (July 2013) ----------------------- * ~2000 changes, numerous bugfixes * Language * `impl`s no longer accept a visibility qualifier. Put them on methods instead. * The borrow checker has been rewritten with flow-sensitivity, fixing many bugs and inconveniences. * The `self` parameter no longer implicitly means `&'self self`, and can be explicitly marked with a lifetime. * Overloadable compound operators (`+=`, etc.) have been temporarily removed due to bugs. * The `for` loop protocol now requires `for`-iterators to return `bool` so they compose better. * The `Durable` trait is replaced with the `'static` bounds. * Trait default methods work more often. * Structs with the `#[packed]` attribute have byte alignment and no padding between fields. * Type parameters bound by `Copy` must now be copied explicitly with the `copy` keyword. * It is now illegal to move out of a dereferenced unsafe pointer. * `Option<~T>` is now represented as a nullable pointer. * `@mut` does dynamic borrow checks correctly. * The `main` function is only detected at the topmost level of the crate. The `#[main]` attribute is still valid anywhere. * Struct fields may no longer be mutable. Use inherited mutability. * The `#[no_send]` attribute makes a type that would otherwise be `Send`, not. * The `#[no_freeze]` attribute makes a type that would otherwise be `Freeze`, not. * Unbounded recursion will abort the process after reaching the limit specified by the `RUST_MAX_STACK` environment variable (default: 1GB). * The `vecs_implicitly_copyable` lint mode has been removed. Vectors are never implicitly copyable. * `#[static_assert]` makes compile-time assertions about static bools. * At long last, 'argument modes' no longer exist. * The rarely used `use mod` statement no longer exists. * Syntax extensions * `fail!` and `assert!` accept `~str`, `&'static str` or `fmt!`-style argument list. * `Encodable`, `Decodable`, `Ord`, `TotalOrd`, `TotalEq`, `DeepClone`, `Rand`, `Zero` and `ToStr` can all be automatically derived with `#[deriving(...)]`. * The `bytes!` macro returns a vector of bytes for string, u8, char, and unsuffixed integer literals. * Libraries * The `core` crate was renamed to `std`. * The `std` crate was renamed to `extra`. * More and improved documentation. * std: `iterator` module for external iterator objects. * Many old-style (internal, higher-order function) iterators replaced by implementations of `Iterator`. * std: Many old internal vector and string iterators, incl. `any`, `all`. removed. * std: The `finalize` method of `Drop` renamed to `drop`. * std: The prelude no longer reexports any modules, only types and traits. * std: Prelude additions: `print`, `println`, `FromStr`, `ApproxEq`, `Equiv`, `Iterator`, `IteratorUtil`, many numeric traits, many tuple traits. * std: New numeric traits: `Fractional`, `Real`, `RealExt`, `Integer`, `Ratio`, `Algebraic`, `Trigonometric`, `Exponential`, `Primitive`. * std: Tuple traits and accessors defined for up to 12-tuples, e.g. `(0, 1, 2).n2()` or `(0, 1, 2).n2_ref()`. * std: Many types implement `Clone`. * std: `path` type renamed to `Path`. * std: `mut` module and `Mut` type removed. * std: Many standalone functions removed in favor of methods and iterators in `vec`, `str`. In the future methods will also work as functions. * std: `reinterpret_cast` removed. Use `transmute`. * std: ascii string handling in `std::ascii`. * std: `Rand` is implemented for ~/@. * std: `run` module for spawning processes overhauled. * std: Various atomic types added to `unstable::atomic`. * std: Various types implement `Zero`. * std: `LinearMap` and `LinearSet` renamed to `HashMap` and `HashSet`. * std: Borrowed pointer functions moved from `ptr` to `borrow`. * std: Added `os::mkdir_recursive`. * std: Added `os::glob` function performs filesystems globs. * std: `FuzzyEq` renamed to `ApproxEq`. * std: `Map` now defines `pop` and `swap` methods. * std: `Cell` constructors converted to static methods. * extra: `rc` module adds the reference counted pointers, `Rc` and `RcMut`. * extra: `flate` module moved from `std` to `extra`. * extra: `fileinput` module for iterating over a series of files. * extra: `Complex` number type and `complex` module. * extra: `Rational` number type and `rational` module. * extra: `BigInt`, `BigUint` implement numeric and comparison traits. * extra: `term` uses terminfo now, is more correct. * extra: `arc` functions converted to methods. * extra: Implementation of fixed output size variations of SHA-2. * Tooling * `unused_variable` lint mode for unused variables (default: warn). * `unused_unsafe` lint mode for detecting unnecessary `unsafe` blocks (default: warn). * `unused_mut` lint mode for identifying unused `mut` qualifiers (default: warn). * `dead_assignment` lint mode for unread variables (default: warn). * `unnecessary_allocation` lint mode detects some heap allocations that are immediately borrowed so could be written without allocating (default: warn). * `missing_doc` lint mode (default: allow). * `unreachable_code` lint mode (default: warn). * The `rusti` command has been rewritten and a number of bugs addressed. * rustc outputs in color on more terminals. * rustc accepts a `--link-args` flag to pass arguments to the linker. * rustc accepts a `-Z print-link-args` flag for debugging linkage. * Compiling with `-g` will make the binary record information about dynamic borrowcheck failures for debugging. * rustdoc has a nicer stylesheet. * Various improvements to rustdoc. * Improvements to rustpkg (see the detailed release notes). Contributors to Rust 0.7 ------------------------ Alex Crichton Alexei Sholik Anthony Juckel Ben Blum Benjamin Herr Ben Striegel Bill Myers Bill Wendling Birunthan Mohanathas Bj?rn Steinbrink Brendan Zabarauskas Brett Cannon Brian Anderson Brian Leibig Bryan Dunsmore Caitlin Potter Corey Richardson Daniel Farina Daniel Micay Daniel Ralston Dan Luu Diggory Hardy Erick Tryzelaar Fedor Indutny Felix S. Klock II G?bor Horv?th gareth gifnksm Graydon Hoare Herman J. Radtke III Honza Strnad Huon Wilson ILyoan ILYONG CHO Jack Moffitt James Miller James Tranovich Jeaye Jed Davis Jed Estep Jens Nockert Jeong YunWon Jesse Luehrs Jihyun Yu John Clements Jordi Boggiano Joris Rehm Josh Matthews Junyoung Cho Jyun-Yan You Kevin Ballard klutzy kud1ing Leah Hanson Lenny222 Lindsey Kuper Luca Bruno Luqman Aden Marti Raudsepp Marvin L?bel Matthijs Hofstra Michael Sullivan Michael Woerister Nick Desaulniers Niko Matsakis Olivier Saut Palmer Cox

Patrick Walton Pavel Panchekha Philipp Br?schweiler Ralph Bodenner Ramkumar Ramachandra reus Rob Hoelz Ron Dahlgren Samuel Chase Sander Mathijs van Veen Sangeun Kim Saurabh Anand Sean Moon Seo Sanghyeon SiegeLord Steve Klabnik Steven De Coeyer Steven Fackler Steven Stewart-Gallus Ted Horst Thomas Daede Tim Chevalier Tom Lee Tommy M. McGuire Tuncer Ayaz Uwe Dauernheim Vadim Chugunov Vivek Galatage Young-il Choi Youngmin Yoo Youngsoo Son Zack Corr zofrex From marcianx at gmail.com Wed Jul 3 13:00:08 2013 From: marcianx at gmail.com (Ashish Myles) Date: Wed, 3 Jul 2013 16:00:08 -0400 Subject: [rust-dev] Rust 0.7 prerelease testing In-Reply-To: <51D44660.8040304@mozilla.com> References: <51D39726.4000403@mozilla.com> <51D44660.8040304@mozilla.com> Message-ID: openSUSE 12.2 (i.e. previous release). "make check" succeeds: ---- summary of 25 test runs: 5261 passed; 0 failed; 302 ignored ---- From marcianx at gmail.com Wed Jul 3 13:05:31 2013 From: marcianx at gmail.com (Ashish Myles) Date: Wed, 3 Jul 2013 16:05:31 -0400 Subject: [rust-dev] Rust 0.7 prerelease testing In-Reply-To: References: <51D39726.4000403@mozilla.com> <51D44660.8040304@mozilla.com> Message-ID: On Wed, Jul 3, 2013 at 4:00 PM, Ashish Myles wrote: > openSUSE 12.2 (i.e. previous release). "make check" succeeds: > ---- > summary of 25 test runs: 5261 passed; 0 failed; 302 ignored > ---- To clarify, I did the check against trunk (0c6fc46c030ab0515a052fa99c9e10c75cfc8184), and my e-mail above was ~1hour after Brian's release announcement. From vadimcn at gmail.com Wed Jul 3 14:26:14 2013 From: vadimcn at gmail.com (Vadim) Date: Wed, 3 Jul 2013 14:26:14 -0700 Subject: [rust-dev] Rust 0.7 prerelease testing In-Reply-To: <51D3CED0.3000604@korapaty.com> References: <51D3CED0.3000604@korapaty.com> Message-ID: Looks like MinGW's "libpthread-2.dll" got renamed to "pthreadGC2.dll"at some point. So Rust 0.7 won't work with a fresh MinGW installation unless users downgrade libpthread to v2.8 (mingw-get upgrade "libpthread=2.8.0-3"). However, previous Rust releases had used libpthread v2.9, so, perhaps, this change wasn't intentional? On Wed, Jul 3, 2013 at 12:12 AM, Vijay Korapaty wrote: > Ran the installer on Windows 7 (64-bit) and came across 2 problems so far. > > The first was when trying the 'rustc' command from cmd.exe, I got an error > 'libpthread-2.dll is not found'. If tried in PowerShell, there is no output > or error, just a new prompt. Following the 'Troubleshooting Windows > environment setups' section here https://github.com/mozilla/** > rust/wiki/Note-getting-**started-developing-Rust, > and dumping the dll into the Rust installation directory (C:\Program > Files(x86)\Rust\bin) fixed that error. > > (I would note that I have no idea where that lzma command line program > mentioned in the Notes page comes from. Tried > http://www.7-zip.org/sdk.html that, and that was a rabbit hole of > confusion. It was much simpler to use the 7-zip GUI to extract the dll from > the .tar.lzma package.) > > The second problem is with 'rusti', https://github.com/mozilla/** > rust/issues/7499 was > happening for me. > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From vadimcn at gmail.com Wed Jul 3 14:38:01 2013 From: vadimcn at gmail.com (Vadim) Date: Wed, 3 Jul 2013 14:38:01 -0700 Subject: [rust-dev] Rust 0.7 prerelease testing In-Reply-To: References: <51D3CED0.3000604@korapaty.com> Message-ID: Correction: apparently previous releases were not dependent on libpthread at all. I'm guessing this new dependency is because Rust's LLVM is now compiled in multi-threaded configuration? Anyhow, my point still stands: a default fresh MinGW installation will have the wrong version of libpthread. On Wed, Jul 3, 2013 at 2:26 PM, Vadim wrote: > Looks like MinGW's "libpthread-2.dll" got renamed to "pthreadGC2.dll"at some point. So Rust 0.7 won't work with a fresh MinGW installation > unless users downgrade libpthread to v2.8 (mingw-get upgrade > "libpthread=2.8.0-3"). > > However, previous Rust releases had used libpthread v2.9, so, perhaps, > this change wasn't intentional? > > > > On Wed, Jul 3, 2013 at 12:12 AM, Vijay Korapaty wrote: > >> Ran the installer on Windows 7 (64-bit) and came across 2 problems so far. >> >> The first was when trying the 'rustc' command from cmd.exe, I got an >> error 'libpthread-2.dll is not found'. If tried in PowerShell, there is no >> output or error, just a new prompt. Following the 'Troubleshooting Windows >> environment setups' section here https://github.com/mozilla/** >> rust/wiki/Note-getting-**started-developing-Rust, >> and dumping the dll into the Rust installation directory (C:\Program >> Files(x86)\Rust\bin) fixed that error. >> >> (I would note that I have no idea where that lzma command line program >> mentioned in the Notes page comes from. Tried >> http://www.7-zip.org/sdk.html that, and that was a rabbit hole of >> confusion. It was much simpler to use the 7-zip GUI to extract the dll from >> the .tar.lzma package.) >> >> The second problem is with 'rusti', https://github.com/mozilla/** >> rust/issues/7499 was >> happening for me. >> ______________________________**_________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/**listinfo/rust-dev >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From andres.osinski at gmail.com Wed Jul 3 17:01:37 2013 From: andres.osinski at gmail.com (Andres Osinski) Date: Wed, 3 Jul 2013 21:01:37 -0300 Subject: [rust-dev] Tutorial translations Message-ID: Hi all, I'd like to start contributing to Rust by writing a Spanish translation of the current language tutorial. This process would obviously take some time, however it'd be a nice start for having internationalized documentation of the project. I was wondering if any arrangements could be made to publish docs in non-English languages in the main website, and if there's any chance that said docs could be maintained in either the Rust tree, or a related project in GitHub or other code repo. I'm mostly raising the issue here since I'd like to know if there's any proposal already, and if perhaps such arrangements could be finished before a full version of the translated tutorial could be published (which, given how quickly the language changes, would be woefully out of date if this becomes just a personal project of mine without some platform to support community contributions and a minimum level of visibility). Thanks -- Andr?s Osinski http://www.andresosinski.com.ar/ From catamorphism at gmail.com Wed Jul 3 17:06:01 2013 From: catamorphism at gmail.com (Tim Chevalier) Date: Wed, 3 Jul 2013 17:06:01 -0700 Subject: [rust-dev] Tutorial translations In-Reply-To: References: Message-ID: On Wed, Jul 3, 2013 at 5:01 PM, Andres Osinski wrote: > Hi all, I'd like to start contributing to Rust by writing a Spanish > translation of the current language tutorial. This process would > obviously take some time, however it'd be a nice start for having > internationalized documentation of the project. > > I was wondering if any arrangements could be made to publish docs in > non-English languages in the main website, and if there's any chance > that said docs could be maintained in either the Rust tree, or a > related project in GitHub or other code repo. > That would be great! Patches welcome -- I think it should be in-tree so that the translations aren't second-class. > I'm mostly raising the issue here since I'd like to know if there's > any proposal already, and if perhaps such arrangements could be > finished before a full version of the translated tutorial could be > published (which, given how quickly the language changes, would be > woefully out of date if this becomes just a personal project of mine > without some platform to support community contributions and a minimum > level of visibility). I don't know of any such proposal already, so I encourage you to take the lead. Of course, even with the translations in the tree, there's the risk that they could become out of sync with the English version, but that's preferable to not having translations at all. (Perhaps other people who have been in projects with internationalized documentation can comment on the best approach(es) to this issue?) Thanks, Tim -- Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt "Not a riot, it's a rebellion." -- Boots Riley "Attention Bros and Trolls: When I call out your spew, I'm not angry, I'm defiant." -- Reg Braithwaite From graydon at mozilla.com Wed Jul 3 17:26:05 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 03 Jul 2013 17:26:05 -0700 Subject: [rust-dev] Tutorial translations In-Reply-To: References: Message-ID: <51D4C11D.70703@mozilla.com> On 13-07-03 05:06 PM, Tim Chevalier wrote: > I don't know of any such proposal already, so I encourage you to take > the lead. Of course, even with the translations in the tree, there's > the risk that they could become out of sync with the English version, > but that's preferable to not having translations at all. (Perhaps > other people who have been in projects with internationalized > documentation can comment on the best approach(es) to this issue?) I was hoping we'd set up a pootle server to translate .po files, and/or use the existing pootle instance mozilla runs: https://localize.mozilla.org/ .po files aren't perfect, but they seem to be dominant in this space. There are a lot of tools to work with them, show the drift from a translation and its source, and reconstruct software and documentation artifacts from the result. I think po4a might be applicable to the .md files that hold our docs: http://po4a.alioth.debian.org/ Someone who is familiar with these tools and workflows would be very welcome here. We've had a few people ask and just haven't got around to handling it yet. -Graydon From marcianx at gmail.com Wed Jul 3 19:53:04 2013 From: marcianx at gmail.com (Ashish Myles) Date: Wed, 3 Jul 2013 22:53:04 -0400 Subject: [rust-dev] Borrow lifetime assignment changed? Message-ID: Any idea why the following fails ---- use std::{io,rand,task}; fn main() { for ["Alice", "Bob", "Carol"].iter().advance |&name| { do task::spawn { use std::rand::RngUtil; let v = rand::rng().shuffle([1, 2, 3]); for v.iter().advance |&num| { io::print(fmt!("%s says: '%d'\n", name, num)) } } } } ---- with ---- hello.rs:4:8: 4:33 error: borrowed value does not live long enough hello.rs:4 for ["Alice", "Bob", "Carol"].iter().advance |&name| { ^~~~~~~~~~~~~~~~~~~~~~~~~ hello.rs:12:4: 12:5 note: borrowed pointer must be valid for the method call at 12:4... hello.rs:12 } ^ hello.rs:4:8: 4:41 note: ...but borrowed value is only valid for the method call at 4:8 hello.rs:4 for ["Alice", "Bob", "Carol"].iter().advance |&name| { ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to previous error ---- Changing to let lst = ["Alice", "Bob", "Carol"]; for lst.iter().advance |&name| { //... } succeeds, but I am surprised that the lifetime is not equivalent for lst and the raw vector literal for this specific code as there is nothing after the for-loop. -------------- next part -------------- An HTML attachment was scrubbed... URL: From dbau.pp at gmail.com Thu Jul 4 09:02:59 2013 From: dbau.pp at gmail.com (Huon Wilson) Date: Fri, 05 Jul 2013 02:02:59 +1000 Subject: [rust-dev] IsRustSlimYet (IsRustFastYet v2) Message-ID: <51D59CB3.20400@gmail.com> Hi, Corey Richardson has hooked up a spare computer to be a basic [bench slave]; and I've played around with an interface showing timing and memory profiles, [IRSY]. (It's very much in progress; e.g. I'm going to add the information from -Z time-passes to the memory profile graph.) It looks like it's a lot more consistent than the original [IRFY], so it might actually be useful for identifying performance issues. (Speaking of performance issues, it takes extra::json ~1.8s to parse one of the 4 MB mem.json file; Python takes about 150ms; the `perf` output http://ix.io/6tV, a *lot* of time spent in allocations.) In any case, the back-end is (mostly) written in Rust, rather than Python, so clearly the new version is better. ;) Huon [bench slave]: http://hnn.mrsd.org/~cmr/ [IRSY]: http://huonw.github.io/isrustfastyet/mem/#648c5e9,ca835f4 [IRFY]: http://huonw.github.io/isrustfastyet/ From graydon at mozilla.com Thu Jul 4 09:51:40 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 04 Jul 2013 09:51:40 -0700 Subject: [rust-dev] IsRustSlimYet (IsRustFastYet v2) In-Reply-To: <51D59CB3.20400@gmail.com> References: <51D59CB3.20400@gmail.com> Message-ID: <51D5A81C.1040307@mozilla.com> On 13-07-04 09:02 AM, Huon Wilson wrote: > Hi, > > Corey Richardson has hooked up a spare computer to be a basic [bench > slave]; and I've played around with an interface showing timing and > memory profiles, [IRSY]. (It's very much in progress; e.g. I'm going to > add the information from -Z time-passes to the memory profile graph.) > > It looks like it's a lot more consistent than the original [IRFY], so it > might actually be useful for identifying performance issues. (Speaking > of performance issues, it takes extra::json ~1.8s to parse one of the 4 > MB mem.json file; Python takes about 150ms; the `perf` output > http://ix.io/6tV, a *lot* of time spent in allocations.) Yeah. Optimization opportunities are .. everywhere. > In any case, the back-end is (mostly) written in Rust, rather than > Python, so clearly the new version is better. ;) Very nice! Thanks so much for doing this. -Graydon From lillymatsson at gmail.com Wed Jul 3 23:32:40 2013 From: lillymatsson at gmail.com (Lilly Matsson) Date: Thu, 4 Jul 2013 08:32:40 +0200 Subject: [rust-dev] 64-bit Windows Message-ID: Hello! I recently made a post on Reddit ( http://www.reddit.com/r/rust/comments/1hk25r/rust_on_64bit_windows_7/) asking about 64-bit Windows support, and kibwen urged me to post here to start some kind of discussion about the current state of 64-bit Windows support. So, what is the deal? What needs to be done to fully get 64-bit support for Windows? As I understand it, it has to do with LLVM. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bsteinbr at gmail.com Thu Jul 4 10:02:04 2013 From: bsteinbr at gmail.com (=?iso-8859-1?Q?Bj=F6rn?= Steinbrink) Date: Thu, 4 Jul 2013 19:02:04 +0200 Subject: [rust-dev] IsRustSlimYet (IsRustFastYet v2) In-Reply-To: <51D59CB3.20400@gmail.com> References: <51D59CB3.20400@gmail.com> Message-ID: <20130704170204.GA6224@atjola.homenet> Hi, On 2013.07.05 02:02:59 +1000, Huon Wilson wrote: > It looks like it's a lot more consistent than the original [IRFY], > so it might actually be useful for identifying performance issues. > (Speaking of performance issues, it takes extra::json ~1.8s to parse > one of the 4 MB mem.json file; Python takes about 150ms; the `perf` > output http://ix.io/6tV, a *lot* of time spent in allocations.) This is to a large part due to stack growth. A flamegraph that shows this can be found here: http://i.minus.com/1373041398/43t7zpBOcgy3CeDpkSht0w/inUqVLvZGEUfx.svg Setting RUST_MIN_STACK to 8000000 cuts runtime in half for me. Bj?rn From graydon at mozilla.com Thu Jul 4 10:02:29 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 04 Jul 2013 10:02:29 -0700 Subject: [rust-dev] 64-bit Windows In-Reply-To: References: Message-ID: <51D5AAA5.7030501@mozilla.com> On 13-07-03 11:32 PM, Lilly Matsson wrote: > Hello! > > I recently made a post on Reddit > (http://www.reddit.com/r/rust/comments/1hk25r/rust_on_64bit_windows_7/) > asking about 64-bit Windows support, and kibwen urged me to post here to > start some kind of discussion about the current state of 64-bit Windows > support. > > So, what is the deal? What needs to be done to fully get 64-bit support > for Windows? As I understand it, it has to do with LLVM. I don't think it'd be terribly difficult, given the current situation. The broad-brushstrokes steps are: - Shift our dependencies to mingw-w64. We've wanted to do this for a while anyways, since it's the newer / better-supported flavour, just lacked person-power to do it. - Add a new target and host config in the makefiles. - Fiddle with the target-specific data layout string in librustc::back - Fiddle with any missing definitions in std::libc. - Cross compile to it, make a snapshot and register it. I'm not aware of any LLVM issues blocking it. Thad Guidry and Luqman Aden have both been working on these steps and probably a bunch others that I've missed. There might also be a nontrivial number of Subtle Complications in the first step (i.e. "gcc-isms that we are bug-dependent on or something") but I don't know of specifics. Others might know. You can see some of the associated bugs and ongoing work here: https://github.com/mozilla/rust/issues/1237 https://github.com/mozilla/rust/issues/2398 https://github.com/mozilla/rust/pull/7494 https://github.com/mozilla/rust/pull/7547 We'd be very happy to see this land during 0.8 cycle, it's just been a matter of finding enough spare hands. The "install a very old version of mingw" step in our current getting-started guide is offputting to ... a lot of people :( -Graydon From matthieu.monrocq at gmail.com Thu Jul 4 12:12:42 2013 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Thu, 4 Jul 2013 21:12:42 +0200 Subject: [rust-dev] Tutorial translations In-Reply-To: <51D4C11D.70703@mozilla.com> References: <51D4C11D.70703@mozilla.com> Message-ID: On Thu, Jul 4, 2013 at 2:26 AM, Graydon Hoare wrote: > On 13-07-03 05:06 PM, Tim Chevalier wrote: > > > I don't know of any such proposal already, so I encourage you to take > > the lead. Of course, even with the translations in the tree, there's > > the risk that they could become out of sync with the English version, > > but that's preferable to not having translations at all. (Perhaps > > other people who have been in projects with internationalized > > documentation can comment on the best approach(es) to this issue?) > > I was hoping we'd set up a pootle server to translate .po files, and/or > use the existing pootle instance mozilla runs: > https://localize.mozilla.org/ > > .po files aren't perfect, but they seem to be dominant in this space. > There are a lot of tools to work with them, show the drift from a > translation and its source, and reconstruct software and documentation > artifacts from the result. I think po4a might be applicable to the .md > files that hold our docs: > http://po4a.alioth.debian.org/ > > Someone who is familiar with these tools and workflows would be very > welcome here. We've had a few people ask and just haven't got around to > handling it yet. > > -Graydon > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > I thought that .po files were mostly used to translate bits and pieces, such as strings used in GUIs, and not full-blown text files such as tutorials ? As to version drift, if both versions are in-tree it seems easy enough to check were made on the English version after the last commit of the Spanish version; you would just have to find the latest ancestor of both changesets and get all changes to the English version that are not in the Spanish branch. -- Matthieu -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Thu Jul 4 12:48:24 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Thu, 4 Jul 2013 15:48:24 -0400 Subject: [rust-dev] IsRustSlimYet (IsRustFastYet v2) In-Reply-To: <20130704170204.GA6224@atjola.homenet> References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> Message-ID: On Thu, Jul 4, 2013 at 1:02 PM, Bj?rn Steinbrink wrote: > Hi, > > On 2013.07.05 02:02:59 +1000, Huon Wilson wrote: >> It looks like it's a lot more consistent than the original [IRFY], >> so it might actually be useful for identifying performance issues. >> (Speaking of performance issues, it takes extra::json ~1.8s to parse >> one of the 4 MB mem.json file; Python takes about 150ms; the `perf` >> output http://ix.io/6tV, a *lot* of time spent in allocations.) > > This is to a large part due to stack growth. A flamegraph that shows > this can be found here: > > http://i.minus.com/1373041398/43t7zpBOcgy3CeDpkSht0w/inUqVLvZGEUfx.svg > > Setting RUST_MIN_STACK to 8000000 cuts runtime in half for me. > > Bj?rn I find this is the case for many benchmarks. With segmented stacks, we're behind Java, and without them Rust can get close to C++. I think it should be part of the API in the task module, allowing segmented stacks to be used only when they make sense. The first task spawned by the scheduler can just have a large fixed stack. From matthieu.monrocq at gmail.com Thu Jul 4 12:52:08 2013 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Thu, 4 Jul 2013 21:52:08 +0200 Subject: [rust-dev] IsRustSlimYet (IsRustFastYet v2) In-Reply-To: References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> Message-ID: On Thu, Jul 4, 2013 at 9:48 PM, Daniel Micay wrote: > On Thu, Jul 4, 2013 at 1:02 PM, Bj?rn Steinbrink > wrote: > > Hi, > > > > On 2013.07.05 02:02:59 +1000, Huon Wilson wrote: > >> It looks like it's a lot more consistent than the original [IRFY], > >> so it might actually be useful for identifying performance issues. > >> (Speaking of performance issues, it takes extra::json ~1.8s to parse > >> one of the 4 MB mem.json file; Python takes about 150ms; the `perf` > >> output http://ix.io/6tV, a *lot* of time spent in allocations.) > > > > This is to a large part due to stack growth. A flamegraph that shows > > this can be found here: > > > > http://i.minus.com/1373041398/43t7zpBOcgy3CeDpkSht0w/inUqVLvZGEUfx.svg > > > > Setting RUST_MIN_STACK to 8000000 cuts runtime in half for me. > > > > Bj?rn > > I find this is the case for many benchmarks. With segmented stacks, > we're behind Java, and without them Rust can get close to C++. > > I think it should be part of the API in the task module, allowing > segmented stacks to be used only when they make sense. The first task > spawned by the scheduler can just have a large fixed stack. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > You are here assuming that one will not create many schedulers, which the current design allows. (Not necessarily a bad idea, per se, just wanted to point out a possible new limitation) -- Matthieu -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Thu Jul 4 12:58:02 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Thu, 4 Jul 2013 15:58:02 -0400 Subject: [rust-dev] IsRustSlimYet (IsRustFastYet v2) In-Reply-To: References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> Message-ID: On Thu, Jul 4, 2013 at 3:52 PM, Matthieu Monrocq wrote: > > You are here assuming that one will not create many schedulers, which the > current design allows. > > (Not necessarily a bad idea, per se, just wanted to point out a possible new > limitation) > > -- Matthieu You can create many threads with fixed stacks, they just start off using 4K instead of however much smaller our segmented stacks will be. A scheduler will just be more expensive than a regular lightweight task. The 15-100% performance hit from segmented stacks pushes Rust well out of the systems language niche. I think it does have to change if Rust plans on ever fitting in the niche that C, C++ and D do. From graydon at mozilla.com Thu Jul 4 14:48:34 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 04 Jul 2013 14:48:34 -0700 Subject: [rust-dev] Tutorial translations In-Reply-To: References: <51D4C11D.70703@mozilla.com> Message-ID: <51D5EDB2.4050903@mozilla.com> On 13-07-04 12:12 PM, Matthieu Monrocq wrote: > I thought that .po files were mostly used to translate bits and pieces, > such as strings used in GUIs, and not full-blown text files such as > tutorials ? This is what it was designed for. But it appears to have been extended to use in documentation workflows by, as I linked above, po4a. Take a look through their docs, especially FAQ: http://po4a.alioth.debian.org/man/man7/po4a.7.php#lbAW It doesn't seem like .po files break if you make each string a paragraph. It's not like the computer runs out of memory when the string is too long. This is the mechanism GNOME[1], KDE[2] and (to some extent) Mozilla[3] all use to manage translation workflows. Including docs. > As to version drift, if both versions are in-tree it seems easy enough > to check were made on the English version after the last commit of the > Spanish version; you would just have to find the latest ancestor of both > changesets and get all changes to the English version that are not in > the Spanish branch. Certainly a VCS-centric approach is possible. What I've _heard_ from translators and those working in the mozilla L10N community is that translators often prefer using .po-centric tools that automatically find drift. These tend to be friendlier to operate (often with GUIs or web-based frontends[4]), can be worked on casually by end users, and have translation memory[5], machine translation[6] and translation-centric checks[7]. I don't know from my own experience how true (or important) this all is. I've not used them. But I would like to use as few different technologies as possible, and if we can get by using the same thing for message catalogs and docs, I'm happy to go that way. -Graydon [1] https://l10n.gnome.org/POT/gnome-user-docs.master/docs/gnome-help.master.pot [2] http://websvn.kde.org/trunk/l10n-kde4/templates/docmessages/applications/konqueror.pot?view=markup [3] https://localize.mozilla.org/ [4] https://localize.mozilla.org/pl/mdn/LC_MESSAGES/messages.po/translate/?page=7 [5] http://docs.translatehouse.org/projects/pootle/en/latest/features/translation_memory.html [6] http://docs.translatehouse.org/projects/pootle/en/latest/features/machine_translation.html [7] http://docs.translatehouse.org/projects/translate-toolkit/en/latest/commands/pofilter_tests.html From pwalton at mozilla.com Thu Jul 4 15:33:03 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Thu, 04 Jul 2013 15:33:03 -0700 Subject: [rust-dev] Segmented stacks (was: IsRustSlimYet (IsRustFastYet v2)) In-Reply-To: References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> Message-ID: <51D5F81F.5020204@mozilla.com> On 7/4/13 12:58 PM, Daniel Micay wrote: > You can create many threads with fixed stacks, they just start off > using 4K instead of however much smaller our segmented stacks will be. > A scheduler will just be more expensive than a regular lightweight > task. > > The 15-100% performance hit from segmented stacks pushes Rust well out > of the systems language niche. I think it does have to change if Rust > plans on ever fitting in the niche that C, C++ and D do. I agree. The sole benefit of segmented stacks on modern OS's that lazily allocate pages is that, on 32-bit, you can avoid running out of address space with many tasks. This is counterbalanced by these disadvantages: 1. There is no way for the compiler or runtime to know ahead of time how much stack any given task will need, because this is based on dynamic control flow. 2. The consequence of overshooting (choosing a stack size that is too big) is that the benefit above is reduced. 3. The consequence of undershooting (choosing a stack size that is too small) is disastrous performance. In the limit, the performance degrades to something like what many Schemes and SML/NJ do, in that stack frames are malloc'd from the heap. Except that Scheme and SML/NJ have precise generational garbage collectors with bump allocators in the nursery, and we have C malloc(). Furthermore, stack segment allocation is the slow path in C malloc, because it's in a high storage class. So performance becomes abysmal in the slow path. Unlike systems like Erlang and Cilk, there is no way to relocate stack segments in Rust because of unmanaged interior pointers: Erlang could at least in theory correct its mistakes and keep stacks contiguous (although I don't know if the implementation does). So the best we can do is cache and hope for the best--but too much caching increases memory usage and decreases the benefits of stack segments! 4. The benefit above is significantly reduced when calling into C code, and all solutions to this either hurt the benefit more or significantly penalize the FFI. I think that segmented stacks just don't work. *Relocatable* stacks may work, but not in Rust. From what I have read, Walter Bright and Rob Pike agree. At this point I'd like to suggest just allowing the user to choose a stack size on a per-task basis, and failing if the stack size is exceeded. Basically `__morestack` would turn into `fail`. Brian has pointed out to me that, currently, running out of stack has to abort the whole process, because the DWARF unwinder doesn't consider `__morestack` a "may-throw" position and as a result the arguments would leak. There are a number of ways we could fix this, ranging from principled to hacky. But for now I think aborting on stack exhaustion wouldn't be the end of the world (although others may disagree). Patrick From daede003 at umn.edu Thu Jul 4 15:53:46 2013 From: daede003 at umn.edu (Thomas Daede) Date: Thu, 4 Jul 2013 17:53:46 -0500 Subject: [rust-dev] Segmented stacks (was: IsRustSlimYet (IsRustFastYet v2)) In-Reply-To: <51D5F81F.5020204@mozilla.com> References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> <51D5F81F.5020204@mozilla.com> Message-ID: On Thu, Jul 4, 2013 at 5:33 PM, Patrick Walton wrote: > 1. There is no way for the compiler or runtime to know ahead of time how > much stack any given task will need, because this is based on dynamic > control flow. There is, unfortunately, no easy way for the user to know ahead of time either. On embedded systems, the traditional way to figure this out has been to use a "watermark" - fill the stack space with a pattern, then scan it later to see how much was overwritten (there is no MMU, so no way to grow the stack, and often times a stack overflow is undetectable unless it starts corrupting other memory). In a lot of things, the startup time of growing a stack is undesirable, even when debugging. Maybe an equivalent "watermark" in Rust could be implemented, using the existing stack growing routines, but having a very large stack preallocated at first, so that the user could go back later and fine tune the stack sizes. > 4. The benefit above is significantly reduced when calling into C code, and > all solutions to this either hurt the benefit more or significantly penalize > the FFI. > Calling C code is really unfortunate, and would break the watermarking idea above. Maybe one option would be to specially compile C code with the extra stack size instrumentation in place. This wouldn't really work on the desktop with shared libraries, though. > I think that segmented stacks just don't work. *Relocatable* stacks may > work, but not in Rust. From what I have read, Walter Bright and Rob Pike > agree. > > At this point I'd like to suggest just allowing the user to choose a stack > size on a per-task basis, and failing if the stack size is exceeded. > Basically `__morestack` would turn into `fail`. > > Brian has pointed out to me that, currently, running out of stack has to > abort the whole process, because the DWARF unwinder doesn't consider > `__morestack` a "may-throw" position and as a result the arguments would > leak. There are a number of ways we could fix this, ranging from principled > to hacky. But for now I think aborting on stack exhaustion wouldn't be the > end of the world (although others may disagree). It's far better than weird unrelated bugs showing up due to memory corruption, as is usually the case on embedded. From danielmicay at gmail.com Thu Jul 4 16:49:23 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Thu, 4 Jul 2013 19:49:23 -0400 Subject: [rust-dev] Segmented stacks (was: IsRustSlimYet (IsRustFastYet v2)) In-Reply-To: <51D5F81F.5020204@mozilla.com> References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> <51D5F81F.5020204@mozilla.com> Message-ID: On Thu, Jul 4, 2013 at 6:33 PM, Patrick Walton wrote: > On 7/4/13 12:58 PM, Daniel Micay wrote: >> >> You can create many threads with fixed stacks, they just start off >> using 4K instead of however much smaller our segmented stacks will be. >> A scheduler will just be more expensive than a regular lightweight >> task. >> >> The 15-100% performance hit from segmented stacks pushes Rust well out >> of the systems language niche. I think it does have to change if Rust >> plans on ever fitting in the niche that C, C++ and D do. > > > I agree. The sole benefit of segmented stacks on modern OS's that lazily > allocate pages is that, on 32-bit, you can avoid running out of address > space with many tasks. This is counterbalanced by these disadvantages: If we do manage to get them significantly smaller than the page size, they're still potentially useful for I/O handling or as coroutines on x86_64. Like Go, we need to handle system calls and allocation within code aware of segmented stacks for them to really be useful. I think large stacks should be the default (task::spawn) with an API available to reserve a different minimum stack size (task::spawn_reserve(0), to get the smallest initial size). It could just be a clear memory vs. performance trade-off. The caching of stack segments won't be needed because stack growth would just be a fallback. From danielmicay at gmail.com Thu Jul 4 17:07:46 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Thu, 4 Jul 2013 20:07:46 -0400 Subject: [rust-dev] Segmented stacks (was: IsRustSlimYet (IsRustFastYet v2)) In-Reply-To: References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> <51D5F81F.5020204@mozilla.com> Message-ID: On Thu, Jul 4, 2013 at 7:49 PM, Daniel Micay wrote: > On Thu, Jul 4, 2013 at 6:33 PM, Patrick Walton wrote: >> On 7/4/13 12:58 PM, Daniel Micay wrote: >>> >>> You can create many threads with fixed stacks, they just start off >>> using 4K instead of however much smaller our segmented stacks will be. >>> A scheduler will just be more expensive than a regular lightweight >>> task. >>> >>> The 15-100% performance hit from segmented stacks pushes Rust well out >>> of the systems language niche. I think it does have to change if Rust >>> plans on ever fitting in the niche that C, C++ and D do. >> >> >> I agree. The sole benefit of segmented stacks on modern OS's that lazily >> allocate pages is that, on 32-bit, you can avoid running out of address >> space with many tasks. This is counterbalanced by these disadvantages: > > If we do manage to get them significantly smaller than the page size, > they're still potentially useful for I/O handling or as coroutines on > x86_64. Like Go, we need to handle system calls and allocation within > code aware of segmented stacks for them to really be useful. Something else to note here is that a system call on Linux with the syscall instruction is only 2-3x as slow as our current FFI calls. Even a really terrible allocator would likely be better than what we're doing right now. From aatch at aatch.net Thu Jul 4 17:37:39 2013 From: aatch at aatch.net (James Miller) Date: Fri, 5 Jul 2013 12:37:39 +1200 Subject: [rust-dev] 64-bit Windows In-Reply-To: <51D5AAA5.7030501@mozilla.com> References: <51D5AAA5.7030501@mozilla.com> Message-ID: <20130705003735.GA25481@freya.fritz.box> On 2013-07-04 10:02:29, Graydon Hoare wrote: > On 13-07-03 11:32 PM, Lilly Matsson wrote: > >Hello! > > > >I recently made a post on Reddit > >(http://www.reddit.com/r/rust/comments/1hk25r/rust_on_64bit_windows_7/) > >asking about 64-bit Windows support, and kibwen urged me to post here to > >start some kind of discussion about the current state of 64-bit Windows > >support. > > > >So, what is the deal? What needs to be done to fully get 64-bit support > >for Windows? As I understand it, it has to do with LLVM. > > - Add a new target and host config in the makefiles. > > - Fiddle with the target-specific data layout string in > librustc::back > I'm currently working on stuff related to these two points at the moment, for the record. Basically moving the current target-handling stuff all to one place and making it run through a `~Target` trait object. This is based off of the related code in Clang currently. The code I currently have will _theoretically_ support every major platform, with there currently being code for MingW32, Cygwin and Win32 separately. >From what I can tell, 64-bit MinGW is still considered to be MinGW32, just on a 64-bit architecture (This is based on the fact that the LLVM target triple code doesn't have a 'mingw64' entry). This means that when I'm done, it should be pretty easy to "port" to a new platform just by updating some build files and fixing any breakage. -- James Miller From thadguidry at gmail.com Thu Jul 4 18:25:52 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Thu, 4 Jul 2013 20:25:52 -0500 Subject: [rust-dev] 64-bit Windows In-Reply-To: <20130705003735.GA25481@freya.fritz.box> References: <51D5AAA5.7030501@mozilla.com> <20130705003735.GA25481@freya.fritz.box> Message-ID: Luqman and I found out today some interesting bits from the mngw guys on IRC... I'm going to continue documenting what I find on the Wiki page https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust under a new 64bit Windows building section. But here is the info so far: ( I set my MinGW64 path with a statement at the bottom of my MinGW/msys/1.0/etc/proifle with # Enable MinGW64 path export PATH="/c/mingw-builds/x64-4.8.1-win32-seh-rev1/mingw64/bin:/usr/local:$PATH" ) >From what we gathered the mingw-w64 toolchain installer [1] works well with the following easy installer settings: Install path is C:\mingw-builds Version: (to be determined what the max version of GCC to be that build correctly ? at 4.8.1 currently) Architecture: x64 Threads: win32 Exception: seh Build revision: (whichever latest for mingw-w64) This was based on our conversation with jon_y in mingw channel. [snip] jon_y: be aware that if you use the posix thread gcc, all your code will depend on the pthred dll whether you actually use pthreads or not jon_y: libgcc itself pulls in pthreads Thad: for our Rust (Windows) users...we'd choose win32 threads Thad: we instruct them on how to build it within the MinGW/Msys environment on our wiki jon_y: sure, the link I gave you will not support C++11 threads Thad: jon luqman says we don't need them. he would know. jon_y: ok Thad: so I think just the win32 thread with SEH for Win64 host is ideal Thad: thanks so so much jon_y: try to use the installer Thad: yeah a simple switch for that... easy jon_y: rather than pointing users to the link directly Thad: yeah, agree.... we will... I'll write it up and modify our step by step for Windows users today. Thanks ! jon_y: c++11 threads is the only reason you'd use the posix thread gcc on windpws jon_y: *windows jon_y: np Thad: I"ll also make a note about that as well. [1] - http://sourceforge.net/projects/mingwbuilds (green button download installer.exe) On Thu, Jul 4, 2013 at 7:37 PM, James Miller wrote: > On 2013-07-04 10:02:29, Graydon Hoare wrote: > > On 13-07-03 11:32 PM, Lilly Matsson wrote: > > >Hello! > > > > > >I recently made a post on Reddit > > >(http://www.reddit.com/r/rust/comments/1hk25r/rust_on_64bit_windows_7/) > > >asking about 64-bit Windows support, and kibwen urged me to post here to > > >start some kind of discussion about the current state of 64-bit Windows > > >support. > > > > > >So, what is the deal? What needs to be done to fully get 64-bit support > > >for Windows? As I understand it, it has to do with LLVM. > > > > - Add a new target and host config in the makefiles. > > > > - Fiddle with the target-specific data layout string in > > librustc::back > > > > I'm currently working on stuff related to these two points at the moment, > for > the record. Basically moving the current target-handling stuff all to one > place > and making it run through a `~Target` trait object. This is based off of > the > related code in Clang currently. > > The code I currently have will _theoretically_ support every major > platform, > with there currently being code for MingW32, Cygwin and Win32 separately. > From what I can tell, 64-bit MinGW is still considered to be MinGW32, just > on a > 64-bit architecture (This is based on the fact that the LLVM target triple > code > doesn't have a 'mingw64' entry). > > This means that when I'm done, it should be pretty easy to "port" to a new > platform just by updating some build files and fixing any breakage. > > -- > James Miller > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- -Thad Thad on Freebase.com Thad on LinkedIn -------------- next part -------------- An HTML attachment was scrubbed... URL: From thadguidry at gmail.com Thu Jul 4 18:29:10 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Thu, 4 Jul 2013 20:29:10 -0500 Subject: [rust-dev] 64-bit Windows In-Reply-To: References: <51D5AAA5.7030501@mozilla.com> <20130705003735.GA25481@freya.fritz.box> Message-ID: Incidentally, the mingw guys plan to have x32 SEH (not just x64 SEH) working and available in 2014... something about letting a Borland patent having to expire... On Thu, Jul 4, 2013 at 8:25 PM, Thad Guidry wrote: > Luqman and I found out today some interesting bits from the mngw guys on > IRC... > > I'm going to continue documenting what I find on the Wiki page > https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust > > under a new 64bit Windows building section. > > But here is the info so far: > > ( > I set my MinGW64 path with a statement at the bottom of my > MinGW/msys/1.0/etc/proifle with > # Enable MinGW64 path > export > PATH="/c/mingw-builds/x64-4.8.1-win32-seh-rev1/mingw64/bin:/usr/local:$PATH" > ) > > From what we gathered the mingw-w64 toolchain installer [1] works well > with the following easy installer settings: > > Install path is C:\mingw-builds > > Version: (to be determined what the max version of GCC to be that build > correctly ? at 4.8.1 currently) > Architecture: x64 > Threads: win32 > Exception: seh > Build revision: (whichever latest for mingw-w64) > > This was based on our conversation with jon_y in mingw channel. > > [snip] > jon_y: be aware that if you use the posix thread gcc, all your code will > depend on the pthred dll whether you actually use pthreads or not > jon_y: libgcc itself pulls in pthreads > Thad: for our Rust (Windows) users...we'd choose win32 threads > Thad: we instruct them on how to build it within the MinGW/Msys > environment on our wiki > jon_y: sure, the link I gave you will not support C++11 threads > Thad: jon luqman says we don't need them. he would know. > jon_y: ok > Thad: so I think just the win32 thread with SEH for Win64 host is ideal > Thad: thanks so so much > jon_y: try to use the installer > Thad: yeah a simple switch for that... easy > jon_y: rather than pointing users to the link directly > Thad: yeah, agree.... we will... I'll write it up and modify our step by > step for Windows users today. Thanks ! > jon_y: c++11 threads is the only reason you'd use the posix thread gcc on > windpws > jon_y: *windows > jon_y: np > Thad: I"ll also make a note about that as well. > > [1] - http://sourceforge.net/projects/mingwbuilds (green button download > installer.exe) > > > > > On Thu, Jul 4, 2013 at 7:37 PM, James Miller wrote: > >> On 2013-07-04 10:02:29, Graydon Hoare wrote: >> > On 13-07-03 11:32 PM, Lilly Matsson wrote: >> > >Hello! >> > > >> > >I recently made a post on Reddit >> > >(http://www.reddit.com/r/rust/comments/1hk25r/rust_on_64bit_windows_7/ >> ) >> > >asking about 64-bit Windows support, and kibwen urged me to post here >> to >> > >start some kind of discussion about the current state of 64-bit Windows >> > >support. >> > > >> > >So, what is the deal? What needs to be done to fully get 64-bit support >> > >for Windows? As I understand it, it has to do with LLVM. >> > >> > - Add a new target and host config in the makefiles. >> > >> > - Fiddle with the target-specific data layout string in >> > librustc::back >> > >> >> I'm currently working on stuff related to these two points at the moment, >> for >> the record. Basically moving the current target-handling stuff all to one >> place >> and making it run through a `~Target` trait object. This is based off of >> the >> related code in Clang currently. >> >> The code I currently have will _theoretically_ support every major >> platform, >> with there currently being code for MingW32, Cygwin and Win32 separately. >> From what I can tell, 64-bit MinGW is still considered to be MinGW32, >> just on a >> 64-bit architecture (This is based on the fact that the LLVM target >> triple code >> doesn't have a 'mingw64' entry). >> >> This means that when I'm done, it should be pretty easy to "port" to a new >> platform just by updating some build files and fixing any breakage. >> >> -- >> James Miller >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> > > > > -- > -Thad > Thad on Freebase.com > Thad on LinkedIn > -- -Thad Thad on Freebase.com Thad on LinkedIn -------------- next part -------------- An HTML attachment was scrubbed... URL: From ben.striegel at gmail.com Thu Jul 4 19:16:20 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Thu, 4 Jul 2013 22:16:20 -0400 Subject: [rust-dev] Segmented stacks (was: IsRustSlimYet (IsRustFastYet v2)) In-Reply-To: References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> <51D5F81F.5020204@mozilla.com> Message-ID: Would moving away from segmented stacks also allow us to bring jemalloc back? -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Thu Jul 4 19:18:17 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Thu, 4 Jul 2013 22:18:17 -0400 Subject: [rust-dev] Segmented stacks (was: IsRustSlimYet (IsRustFastYet v2)) In-Reply-To: References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> <51D5F81F.5020204@mozilla.com> Message-ID: On Thu, Jul 4, 2013 at 10:16 PM, Benjamin Striegel wrote: > Would moving away from segmented stacks also allow us to bring jemalloc > back? Not if we still have them as an optional feature. We'll still hit the same problem as before. From bklooste at gmail.com Thu Jul 4 19:24:39 2013 From: bklooste at gmail.com (Bennie Kloosteman) Date: Fri, 5 Jul 2013 10:24:39 +0800 Subject: [rust-dev] Fwd: IsRustSlimYet (IsRustFastYet v2) In-Reply-To: References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> Message-ID: Still the cost is 10* and the stack is only 2* part of it..so there are bigger issues . Speaking of stacks sIngularity used segmented stacks..and it did not give a big issues ( and that is for the whole OS) .. maybe someone should have a closer look. Here is a quote . Note the compiler analysis to determine the stack space needed i have attached the name of the paper that references it . 3.3.1 Stack Management Singularity uses linked stacks to reduce the memory overhead of a thread. These stacks grow on demand by adding non-contiguous segments of 4K or more. Singularity?s compiler performs static interprocedural analysis to optimize placement of overflow tests [51]. Each of these compiler-inserted checks is trusted code that accesses system data structures, residing in the process?s object space, to determine the amount of space remaining in the current stack segment. Before the running thread pushes a new stack frame which would potentially allow overflow of the current stack segment, the trusted code calls a kernel method, which disable interrupts and invokes the page manager to allocate a new stack segment. This code also initializes the first stack frame in the segment?between the running procedure and its callee?to call the segment unlink routine, which will deallocate the segment when the stack is popped. Since all processes run in ring 0 on an x86, the current stack segment must always leave enough room for the processor to save an interrupt or exception frame, before the handler switches to a dedicated interrupt stack. 51. von Behren, R., Condit, J., Zhou, F., Necula, G.C. and Brewer, E. Capriccio: Scalable Threads for Internet Services. in Proceedings of the Nineteenth ACM Symposium on Operating Systems Principles (SOSP '03), Bolton Landing, NY, 2003, 268- 281. On Fri, Jul 5, 2013 at 3:58 AM, Daniel Micay wrote: > On Thu, Jul 4, 2013 at 3:52 PM, Matthieu Monrocq > wrote: > > > > You are here assuming that one will not create many schedulers, which the > > current design allows. > > > > (Not necessarily a bad idea, per se, just wanted to point out a possible > new > > limitation) > > > > -- Matthieu > > You can create many threads with fixed stacks, they just start off > using 4K instead of however much smaller our segmented stacks will be. > A scheduler will just be more expensive than a regular lightweight > task. > > The 15-100% performance hit from segmented stacks pushes Rust well out > of the systems language niche. I think it does have to change if Rust > plans on ever fitting in the niche that C, C++ and D do. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From thadguidry at gmail.com Thu Jul 4 19:30:44 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Thu, 4 Jul 2013 21:30:44 -0500 Subject: [rust-dev] Segmented stacks (was: IsRustSlimYet (IsRustFastYet v2)) In-Reply-To: <51D5F81F.5020204@mozilla.com> References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> <51D5F81F.5020204@mozilla.com> Message-ID: On Windows there's a better way than DWARF or SJLJ to catch exceptions I learned today. (I have no idea what I am talking about, but here goes from what I read...) Windows uses it's own exception handling mechanism known as SEH. GCC supports SEH on Win64 (and has plans I think later for Win32?) More info in the answer here: http://stackoverflow.com/questions/15670169/what-is-difference-between-sjlj-vs-dwarf-vs-seh/15685229#15685229 and issues here: http://comments.gmane.org/gmane.comp.gcc.help/44153 On Thu, Jul 4, 2013 at 5:33 PM, Patrick Walton wrote: > On 7/4/13 12:58 PM, Daniel Micay wrote: > >> You can create many threads with fixed stacks, they just start off >> using 4K instead of however much smaller our segmented stacks will be. >> A scheduler will just be more expensive than a regular lightweight >> task. >> >> The 15-100% performance hit from segmented stacks pushes Rust well out >> of the systems language niche. I think it does have to change if Rust >> plans on ever fitting in the niche that C, C++ and D do. >> > > I agree. The sole benefit of segmented stacks on modern OS's that lazily > allocate pages is that, on 32-bit, you can avoid running out of address > space with many tasks. This is counterbalanced by these disadvantages: > > 1. There is no way for the compiler or runtime to know ahead of time how > much stack any given task will need, because this is based on dynamic > control flow. > > 2. The consequence of overshooting (choosing a stack size that is too big) > is that the benefit above is reduced. > > 3. The consequence of undershooting (choosing a stack size that is too > small) is disastrous performance. In the limit, the performance degrades to > something like what many Schemes and SML/NJ do, in that stack frames are > malloc'd from the heap. Except that Scheme and SML/NJ have precise > generational garbage collectors with bump allocators in the nursery, and we > have C malloc(). Furthermore, stack segment allocation is the slow path in > C malloc, because it's in a high storage class. So performance becomes > abysmal in the slow path. Unlike systems like Erlang and Cilk, there is no > way to relocate stack segments in Rust because of unmanaged interior > pointers: Erlang could at least in theory correct its mistakes and keep > stacks contiguous (although I don't know if the implementation does). So > the best we can do is cache and hope for the best--but too much caching > increases memory usage and decreases the benefits of stack segments! > > 4. The benefit above is significantly reduced when calling into C code, > and all solutions to this either hurt the benefit more or significantly > penalize the FFI. > > I think that segmented stacks just don't work. *Relocatable* stacks may > work, but not in Rust. From what I have read, Walter Bright and Rob Pike > agree. > > At this point I'd like to suggest just allowing the user to choose a stack > size on a per-task basis, and failing if the stack size is exceeded. > Basically `__morestack` would turn into `fail`. > > Brian has pointed out to me that, currently, running out of stack has to > abort the whole process, because the DWARF unwinder doesn't consider > `__morestack` a "may-throw" position and as a result the arguments would > leak. There are a number of ways we could fix this, ranging from principled > to hacky. But for now I think aborting on stack exhaustion wouldn't be the > end of the world (although others may disagree). > > Patrick > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -- -Thad Thad on Freebase.com Thad on LinkedIn -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Thu Jul 4 19:32:57 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Thu, 4 Jul 2013 22:32:57 -0400 Subject: [rust-dev] Fwd: IsRustSlimYet (IsRustFastYet v2) In-Reply-To: References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> Message-ID: Rust makes heavy use of FFI to call out to C, and C doesn't use segmented stacks, so Rust assumes they need 2MiB of stack space. If we get rid of everything in the standard library calling out to C, it might just mean a reasonable 10-30% performance hit but I don't see that happening soon. From james at mansionfamily.plus.com Thu Jul 4 22:54:18 2013 From: james at mansionfamily.plus.com (james) Date: Fri, 05 Jul 2013 06:54:18 +0100 Subject: [rust-dev] Segmented stacks In-Reply-To: <51D5F81F.5020204@mozilla.com> References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> <51D5F81F.5020204@mozilla.com> Message-ID: <51D65F8A.4040707@mansionfamily.plus.com> On 04/07/2013 23:33, Patrick Walton wrote: > stack segment allocation is the slow path in C malloc, because it's in > a high storage class. If the segments are allocated from a selection of standard sizes, can you not have a (hardware) thread-local pool for each size and dump to a shared pool? I know modern allocators try to perform a similar optimisation but the requirement here is surely more constrained than the general allocation case, and if you ever hit a stop-the-world across threads then you can also balance out the pools if necessary. Is it actually the allocation that is expensive, or is it the check to see if a new segment is needed? How much would it hurt to lose a register in calls? If a function made a check on how much stack space there is remaining and it calls some further function, then it could typically tell that function how much space remains. When functions are inlined, are the stack checks all combined? It seems odd that the impact should be so high. James From graydon at mozilla.com Fri Jul 5 00:27:16 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 05 Jul 2013 00:27:16 -0700 Subject: [rust-dev] Segmented stacks In-Reply-To: References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> <51D5F81F.5020204@mozilla.com> Message-ID: <51D67554.9060301@mozilla.com> On 13-07-04 07:30 PM, Thad Guidry wrote: > On Windows there's a better way than DWARF or SJLJ to catch exceptions I > learned today. (I have no idea what I am talking about, but here goes > from what I read...) > > Windows uses it's own exception handling mechanism known as SEH. GCC > supports SEH on Win64 (and has plans I think later for Win32?) We're aware of SEH; it is not supported by LLVM. Also win64 uses vectored exception handling (VEH) which is different once more, and also not supported by LLVM. We're planning on using return-unwind on windows. https://github.com/mozilla/rust/pull/4342 -Graydon From graydon at mozilla.com Fri Jul 5 00:37:33 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 05 Jul 2013 00:37:33 -0700 Subject: [rust-dev] Segmented stacks In-Reply-To: <51D65F8A.4040707@mansionfamily.plus.com> References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> <51D5F81F.5020204@mozilla.com> <51D65F8A.4040707@mansionfamily.plus.com> Message-ID: <51D677BD.5090307@mozilla.com> On 13-07-04 10:54 PM, james wrote: > If the segments are allocated from a selection of standard sizes, can > you not have a (hardware) thread-local pool for each size and dump to a > shared pool? No. We should be, but we've not moved to a single page-size pool yet. I hope to move to this design as well as a uniform-page-pool for the mostly-copying GC. But this is all a ways off. > Is it actually the allocation that is expensive, or is it the check to > see if a new segment is needed? The allocation and relatively complex logic around it. I think this could be simplified a lot, but it's very delicate and nobody's looked at it in a while. The checks are a tax but they're pretty constant and CPUs can chew through them pretty fast. > How much would it hurt to lose a register in calls? If a function made > a check on how much stack space there is remaining and it calls some > further function, then it could typically tell that function how much > space remains. It's all done by comparing the stack pointer to a reserved segment register. The growth-prologue on x64 looks like this: 400b90: 64 48 3b 24 25 70 00 cmp %fs:0x70,%rsp 400b97: 00 00 400b99: 77 1a ja 400bb5 400b9b: 49 ba 08 00 00 00 00 movabs $0x8,%r10 400ba2: 00 00 00 400ba5: 49 bb 00 00 00 00 00 movabs $0x0,%r11 400bac: 00 00 00 400baf: e8 28 00 00 00 callq 400bdc <__morestack> 400bb4: c3 retq > When functions are inlined, are the stack checks all combined? Yes. > It seems odd that the impact should be so high. I agree that it's higher than it seems it "needs to be". But it will always be unnecessary overhead on x64; it really makes no sense there. The address space is enormous and it's all lazily committed. -Graydon From igor at mir2.org Fri Jul 5 01:44:16 2013 From: igor at mir2.org (Igor Bukanov) Date: Fri, 5 Jul 2013 10:44:16 +0200 Subject: [rust-dev] Segmented stacks In-Reply-To: <51D677BD.5090307@mozilla.com> References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> <51D5F81F.5020204@mozilla.com> <51D65F8A.4040707@mansionfamily.plus.com> <51D677BD.5090307@mozilla.com> Message-ID: On 5 July 2013 09:37, Graydon Hoare wrote: > It's all done by comparing the stack pointer to a reserved segment register. > The growth-prologue on x64 looks like this: I am curious, has moving stack checks to the caller been considered so a function code can assume that it always has enough space for its frame? It allows to replace checks in a all functions that a parent calls by a single check in the parent for the max stack size. And if the function does not call anything, then it does not contain any stack checks. From bill_myers at outlook.com Fri Jul 5 13:58:02 2013 From: bill_myers at outlook.com (Bill Myers) Date: Fri, 5 Jul 2013 20:58:02 +0000 Subject: [rust-dev] Segmented stacks (was: IsRustSlimYet (IsRustFastYet v2)) In-Reply-To: <51D5F81F.5020204@mozilla.com> References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet>, , , , <51D5F81F.5020204@mozilla.com> Message-ID: I believe that instead of segmented stacks, the runtime should determine a tight upper bound for stack space for the a task's function, and only allocate a fixed stack of that size, falling back to a large "C-sized" stack if a bound cannot be determined. Such a bound can always be computed if there is no recursion, dynamic dispatch, dynamic allocation on the stack, or foreign C functions. And in fact, it can probably be computed even for foreign C functions, as long as DWARF exception tables are available, or some constraints on machine code are assumed (i.e. that negative offsets are not applied to pointers to the stack stored in memory). This would allow for instance to transform many simple internal iterators into external ones automatically via coroutines, without large memory overhead. -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Fri Jul 5 14:07:14 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Fri, 5 Jul 2013 17:07:14 -0400 Subject: [rust-dev] Segmented stacks (was: IsRustSlimYet (IsRustFastYet v2)) In-Reply-To: References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> <51D5F81F.5020204@mozilla.com> Message-ID: On Fri, Jul 5, 2013 at 4:58 PM, Bill Myers wrote: > I believe that instead of segmented stacks, the runtime should determine a > tight upper bound for stack space for the a task's function, and only > allocate a fixed stack of that size, falling back to a large "C-sized" stack > if a bound cannot be determined. > > Such a bound can always be computed if there is no recursion, dynamic > dispatch, dynamic allocation on the stack, or foreign C functions. > In practice this means everything would use a large stack. It misses the use case of scaling up tasks to many I/O requests by trading off performance for small size. From james at mansionfamily.plus.com Fri Jul 5 14:43:15 2013 From: james at mansionfamily.plus.com (james) Date: Fri, 05 Jul 2013 22:43:15 +0100 Subject: [rust-dev] Segmented stacks In-Reply-To: <51D677BD.5090307@mozilla.com> References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> <51D5F81F.5020204@mozilla.com> <51D65F8A.4040707@mansionfamily.plus.com> <51D677BD.5090307@mozilla.com> Message-ID: <51D73DF3.7030106@mansionfamily.plus.com> On 05/07/2013 08:37, Graydon Hoare wrote: > I agree that it's higher than it seems it "needs to be". But it will > always be unnecessary overhead on x64; it really makes no sense there. > The address space is enormous and it's all lazily committed. I don't think you can rely on 'lazily committed'. Not on a system that is properly engineered anyway. From danielmicay at gmail.com Fri Jul 5 15:05:49 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Fri, 5 Jul 2013 18:05:49 -0400 Subject: [rust-dev] Segmented stacks In-Reply-To: <51D73DF3.7030106@mansionfamily.plus.com> References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> <51D5F81F.5020204@mozilla.com> <51D65F8A.4040707@mansionfamily.plus.com> <51D677BD.5090307@mozilla.com> <51D73DF3.7030106@mansionfamily.plus.com> Message-ID: On Fri, Jul 5, 2013 at 5:43 PM, james wrote: > On 05/07/2013 08:37, Graydon Hoare wrote: >> >> I agree that it's higher than it seems it "needs to be". But it will >> always be unnecessary overhead on x64; it really makes no sense there. The >> address space is enormous and it's all lazily committed. > > > I don't think you can rely on 'lazily committed'. Not on a system that is > properly engineered anyway. You can rely on it, it's the standard behaviour on Linux. The actual consumed memory will be equal to the size of the pages that have been touched. From daede003 at umn.edu Fri Jul 5 15:43:52 2013 From: daede003 at umn.edu (Thomas Daede) Date: Fri, 5 Jul 2013 17:43:52 -0500 Subject: [rust-dev] Segmented stacks In-Reply-To: References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> <51D5F81F.5020204@mozilla.com> <51D65F8A.4040707@mansionfamily.plus.com> <51D677BD.5090307@mozilla.com> <51D73DF3.7030106@mansionfamily.plus.com> Message-ID: On Fri, Jul 5, 2013 at 5:05 PM, Daniel Micay wrote: > You can rely on it, it's the standard behaviour on Linux. The actual > consumed memory will be equal to the size of the pages that have been > touched. Has anyone actually tested the performance of a a highly fragmented page table resulting from very small increments in stack usage? If Linux lazily allocates pages, wouldn't that involve potentially a large lookup cost in the kernel, similar or greater than Rust's userspace segmented stack usage? Why can the kernel supposedly perform so much better? From danielmicay at gmail.com Fri Jul 5 15:52:50 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Fri, 5 Jul 2013 18:52:50 -0400 Subject: [rust-dev] Segmented stacks In-Reply-To: References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> <51D5F81F.5020204@mozilla.com> <51D65F8A.4040707@mansionfamily.plus.com> <51D677BD.5090307@mozilla.com> <51D73DF3.7030106@mansionfamily.plus.com> Message-ID: On Fri, Jul 5, 2013 at 6:43 PM, Thomas Daede wrote: > On Fri, Jul 5, 2013 at 5:05 PM, Daniel Micay wrote: >> You can rely on it, it's the standard behaviour on Linux. The actual >> consumed memory will be equal to the size of the pages that have been >> touched. > > Has anyone actually tested the performance of a a highly fragmented > page table resulting from very small increments in stack usage? If > Linux lazily allocates pages, wouldn't that involve potentially a > large lookup cost in the kernel, similar or greater than Rust's > userspace segmented stack usage? Why can the kernel supposedly perform > so much better? It's very fast and has little overhead. We're not going to do come close to the performance of the kernel and the MMU. The kernel is asking the MMU to fault on writes to the pages, it's close to free. If you allocate 100k 2MiB stacks and touch one page in each, the memory usage in userland is 390MiB as expected. If you touch 4 pages in each, the userland memory usage is 1560MiB and there's only a space overhead of maybe 20% separate from the process (it quickly drops down to less than 1% as you touch more pages, but it's hard to measure accurately). From marcianx at gmail.com Fri Jul 5 22:26:30 2013 From: marcianx at gmail.com (Ashish Myles) Date: Sat, 6 Jul 2013 01:26:30 -0400 Subject: [rust-dev] deriving Clone on a struct with a static vector Message-ID: 1. The following code ---- #[deriving(Clone)] struct V { v : [f64, ..3] } fn main() { } ---- gives the following error ---- tmp.rs:1:11: 1:16 error: mismatched types: expected `[f64, .. 3]` but found `&[f64, .. 3]` (expected vector but found &-ptr) tmp.rs:1 #[deriving(Clone)] ---- Is this intended behavior or a bug? 2. Also, how does one now implement the Copy trait anymore? Using #[deriving Copy] currently gives the following error error: unknown `deriving` trait: `Copy` -------------- next part -------------- An HTML attachment was scrubbed... URL: From marcianx at gmail.com Fri Jul 5 22:42:02 2013 From: marcianx at gmail.com (Ashish Myles) Date: Sat, 6 Jul 2013 01:42:02 -0400 Subject: [rust-dev] deriving Clone on a struct with a static vector In-Reply-To: References: Message-ID: And an additional question. 3. What is the rationale in having both Copy and Clone? Can one provide an exhaustive list for where one would want to use Copy instead of Clone/DeepClone? I tried to use clone everywhere, but I needed to be able to write, for example, [Zero::zero(),.. 3] as in the following code ---- struct V { v : [T, ..3] } impl V { pub fn new() -> V { V { v: [Zero::zero(), ..3] } } } ---- (As the actual code was from a macro that was parametrized by the number of elements, I don't want to simply rewrite the initialization above as [Zero::zero(), Zero::zero(), Zero::zero()] to avoid the dependence on Copy.) From pwalton at mozilla.com Fri Jul 5 22:43:07 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Fri, 05 Jul 2013 22:43:07 -0700 Subject: [rust-dev] deriving Clone on a struct with a static vector In-Reply-To: References: Message-ID: <51D7AE6B.8060803@mozilla.com> On 7/5/13 10:42 PM, Ashish Myles wrote: > And an additional question. > 3. What is the rationale in having both Copy and Clone? Can one > provide an exhaustive list for where one would want to use Copy > instead of Clone/DeepClone? I tried to use clone everywhere, but I > needed to be able to write, for example, > [Zero::zero(),.. 3] as in the following code I'm busy removing Copy from the language right now. Regarding your initial question, we need some implementations of Clone for various standard vector sizes in the standard library. Patrick From graydon at mozilla.com Sat Jul 6 00:24:45 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Sat, 06 Jul 2013 00:24:45 -0700 Subject: [rust-dev] rusti and bors Message-ID: <51D7C63D.6090500@mozilla.com> It seems that rusti is not stable enough to be part of normal integration tests; completely unrelated changes are causing it to fail more often than not, and bors is backing up with changes that are otherwise fine. I discussed with folks on IRC and the consensus seemed to be disabling rusti tests until LLVM gets upgraded, since it's going to bring a lot of JIT fixes. If everyone else is ok with that, I'll land a change that disables them. (I'm a little concerned about rusti bitrotting again, but am not sure what else we can do in the short term. The failures all seem pretty opaque -- lockups and crashes.) -Graydon From dbau.pp at gmail.com Sat Jul 6 01:18:59 2013 From: dbau.pp at gmail.com (Huon Wilson) Date: Sat, 06 Jul 2013 18:18:59 +1000 Subject: [rust-dev] deriving Clone on a struct with a static vector In-Reply-To: References: Message-ID: <51D7D2F3.4060106@gmail.com> On 06/07/13 15:26, Ashish Myles wrote: > 1. The following code > ---- > #[deriving(Clone)] > struct V { > v : [f64, ..3] > } > > fn main() { > } > ---- > gives the following error > ---- > tmp.rs:1:11: 1:16 error: mismatched types: expected `[f64, .. 3]` but > found `&[f64, .. 3]` (expected vector but found &-ptr) > tmp.rs:1 #[deriving(Clone)] > ---- > Is this intended behavior or a bug? > It's a bug. The fixed-length vectors don't implement any traits (#7622), because they have to be implemented by hand (well, by macro would be more reasonable) for each size, and there are a lot of possible sizes. The error message is very opaque (#7621, I borrowed your example, thanks), since it is calling Clone on `&T` where `T` is not Clone, and this means that it just copies the reference. That is, #[deriving] creates an clone method where the body is (basically) `V { v: (&self.v).clone() }`, but the .clone() call is cloning the reference (something of type `&([f64, .. 3])`), not the vector itself (`[f64, .. 3]`), so there's a type error, but not a very useful one. (Fixed-length vectors are poorly handled in general, e.g. #5520 and #7045) Huon 5520: https://github.com/mozilla/rust/issues/5520 7045: https://github.com/mozilla/rust/issues/7045 7621: https://github.com/mozilla/rust/issues/7621 7622: https://github.com/mozilla/rust/issues/7622 -------------- next part -------------- An HTML attachment was scrubbed... URL: From kballard at gmail.com Sat Jul 6 02:20:28 2013 From: kballard at gmail.com (Kevin Ballard) Date: Sat, 6 Jul 2013 02:20:28 -0700 Subject: [rust-dev] Proposal for string encodings Message-ID: I've been thinking about string encoding support lately, and the approach I've decided to experiment with is representing a string encoding as a pair of external Iterators. The encoder is an Iterator that consumes an Iterator, and the decoder is an Iterator that consumes an Iterator. A pair of conditions is used to control error handling, with the default behavior to use U+FFFD REPLACEMENT CHAR. Today I implemented this as a new module std::encoding, with a proof-of-concept UTF-16 implementation. This is available on my fork at https://github.com/kballard/rust/tree/encodings (current compiling commit is https://github.com/kballard/rust/commit/54b5b50f0afd8d5dc329d01109c6b760754d56de; I won't guarantee that the branch will always compile). Usage is slightly awkward at the moment due to the usage of Iterator instead of Iterator<&u8> (and same for char). To convert a UTF-16 &[u8] into a ~[char] you can say let res : ~[u8] = encoding::utf16.decode(src.iter().transform(|&x| x)).collect(); I had hoped to provide a convenience method .decodeBytes() so you could say `encoding::utf16.decodeBytes(src)` but the type system has defeated my attempts to do this so far. I'm inclined to add an .iter_clone() method to vectors, which would turn this into the slightly simpler `encoding::utf16.decode(src.iter_clone()).collect()`. If anyone wants to look over what I have so far, I'd love to get your feedback/suggestions/complaints. -Kevin From jfager at gmail.com Sat Jul 6 02:45:17 2013 From: jfager at gmail.com (Jason Fager) Date: Sat, 6 Jul 2013 05:45:17 -0400 Subject: [rust-dev] deriving Clone on a struct with a static vector In-Reply-To: <51D7AE6B.8060803@mozilla.com> References: <51D7AE6B.8060803@mozilla.com> Message-ID: I've started implementing traits for fixed-length vectors with a few macros: https://gist.github.com/jfager/5936197 I don't have Clone yet, but it should be easy to add. On Saturday, July 6, 2013, Patrick Walton wrote: > On 7/5/13 10:42 PM, Ashish Myles wrote: > >> And an additional question. >> 3. What is the rationale in having both Copy and Clone? Can one >> provide an exhaustive list for where one would want to use Copy >> instead of Clone/DeepClone? I tried to use clone everywhere, but I >> needed to be able to write, for example, >> [Zero::zero(),.. 3] as in the following code >> > > I'm busy removing Copy from the language right now. > > Regarding your initial question, we need some implementations of Clone for > various standard vector sizes in the standard library. > > Patrick > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthieu.monrocq at gmail.com Sat Jul 6 04:56:54 2013 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Sat, 6 Jul 2013 13:56:54 +0200 Subject: [rust-dev] Segmented stacks (was: IsRustSlimYet (IsRustFastYet v2)) In-Reply-To: References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> <51D5F81F.5020204@mozilla.com> Message-ID: On Fri, Jul 5, 2013 at 11:07 PM, Daniel Micay wrote: > On Fri, Jul 5, 2013 at 4:58 PM, Bill Myers wrote: > > I believe that instead of segmented stacks, the runtime should determine > a > > tight upper bound for stack space for the a task's function, and only > > allocate a fixed stack of that size, falling back to a large "C-sized" > stack > > if a bound cannot be determined. > > > > Such a bound can always be computed if there is no recursion, dynamic > > dispatch, dynamic allocation on the stack, or foreign C functions. > > > > In practice this means everything would use a large stack. It misses > the use case of scaling up tasks to many I/O requests by trading off > performance for small size. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > There was, at one point, a discussion on providing a #[reserve_stack(2048)] attribute for extern functions where the developer would indicate to the runtime that said function would never need more than N bytes of stack. It was deemed burdensome, and might be somewhat, however I still believe that annotating some key C extern functions (such as those performing IO) would allow computing this upper-bound in more cases. Of course, the real experiment would be to instrument the compiler and see exactly how many tasks can indeed be so bounded... and *why* the others cannot; unfortunately it might take some time to get it working. -- Matthieu -------------- next part -------------- An HTML attachment was scrubbed... URL: From marcianx at gmail.com Sat Jul 6 08:13:51 2013 From: marcianx at gmail.com (Ashish Myles) Date: Sat, 6 Jul 2013 11:13:51 -0400 Subject: [rust-dev] deriving Clone on a struct with a static vector In-Reply-To: <51D7AE6B.8060803@mozilla.com> References: <51D7AE6B.8060803@mozilla.com> Message-ID: On Sat, Jul 6, 2013 at 1:43 AM, Patrick Walton wrote: > On 7/5/13 10:42 PM, Ashish Myles wrote: >> >> And an additional question. >> 3. What is the rationale in having both Copy and Clone? Can one >> provide an exhaustive list for where one would want to use Copy >> instead of Clone/DeepClone? I tried to use clone everywhere, but I >> needed to be able to write, for example, >> [Zero::zero(),.. 3] as in the following code > > > I'm busy removing Copy from the language right now. > Ah, thanks, then after your refactor, what trait would T : Zero need an implementation of to support [Zero::zero(),.. 3]? Clone? Ashish From mcguire at crsr.net Sat Jul 6 08:26:40 2013 From: mcguire at crsr.net (Tommy M. McGuire) Date: Sat, 06 Jul 2013 10:26:40 -0500 Subject: [rust-dev] Borrow lifetime assignment changed? In-Reply-To: References: Message-ID: <51D83730.8040200@crsr.net> On 07/03/2013 09:53 PM, Ashish Myles wrote: > hello.rs:4:8: 4:33 error: borrowed value does not live long enough I was just about to write asking about this. I discovered it with the following code: for sorted_keys(dict).iter().advance |key| { ... } The result of sorted_keys is a temporary vector, which doesn't seem to live long enough for the iterator. If I give the temporary a name, everything works as expected. -- Tommy M. McGuire mcguire at crsr.net From marcianx at gmail.com Sat Jul 6 08:31:26 2013 From: marcianx at gmail.com (Ashish Myles) Date: Sat, 6 Jul 2013 11:31:26 -0400 Subject: [rust-dev] deriving Clone on a struct with a static vector In-Reply-To: References: <51D7AE6B.8060803@mozilla.com> Message-ID: On Sat, Jul 6, 2013 at 5:45 AM, Jason Fager wrote: > I've started implementing traits for fixed-length vectors with a few macros: > > https://gist.github.com/jfager/5936197 > > I don't have Clone yet, but it should be easy to add. > As a side note, looking through your code, this is cool: ---- struct Foo([u8,..2]); .... Foo([1u8,2u8]) ---- I had no idea one could define single-item/wrapper structs that way; i.e. like an anonymous member. This is going in my cool tidbits collection. Ashish From mcguire at crsr.net Sat Jul 6 08:37:49 2013 From: mcguire at crsr.net (Tommy M. McGuire) Date: Sat, 06 Jul 2013 10:37:49 -0500 Subject: [rust-dev] Weird performance regression in 0.7? Message-ID: <51D839CD.3050409@crsr.net> When I updated my idiotic anagrams-hashmap toy to 0.7, I seem to have run across a weird performance regression involving hashmaps. Previous runs took approximately 6 seconds, but the 0.7 build is 1) taking about 35 seconds and 2) very variable, since rebuilding it and sometimes just running it several more times results in smaller run times of ~22 seconds. Further, inserting some println's to look at what was taking so long reduced the run time to about 9 seconds. It is not limited to that particular program; other versions seem to be affected as well, including anagrams-hashmap-mmap, which was just recently run with a post-incoming-change build of the master branch. (5 seconds vs. 11 seconds.) Any ideas what is going on? https://github.com/tmmcguire/rust-toys/blob/master/anagrams-hashmap.rs https://github.com/tmmcguire/rust-toys/blob/master/anagrams-hashmap-mmap.rs -- Tommy M. McGuire mcguire at crsr.net From bsteinbr at gmail.com Sat Jul 6 08:52:00 2013 From: bsteinbr at gmail.com (=?iso-8859-1?Q?Bj=F6rn?= Steinbrink) Date: Sat, 6 Jul 2013 17:52:00 +0200 Subject: [rust-dev] Weird performance regression in 0.7? In-Reply-To: <51D839CD.3050409@crsr.net> References: <51D839CD.3050409@crsr.net> Message-ID: <20130706155200.GA15803@atjola.homenet> Hi, On 2013.07.06 10:37:49 -0500, Tommy M. McGuire wrote: > Previous runs took approximately 6 seconds, but the 0.7 build is 1) > taking about 35 seconds and 2) very variable, since rebuilding it and > sometimes just running it several more times results in smaller run > times of ~22 seconds. Further, inserting some println's to look at what > was taking so long reduced the run time to about 9 seconds. > > It is not limited to that particular program; other versions seem to be > affected as well, including anagrams-hashmap-mmap, which was just > recently run with a post-incoming-change build of the master branch. (5 > seconds vs. 11 seconds.) I can't seem to reproduce that (with a build of the current master). Maybe I'm doing something wrong? What I did was downloading the necessary source files, then: rustc -O combinations.rs rustc -O mmap.rs rustc -O -L . anagrams-hashmap.rs rustc -O -L . anagrams-hashmap-mmap.rs rust run mk_anadict.rs The generated dictionary has 161642 lines. Results: doener at atjola:rust-play $ time ./anagrams-hashmap wachsames 27 real 0m0.686s user 0m0.672s sys 0m0.014s doener at atjola:rust-play $ time ./anagrams-hashmap-mmap wachsames 27 real 0m0.057s user 0m0.051s sys 0m0.006s Times don't change much across runs. Bj?rn From bsteinbr at gmail.com Sat Jul 6 08:59:02 2013 From: bsteinbr at gmail.com (=?iso-8859-1?Q?Bj=F6rn?= Steinbrink) Date: Sat, 6 Jul 2013 17:59:02 +0200 Subject: [rust-dev] Weird performance regression in 0.7? In-Reply-To: <20130706155200.GA15803@atjola.homenet> References: <51D839CD.3050409@crsr.net> <20130706155200.GA15803@atjola.homenet> Message-ID: <20130706155902.GB15803@atjola.homenet> On 2013.07.06 17:52:00 +0200, Bj?rn Steinbrink wrote: > Hi, > > On 2013.07.06 10:37:49 -0500, Tommy M. McGuire wrote: > > Previous runs took approximately 6 seconds, but the 0.7 build is 1) > > taking about 35 seconds and 2) very variable, since rebuilding it and > > sometimes just running it several more times results in smaller run > > times of ~22 seconds. Further, inserting some println's to look at what > > was taking so long reduced the run time to about 9 seconds. > > > > It is not limited to that particular program; other versions seem to be > > affected as well, including anagrams-hashmap-mmap, which was just > > recently run with a post-incoming-change build of the master branch. (5 > > seconds vs. 11 seconds.) > > I can't seem to reproduce that (with a build of the current master). > Maybe I'm doing something wrong? I obviously did. Using the "results" target from the Makefile, I can see the problem. Bj?rn From jfager at gmail.com Sat Jul 6 09:01:48 2013 From: jfager at gmail.com (Jason Fager) Date: Sat, 6 Jul 2013 12:01:48 -0400 Subject: [rust-dev] deriving Clone on a struct with a static vector In-Reply-To: References: <51D7AE6B.8060803@mozilla.com> Message-ID: Yeah, that is a cool feature. They're called newtype structs, after newtypes in Haskell, discussed in the tutorial at http://static.rust-lang.org/doc/tutorial.html#tuple-structs btw, updated that gist w/ a hacky impl of Clone that uses copy, which I think I've heard is going away in the near future. Works for me for now, though. On Sat, Jul 6, 2013 at 11:31 AM, Ashish Myles wrote: > On Sat, Jul 6, 2013 at 5:45 AM, Jason Fager wrote: > > I've started implementing traits for fixed-length vectors with a few > macros: > > > > https://gist.github.com/jfager/5936197 > > > > I don't have Clone yet, but it should be easy to add. > > > > As a side note, looking through your code, this is cool: > ---- > struct Foo([u8,..2]); > .... > Foo([1u8,2u8]) > ---- > I had no idea one could define single-item/wrapper structs that way; > i.e. like an anonymous member. This is going in my cool tidbits > collection. > > Ashish > -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Sat Jul 6 09:57:35 2013 From: corey at octayn.net (Corey Richardson) Date: Sat, 6 Jul 2013 12:57:35 -0400 Subject: [rust-dev] Weird performance regression in 0.7? In-Reply-To: <51D839CD.3050409@crsr.net> References: <51D839CD.3050409@crsr.net> Message-ID: (This or something derived from it would be nice for https://github.com/mozilla/rust/issues/7532) On Sat, Jul 6, 2013 at 11:37 AM, Tommy M. McGuire wrote: > When I updated my idiotic anagrams-hashmap toy to 0.7, I seem to have > run across a weird performance regression involving hashmaps. > > Previous runs took approximately 6 seconds, but the 0.7 build is 1) > taking about 35 seconds and 2) very variable, since rebuilding it and > sometimes just running it several more times results in smaller run > times of ~22 seconds. Further, inserting some println's to look at what > was taking so long reduced the run time to about 9 seconds. > > It is not limited to that particular program; other versions seem to be > affected as well, including anagrams-hashmap-mmap, which was just > recently run with a post-incoming-change build of the master branch. (5 > seconds vs. 11 seconds.) > > Any ideas what is going on? > > https://github.com/tmmcguire/rust-toys/blob/master/anagrams-hashmap.rs > https://github.com/tmmcguire/rust-toys/blob/master/anagrams-hashmap-mmap.rs > > -- > Tommy M. McGuire > mcguire at crsr.net > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From mcguire at crsr.net Sat Jul 6 11:07:30 2013 From: mcguire at crsr.net (Tommy M. McGuire) Date: Sat, 06 Jul 2013 13:07:30 -0500 Subject: [rust-dev] Weird performance regression in 0.7? In-Reply-To: <20130706155902.GB15803@atjola.homenet> References: <51D839CD.3050409@crsr.net> <20130706155200.GA15803@atjola.homenet> <20130706155902.GB15803@atjola.homenet> Message-ID: <51D85CE2.9010307@crsr.net> On 07/06/2013 10:59 AM, Bj?rn Steinbrink wrote: > On 2013.07.06 17:52:00 +0200, Bj?rn Steinbrink wrote: >> Hi, >> >> On 2013.07.06 10:37:49 -0500, Tommy M. McGuire wrote: >>> Previous runs took approximately 6 seconds, but the 0.7 build is 1) >>> taking about 35 seconds and 2) very variable, since rebuilding it and >>> sometimes just running it several more times results in smaller run >>> times of ~22 seconds. Further, inserting some println's to look at what >>> was taking so long reduced the run time to about 9 seconds. >>> >>> It is not limited to that particular program; other versions seem to be >>> affected as well, including anagrams-hashmap-mmap, which was just >>> recently run with a post-incoming-change build of the master branch. (5 >>> seconds vs. 11 seconds.) >> >> I can't seem to reproduce that (with a build of the current master). >> Maybe I'm doing something wrong? > > I obviously did. Using the "results" target from the Makefile, I can see > the problem. Sorry about making it difficult. I've added my anadict.txt to the repository (along with making sure all of the programs use it). Mine is created from /usr/share/dict/words, the wamerican package, Ubuntu 12.04, and has 58505 lines. It produces 111 results on "wachsames" and 7440 on "asdwtribnowplfglewhqagnbe". -- Tommy M. McGuire mcguire at crsr.net From bsteinbr at gmail.com Sat Jul 6 13:21:44 2013 From: bsteinbr at gmail.com (=?iso-8859-1?Q?Bj=F6rn?= Steinbrink) Date: Sat, 6 Jul 2013 22:21:44 +0200 Subject: [rust-dev] Weird performance regression in 0.7? In-Reply-To: <51D839CD.3050409@crsr.net> References: <51D839CD.3050409@crsr.net> Message-ID: <20130706202144.GC15803@atjola.homenet> On 2013.07.06 10:37:49 -0500, Tommy M. McGuire wrote: > When I updated my idiotic anagrams-hashmap toy to 0.7, I seem to have > run across a weird performance regression involving hashmaps. > > Previous runs took approximately 6 seconds, but the 0.7 build is 1) > taking about 35 seconds and 2) very variable, since rebuilding it and > sometimes just running it several more times results in smaller run > times of ~22 seconds. Further, inserting some println's to look at what > was taking so long reduced the run time to about 9 seconds. > > It is not limited to that particular program; other versions seem to be > affected as well, including anagrams-hashmap-mmap, which was just > recently run with a post-incoming-change build of the master branch. (5 > seconds vs. 11 seconds.) > > Any ideas what is going on? Though I can't seem to run into the problem with varying runtimes, I found out at least part of what's wrong with anagram-hashmap (anagram-hashmap-mmap doesn't build with 0.6). The problem is that in 0.7 almost all #[inline(always)] attributes got replaced by just #[inline]. In your code, this causes the write and result function for hashing not to be inlined. On its own, this is not a problem, but unfortunately, that codepath triggers stack growth, which is a problem. doener at atjola:rust-toys (master) $ time ./anagrams-hashmap asdwtribnowplfglewhqabe 6675 real 0m5.724s user 0m5.716s sys 0m0.007s doener at atjola:rust-toys (master) $ time RUST_MIN_STACK=8000000 ./anagrams-hashmap asdwtribnowplfglewhqabe 6675 real 0m1.453s user 0m1.447s sys 0m0.006s This is still 50% slower than the 0.6 version, but I'm not sure yet what's to blame for that. Might be the missing inlining, might be something else. Bj?rn From bsteinbr at gmail.com Sat Jul 6 13:28:44 2013 From: bsteinbr at gmail.com (=?iso-8859-1?Q?Bj=F6rn?= Steinbrink) Date: Sat, 6 Jul 2013 22:28:44 +0200 Subject: [rust-dev] Weird performance regression in 0.7? In-Reply-To: <20130706202144.GC15803@atjola.homenet> References: <51D839CD.3050409@crsr.net> <20130706202144.GC15803@atjola.homenet> Message-ID: <20130706202844.GD15803@atjola.homenet> On 2013.07.06 22:21:44 +0200, Bj?rn Steinbrink wrote: > The problem is that in 0.7 almost all #[inline(always)] attributes got > replaced by just #[inline]. In your code, this causes the write and > result function for hashing not to be inlined. Well, those two among others. Here's the top 5 functions in the 0.6 version: + 79,68% _rust_main + 2,38% _IO_getc + 1,92% _int_free + 1,81% malloc_consolidate + 1,78% upcall_call_shim_on_c_stack And here are the top 10 for the version build with a current master: + 27,66% hash::__extensions__::meth_5785::write::_39f61d6e4ccc62a4::_0$x2e0 + 19,28% hashmap::__extensions__::bucket_for_key_with_hash_5640::_71e677e13b9b19f::_0$x2e0 + 11,78% search::anon::anon::anon::expr_fn_6073 + 10,12% hashmap::__extensions__::find_6075::_c9df72152b93395c::_0$x2e0 + 8,29% search::anon::expr_fn_6013 + 6,27% hash::__extensions__::meth_5787::result_u64::_b414c78da63930e3::_0$x2e0 + 5,38% uint::iterate::_8a579f422041c65::_0$x2e7 + 1,46% _int_free + 1,30% _IO_getc + 1,19% malloc_consolidate Both runs were made with RUST_MIN_STACK=8000000. Bj?rn From corey at octayn.net Sat Jul 6 14:58:03 2013 From: corey at octayn.net (Corey Richardson) Date: Sat, 6 Jul 2013 17:58:03 -0400 Subject: [rust-dev] This Week in Rust Message-ID: Content copied from http://cmr.github.io/blog/2013/07/06/this-week-in-rust/ -- Hello and welcome to the fifth issue of *This Week in Rust*, a weekly overview of Rust and its community. `0.7` was released this week. Hello to the newcomers! I've also decided to put breaking changes first. Feel free to skip the rest, it's relatively unimportant. # Newcomers There's already a lot of traffic from Rust newbies, so you get your own section! Welcome to Rust. I wrote [The State of Rust 0.7](http://cmr.github.io/blog/2013/07/05/the-state-of-rust/) especially for newcomers, so you should read that. Jump on IRC if you have any questions or need help. We're a quite friendly bunch, and we usually don't bite. # What's cooking on master? Issue churn this week was +12. 35 PRs were merged, total PR churn was -8. There continues to be a lot more cleanup than breaking changes, which is encouraging! As I understand it, graydon wants to focus this release cycle on cleanup, rather than language features. Hopefully the compiler can get into a much better state. ## Breaking changes - dbaupp [continues](https://github.com/mozilla/rust/pull/7487) to [slaughter](https://github.com/mozilla/rust/pull/7566) the free functions in `std::vec` where methods can replace them. - He also [added a lint for lowercase statics](https://github.com/mozilla/rust/pull/7523), which is enabled by default because of an astoundingly poor error message. - Seldaek [moved a bunch of iter stuff](https://github.com/mozilla/rust/pull/7474) to `extra`. ## Notable compiler additions, bugfixes, and cleanup - doener [removed an extra layer of indirection](https://github.com/mozilla/rust/pull/7452) that method calls incurred. - Blei [fixed a codegen problem](https://github.com/mozilla/rust/pull/7457) with structs containing `f32` when used with FFI. - I [propagated the great renaming](https://github.com/mozilla/rust/pull/7468) throughout the rest of the codebase (besides compiletest, apparently). - acrichto [rewrote some str code](https://github.com/mozilla/rust/pull/7465) to avoid allocations. - strcat is [removing](https://github.com/mozilla/rust/pull/7495) headers from exchange allocs (see also [#7605](https://github.com/mozilla/rust/pull/7605) and [#7521](https://github.com/mozilla/rust/pull/7521)). They are entirely unused, they just need to be removed and the fallout fixed throughout the compiler. - yjh0502 [fixed a bug](https://github.com/mozilla/rust/pull/7443) that allowed duplicate struct fields (like `struct Foo {a: uint, a: uint}`) - acrichto [turned on](https://github.com/mozilla/rust/pull/7409) LLVM threading. - Luqman [changed configure](https://github.com/mozilla/rust/pull/7498) to require either wget *or* curl. - Dretch [improved the error message](https://github.com/mozilla/rust/pull/7510) for implementing unknown traits to mention the trait name. - sankha93 [improved the error message](https://github.com/mozilla/rust/pull/7531) for trying to capture environment in a plain `fn`. - bblum [improved the error mssage](https://github.com/mozilla/rust/pull/7534) for using a moved value, it now gives better suggestions than just `copy`. - sanxiyn [fixed a bug](https://github.com/mozilla/rust/pull/7543) where eligible newtype structs weren't marked as an immediate value (and thus not passed in registers when they could have been). - Luqman [paved the way](https://github.com/mozilla/rust/pull/7547) for 64-bit windows support. - jensnockert [added byte swapping intrinsics](https://github.com/mozilla/rust/pull/7194) that specialize per-platform, avoiding unnecessary operations. - jld [removed an unused function](https://github.com/mozilla/rust/pull/7554) - sully [fixed more default method bugs](https://github.com/mozilla/rust/pull/7545). ## Notable library additions, bugfixes, and cleanup - sfackler [fixed up some documentation](https://github.com/mozilla/rust/pull/7549) related to the drop/finalize renaming. - acrichto [fixed a correctness bug](https://github.com/mozilla/rust/pull/7530) in TreeMap's `Ord` implementation. - sfackler [much improved](https://github.com/mozilla/rust/pull/7513) and genericized the base64 handling. - graydon did a [bunch of cleanup](https://github.com/mozilla/rust/pull/7518) in `extra::stats`. - Seldaek [fixed a patological case with `str::each_split_within`](https://github.com/mozilla/rust/pull/7475). # Meetings The [Tuesday meeting](https://github.com/mozilla/rust/wiki/Meeting-weekly-2013-07-02) featured more discussion about `@` and `@mut`, that was honestly over my head (as most of the type system stuff is). If someone wants to write some more here, feel free to email me () a paragraph or two. You will get attribution, of course. # Discussion + Blog posts - [The State of Rust 0.7](http://cmr.github.io/blog/2013/07/05/the-state-of-rust/) - ["Rust switches to external iteration" (D forums)](http://forum.dlang.org/thread/kr2vpp$2jmf$1 at digitalmars.com) - [Segmented stacks](https://mail.mozilla.org/pipermail/rust-dev/2013-July/004686.html) - [Is Rust Slim Yet? (Is Rust Fast Yet v2)](http://huonw.github.io/isrustfastyet/mem/) - [Rust Design Patterns](http://joshldavis.com/rust-design-patterns/) - [Program to an Interface, Fool](http://joshldavis.com/2013/07/01/program-to-an-interface-fool/) - [Would You Bet $100,000,000 on [Rust]?](http://www.reddit.com/r/rust/comments/1hg88c/i_think_i_would_take_that_for_rust_when_its_done/) - [mw's third status report](http://michaelwoerister.github.io/2013/06/28/Status-Update-3.html) From marcianx at gmail.com Sat Jul 6 19:09:58 2013 From: marcianx at gmail.com (Ashish Myles) Date: Sat, 6 Jul 2013 22:09:58 -0400 Subject: [rust-dev] Why separate equivalent impls for &'self [A], ~[A], @[A] Message-ID: Perhaps this was an oversight as the code base has developed organically. But in case it was intentional, I just wanted to check. libstd/to_str.rs defines each of the following impls impl<'self,A:ToStr> ToStr for &'self [A] impl ToStr for ~[A] impl ToStr for @[A] whereas only the first one seems to be needed to cover all array cases. To test this, I defined an equivalent MyToStr trait, defining only the implementation for &'self [A], and it seemed to work for all the array types. So just to check: is there any particular reason one would want to define all three with identical implementation? From danielmicay at gmail.com Sat Jul 6 19:26:51 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Sat, 6 Jul 2013 22:26:51 -0400 Subject: [rust-dev] Why separate equivalent impls for &'self [A], ~[A], @[A] In-Reply-To: References: Message-ID: On Sat, Jul 6, 2013 at 10:09 PM, Ashish Myles wrote: > Perhaps this was an oversight as the code base has developed > organically. But in case it was intentional, I just wanted to check. > > libstd/to_str.rs defines each of the following impls > impl<'self,A:ToStr> ToStr for &'self [A] > impl ToStr for ~[A] > impl ToStr for @[A] > whereas only the first one seems to be needed to cover all array > cases. To test this, I defined an equivalent MyToStr trait, defining > only the implementation for &'self [A], and it seemed to work for all > the array types. So just to check: is there any particular reason one > would want to define all three with identical implementation? Vectors will coerce to slices, but the traits still need to be defined on them for it to work in generic code where you only have a type via a generic type parameter. From matthieu.monrocq at gmail.com Sun Jul 7 03:48:35 2013 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Sun, 7 Jul 2013 12:48:35 +0200 Subject: [rust-dev] Borrow lifetime assignment changed? In-Reply-To: <51D83730.8040200@crsr.net> References: <51D83730.8040200@crsr.net> Message-ID: On Sat, Jul 6, 2013 at 5:26 PM, Tommy M. McGuire wrote: > On 07/03/2013 09:53 PM, Ashish Myles wrote: > > hello.rs:4:8: 4:33 error: borrowed value does not live long enough > > I was just about to write asking about this. I discovered it with the > following code: > > for sorted_keys(dict).iter().advance |key| { ... } > > The result of sorted_keys is a temporary vector, which doesn't seem to > live long enough for the iterator. If I give the temporary a name, > everything works as expected. > > > -- > Tommy M. McGuire > mcguire at crsr.net > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > Interesting. There is a specific rule in the C++ specification to address temporaries: they should live up until the end of the full expression they are part of. I suppose that to suppose this case Rust might need the same rule and then determine that "for .... { }" is a single expression. It seems feasible (and maybe partly addressed already) however I cannot help but point out that I regularly see issues related to this popping on the Clang list and commits to fix it "a bit more", apparently it's quite a nest of vipers and has ripple effects on implementing pretty much any other feature of the language. -- Matthieu -------------- next part -------------- An HTML attachment was scrubbed... URL: From bsteinbr at gmail.com Sun Jul 7 06:14:50 2013 From: bsteinbr at gmail.com (=?iso-8859-1?Q?Bj=F6rn?= Steinbrink) Date: Sun, 7 Jul 2013 15:14:50 +0200 Subject: [rust-dev] Weird performance regression in 0.7? In-Reply-To: <20130706202144.GC15803@atjola.homenet> References: <51D839CD.3050409@crsr.net> <20130706202144.GC15803@atjola.homenet> Message-ID: <20130707131450.GE15803@atjola.homenet> On 2013.07.06 22:21:44 +0200, Bj?rn Steinbrink wrote: > The problem is that in 0.7 almost all #[inline(always)] attributes got > replaced by just #[inline]. In your code, this causes the write and > result function for hashing not to be inlined. On its own, this is not a > problem, but unfortunately, that codepath triggers stack growth, which > is a problem. FWIW, I have a PR at https://github.com/mozilla/rust/pull/7636 that improves the situation. At least enough inlining happens to pretty much eliminate the difference between running with and without RUST_MIN_STACK=8000000. Still about 40% slower than the 0.6 version though. Bj?rn From a.stavonin at gmail.com Sun Jul 7 11:49:18 2013 From: a.stavonin at gmail.com (Alexander Stavonin) Date: Sun, 7 Jul 2013 22:49:18 +0400 Subject: [rust-dev] flatpipes question Message-ID: There are two fragments of codes first one can be compiled without any errors: let (port, chan) = flatpipes::serial::pipe_stream(); do task::spawn || { let value = @[1, 2, 3, 4, 5]; chan.send(value) } let val = port.recv(); io::println(fmt!("%?", val)); But second one provides errors: let (port, chan) = flatpipes::serial::pipe_stream(); do task::spawn { let val = port.recv(); io::println(fmt!("Value: %?", val)); } let value = @[1, 2, 3, 4, 5]; chan.send(value); tmp.rs:19:18: 19:22 error: value has non-owned type `extra::flatpipes::FlatPort<@[int],extra::flatpipes::flatteners::DeserializingUnflattener,extra::flatpipes::bytepipes::PipeBytePort>` tmp.rs:19 let val = port.recv(); ^~~~ From my point of view, both fragments are equivalent, so, is it compiler error or my misunderstanding? Kind regards, Alexander -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Sun Jul 7 12:45:54 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Sun, 07 Jul 2013 12:45:54 -0700 Subject: [rust-dev] Borrow lifetime assignment changed? In-Reply-To: References: <51D83730.8040200@crsr.net> Message-ID: <51D9C572.7080802@mozilla.com> On 13-07-07 03:48 AM, Matthieu Monrocq wrote: > There is a specific rule in the C++ specification to address > temporaries: they should live up until the end of the full expression > they are part of. Yeah. We need to nail this down, it's been open for a while, is on milestone #1: https://github.com/mozilla/rust/issues/3511 -Graydon From mcguire at crsr.net Sun Jul 7 13:33:09 2013 From: mcguire at crsr.net (Tommy M. McGuire) Date: Sun, 07 Jul 2013 15:33:09 -0500 Subject: [rust-dev] Borrow lifetime assignment changed? In-Reply-To: <51D9C572.7080802@mozilla.com> References: <51D83730.8040200@crsr.net> <51D9C572.7080802@mozilla.com> Message-ID: <51D9D085.9020407@crsr.net> On 07/07/2013 02:45 PM, Graydon Hoare wrote: > There is a specific rule in the C++ specification to address > temporaries: they should live up until the end of the full expression > they are part of. If it is difficult to get that working right, would it be easier if they lived to the end of the block? That is the effect of naming them, right? (I always thought C++'s rule was more of a stunt or joke than a useful rule---it's apparently harder to get right than I thought it was, it's hard to explain to people, and it does nothing useful for me, programming-wise.) -- Tommy M. McGuire mcguire at crsr.net From james at mansionfamily.plus.com Sun Jul 7 14:01:18 2013 From: james at mansionfamily.plus.com (james) Date: Sun, 07 Jul 2013 22:01:18 +0100 Subject: [rust-dev] Segmented stacks In-Reply-To: References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> <51D5F81F.5020204@mozilla.com> <51D65F8A.4040707@mansionfamily.plus.com> <51D677BD.5090307@mozilla.com> <51D73DF3.7030106@mansionfamily.plus.com> Message-ID: <51D9D71E.6050202@mansionfamily.plus.com> On 05/07/2013 23:05, Daniel Micay wrote: > On Fri, Jul 5, 2013 at 5:43 PM, james wrote: >> >On 05/07/2013 08:37, Graydon Hoare wrote: >>> >> >>> >>I agree that it's higher than it seems it "needs to be". But it will >>> >>always be unnecessary overhead on x64; it really makes no sense there. The >>> >>address space is enormous and it's all lazily committed. >> > >> > >> >I don't think you can rely on 'lazily committed'. Not on a system that is >> >properly engineered anyway. > You can rely on it, it's the standard behaviour on Linux. The actual > consumed memory will be equal to the size of the pages that have been > touched. And that was entirely my point. As a Solaris programmer I thought the lazy assignment and overcommit was a stupid idea on AIX and its still a stupid idea on Linux. There is no good reason for an operating system to fail a process for accessing memory that it has been told it can have, nor for a process to be terminated because some other process uses memory. Its not well-engineered, quite the opposite. And its particularly pointless given that space is so cheap. Its not as if you have to actually wire up backing store, or even wire up page tables - but you do have to make sure that enough resources are available to make sure that you can do so later on demand and won't run out. Preferably using swap that doesn't deadlock when you try to use it. I don't think Linux is well engineered, and I don't think the development process (if that word actually applies) will ever fix its deficiencies. Even if it is standard on Linux, its a really poor idea to assume thet the whole world does now and will continue to use Linux as the only base for doing useful computing. -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Sun Jul 7 14:17:34 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Sun, 7 Jul 2013 17:17:34 -0400 Subject: [rust-dev] Segmented stacks In-Reply-To: <51D9D71E.6050202@mansionfamily.plus.com> References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> <51D5F81F.5020204@mozilla.com> <51D65F8A.4040707@mansionfamily.plus.com> <51D677BD.5090307@mozilla.com> <51D73DF3.7030106@mansionfamily.plus.com> <51D9D71E.6050202@mansionfamily.plus.com> Message-ID: On Sun, Jul 7, 2013 at 5:01 PM, james wrote: > On 05/07/2013 23:05, Daniel Micay wrote: > > On Fri, Jul 5, 2013 at 5:43 PM, james wrote: > >> On 05/07/2013 08:37, Graydon Hoare wrote: > >>> >>> I agree that it's higher than it seems it "needs to be". But it will >>> always be unnecessary overhead on x64; it really makes no sense there. >>> The >>> address space is enormous and it's all lazily committed. > >> >> >> I don't think you can rely on 'lazily committed'. Not on a system that is >> properly engineered anyway. > > You can rely on it, it's the standard behaviour on Linux. The actual > consumed memory will be equal to the size of the pages that have been > touched. > > And that was entirely my point. As a Solaris programmer I thought the lazy > assignment and overcommit was a stupid idea on AIX and its still a stupid > idea on Linux. There is no good reason for an operating system to fail a > process for accessing memory that it has been told it can have, nor for a > process to be terminated because some other process uses memory. Its not > well-engineered, quite the opposite. And its particularly pointless given > that space is so cheap. Its not as if you have to actually wire up backing > store, or even wire up page tables - but you do have to make sure that > enough resources are available to make sure that you can do so later on > demand and won't run out. Preferably using swap that doesn't deadlock when > you try to use it. I don't think Linux is well engineered, and I don't > think the development process (if that word actually applies) will ever fix > its deficiencies. Even if it is standard on Linux, its a really poor idea > to assume thet the whole world does now and will continue to use Linux as > the only base for doing useful computing. > > I'm fine with taking a 20-500% performance hit on what you regard as well-engineered operating systems. We shouldn't be taking an unnecessary performance hit on the poorly engineered ones where processes can actually use large stacks and data structures like hash tables and vectors depending on exponential reallocation without wasting memory. From coder543 at gmail.com Sun Jul 7 14:21:22 2013 From: coder543 at gmail.com (Josh Leverette) Date: Sun, 7 Jul 2013 16:21:22 -0500 Subject: [rust-dev] Segmented stacks In-Reply-To: <51D9D71E.6050202@mansionfamily.plus.com> References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> <51D5F81F.5020204@mozilla.com> <51D65F8A.4040707@mansionfamily.plus.com> <51D677BD.5090307@mozilla.com> <51D73DF3.7030106@mansionfamily.plus.com> <51D9D71E.6050202@mansionfamily.plus.com> Message-ID: You think Linux is not well-engineered? That statement just took the wind out of your sails. There are components that run *on top of *Linux (and similar Unix-like systems) that are poorly engineered, X.org chief among them, but that doesn't make the Linux kernel poorly engineered. Making intangible claims about Linux being both poorly designed and transient is a quick way to make your opinions fall into disregard. This is not the place for such a discussion, and I've never seen any substantive evidence to back up that train of thought. In fact, I don't think anyone has seen substantive evidence to back up that train of thought. Lazily committed RAM is useful, and the logic behind "resource X is plentiful, therefore use it liberally" is the same logic that resulted in something we now know as Windows Vista. Hey, RAM is getting so big these days, why not use more of it! There are edge cases that can cause problems with Lazy Commit, but you really believe there aren't worse problems with a non-Lazy Commit system? The grass isn't greener on the other side, unless you live in an edge case... and that's a strange place to live. On Sun, Jul 7, 2013 at 4:01 PM, james wrote: > On 05/07/2013 23:05, Daniel Micay wrote: > > On Fri, Jul 5, 2013 at 5:43 PM, james wrote: > > > On 05/07/2013 08:37, Graydon Hoare wrote: > > >>>> I agree that it's higher than it seems it "needs to be". But it will>> always be unnecessary overhead on x64; it really makes no sense there. The>> address space is enormous and it's all lazily committed. > > >>> I don't think you can rely on 'lazily committed'. Not on a system that is> properly engineered anyway. > > You can rely on it, it's the standard behaviour on Linux. The actual > consumed memory will be equal to the size of the pages that have been > touched. > > And that was entirely my point. As a Solaris programmer I thought the > lazy assignment and overcommit was a stupid idea on AIX and its still a > stupid idea on Linux. There is no good reason for an operating system to > fail a process for accessing memory that it has been told it can have, nor > for a process to be terminated because some other process uses memory. Its > not well-engineered, quite the opposite. And its particularly pointless > given that space is so cheap. Its not as if you have to actually wire up > backing store, or even wire up page tables - but you do have to make sure > that enough resources are available to make sure that you can do so later > on demand and won't run out. Preferably using swap that doesn't deadlock > when you try to use it. I don't think Linux is well engineered, and I > don't think the development process (if that word actually applies) will > ever fix its deficiencies. Even if it is standard on Linux, its a really > poor idea to assume thet the whole world does now and will continue to use > Linux as the only base for doing useful computing. > > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -- Sincerely, Josh -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Sun Jul 7 14:32:28 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Sun, 07 Jul 2013 14:32:28 -0700 Subject: [rust-dev] Segmented stacks In-Reply-To: References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> <51D5F81F.5020204@mozilla.com> <51D65F8A.4040707@mansionfamily.plus.com> <51D677BD.5090307@mozilla.com> <51D73DF3.7030106@mansionfamily.plus.com> <51D9D71E.6050202@mansionfamily.plus.com> Message-ID: <51D9DE6C.1080905@mozilla.com> I should have asked earlier, but better late than never: this conversation's gone off the rails and well into the "non-courteous, non-productive" territory we ask people to keep off our lists. See "Conduct" here: https://github.com/mozilla/rust/wiki/Note-development-policy We're going to support multiple variants of stack segmentation, much like supporting multiple variants of coroutine:thread mapping, depending on platform, deployment scenario, and user preference. We don't need to descend into a fight over which platform is best engineered. Different people have different needs. -Graydon From bklooste at gmail.com Sun Jul 7 20:06:21 2013 From: bklooste at gmail.com (Bennie Kloosteman) Date: Mon, 8 Jul 2013 11:06:21 +0800 Subject: [rust-dev] Segmented stacks In-Reply-To: References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> <51D5F81F.5020204@mozilla.com> <51D65F8A.4040707@mansionfamily.plus.com> <51D677BD.5090307@mozilla.com> <51D73DF3.7030106@mansionfamily.plus.com> <51D9D71E.6050202@mansionfamily.plus.com> Message-ID: "You think Linux is not well-engineered?" Nope .. its the same piece of 1970s crap that all the other popular OS use , with trivial differences people make a bit deal about.. You really think the difference between Vista and Linux is the kernel when you complain about X.org ? XP ,Vista , Windows8 all basically have the same kernel some OS's people loved others they hated but the difference is never the kernel. Load up a copy of minwin and you can see. That said it doesnt matter , the fact Runtimes like rust create tasks or services like nginx manage there own threads and memory ( and even OS do this with file systems) , basically means the kernel just becomes a big device driver and the apps do what they like but the kernel really should have been doing those things long ago. Instead it was optomized for almost batch processing applications designed in the 70 where latency was more important than throughput . Lazily committed RAM is very useful for batch processing. That said i fired up uclinux for a project a few years ago ( with no VM kernel support on 86_64 so no copy on write for fork ) so no lazy allocation either and ran some heavy load web service like tests and it was so much faster despite uclinux having many older algoritms / techniques.. Ben On Mon, Jul 8, 2013 at 5:21 AM, Josh Leverette wrote: > You think Linux is not well-engineered? That statement just took the wind > out of your sails. There are components that run *on top of *Linux (and > similar Unix-like systems) that are poorly engineered, X.org chief among > them, but that doesn't make the Linux kernel poorly engineered. Making > intangible claims about Linux being both poorly designed and transient is a > quick way to make your opinions fall into disregard. This is not the place > for such a discussion, and I've never seen any substantive evidence to back > up that train of thought. In fact, I don't think anyone has seen > substantive evidence to back up that train of thought. > > Lazily committed RAM is useful, and the logic behind "resource X is > plentiful, therefore use it liberally" is the same logic that resulted in > something we now know as Windows Vista. Hey, RAM is getting so big these > days, why not use more of it! > > There are edge cases that can cause problems with Lazy Commit, but you > really believe there aren't worse problems with a non-Lazy Commit system? > The grass isn't greener on the other side, unless you live in an edge > case... and that's a strange place to live. > > > On Sun, Jul 7, 2013 at 4:01 PM, james wrote: > >> On 05/07/2013 23:05, Daniel Micay wrote: >> >> On Fri, Jul 5, 2013 at 5:43 PM, james wrote: >> >> > On 05/07/2013 08:37, Graydon Hoare wrote: >> >> >>>> I agree that it's higher than it seems it "needs to be". But it will>> always be unnecessary overhead on x64; it really makes no sense there. The>> address space is enormous and it's all lazily committed. >> >> >>> I don't think you can rely on 'lazily committed'. Not on a system that is> properly engineered anyway. >> >> You can rely on it, it's the standard behaviour on Linux. The actual >> consumed memory will be equal to the size of the pages that have been >> touched. >> >> And that was entirely my point. As a Solaris programmer I thought the >> lazy assignment and overcommit was a stupid idea on AIX and its still a >> stupid idea on Linux. There is no good reason for an operating system to >> fail a process for accessing memory that it has been told it can have, nor >> for a process to be terminated because some other process uses memory. Its >> not well-engineered, quite the opposite. And its particularly pointless >> given that space is so cheap. Its not as if you have to actually wire up >> backing store, or even wire up page tables - but you do have to make sure >> that enough resources are available to make sure that you can do so later >> on demand and won't run out. Preferably using swap that doesn't deadlock >> when you try to use it. I don't think Linux is well engineered, and I >> don't think the development process (if that word actually applies) will >> ever fix its deficiencies. Even if it is standard on Linux, its a really >> poor idea to assume thet the whole world does now and will continue to use >> Linux as the only base for doing useful computing. >> >> >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> > > > -- > Sincerely, > Josh > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From zack at z0w0.me Sun Jul 7 20:41:49 2013 From: zack at z0w0.me (Zack Corr) Date: Mon, 8 Jul 2013 13:41:49 +1000 Subject: [rust-dev] Segmented stacks In-Reply-To: References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> <51D5F81F.5020204@mozilla.com> <51D65F8A.4040707@mansionfamily.plus.com> <51D677BD.5090307@mozilla.com> <51D73DF3.7030106@mansionfamily.plus.com> <51D9D71E.6050202@mansionfamily.plus.com> Message-ID: I wasn't aware that Linus Torvalds possessed time travel technology. Either way, to say that Linux, OSX and the Windows kernel are the same but with miniscule differences is a pretty broad statement. On 8 Jul 2013 13:06, "Bennie Kloosteman" wrote: > "You think Linux is not well-engineered?" > > Nope .. its the same piece of 1970s crap that all the other popular OS use > , with trivial differences people make a bit deal about.. You really think > the difference between Vista and Linux is the kernel when you complain > about X.org ? XP ,Vista , Windows8 all basically have the same kernel > some OS's people loved others they hated but the difference is never the > kernel. Load up a copy of minwin and you can see. > > That said it doesnt matter , the fact Runtimes like rust create tasks or > services like nginx manage there own threads and memory ( and even OS do > this with file systems) , basically means the kernel just becomes a big > device driver and the apps do what they like but the kernel really should > have been doing those things long ago. Instead it was optomized for > almost batch processing applications designed in the 70 where latency was > more important than throughput . Lazily committed RAM is very useful for > batch processing. > > That said i fired up uclinux for a project a few years ago ( with no VM > kernel support on 86_64 so no copy on write for fork ) so no lazy > allocation either and ran some heavy load web service like tests and it > was so much faster despite uclinux having many older algoritms / > techniques.. > > Ben > > > On Mon, Jul 8, 2013 at 5:21 AM, Josh Leverette wrote: > >> You think Linux is not well-engineered? That statement just took the wind >> out of your sails. There are components that run *on top of *Linux (and >> similar Unix-like systems) that are poorly engineered, X.org chief among >> them, but that doesn't make the Linux kernel poorly engineered. Making >> intangible claims about Linux being both poorly designed and transient is a >> quick way to make your opinions fall into disregard. This is not the place >> for such a discussion, and I've never seen any substantive evidence to back >> up that train of thought. In fact, I don't think anyone has seen >> substantive evidence to back up that train of thought. >> >> Lazily committed RAM is useful, and the logic behind "resource X is >> plentiful, therefore use it liberally" is the same logic that resulted in >> something we now know as Windows Vista. Hey, RAM is getting so big these >> days, why not use more of it! >> >> There are edge cases that can cause problems with Lazy Commit, but you >> really believe there aren't worse problems with a non-Lazy Commit system? >> The grass isn't greener on the other side, unless you live in an edge >> case... and that's a strange place to live. >> >> >> On Sun, Jul 7, 2013 at 4:01 PM, james wrote: >> >>> On 05/07/2013 23:05, Daniel Micay wrote: >>> >>> On Fri, Jul 5, 2013 at 5:43 PM, james wrote: >>> >>> > On 05/07/2013 08:37, Graydon Hoare wrote: >>> >>> >>>> I agree that it's higher than it seems it "needs to be". But it will>> always be unnecessary overhead on x64; it really makes no sense there. The>> address space is enormous and it's all lazily committed. >>> >>> >>> I don't think you can rely on 'lazily committed'. Not on a system that is> properly engineered anyway. >>> >>> You can rely on it, it's the standard behaviour on Linux. The actual >>> consumed memory will be equal to the size of the pages that have been >>> touched. >>> >>> And that was entirely my point. As a Solaris programmer I thought the >>> lazy assignment and overcommit was a stupid idea on AIX and its still a >>> stupid idea on Linux. There is no good reason for an operating system to >>> fail a process for accessing memory that it has been told it can have, nor >>> for a process to be terminated because some other process uses memory. Its >>> not well-engineered, quite the opposite. And its particularly pointless >>> given that space is so cheap. Its not as if you have to actually wire up >>> backing store, or even wire up page tables - but you do have to make sure >>> that enough resources are available to make sure that you can do so later >>> on demand and won't run out. Preferably using swap that doesn't deadlock >>> when you try to use it. I don't think Linux is well engineered, and I >>> don't think the development process (if that word actually applies) will >>> ever fix its deficiencies. Even if it is standard on Linux, its a really >>> poor idea to assume thet the whole world does now and will continue to use >>> Linux as the only base for doing useful computing. >>> >>> >>> >>> _______________________________________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/listinfo/rust-dev >>> >>> >> >> >> -- >> Sincerely, >> Josh >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Sun Jul 7 20:53:23 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Sun, 7 Jul 2013 23:53:23 -0400 Subject: [rust-dev] Segmented stacks In-Reply-To: References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> <51D5F81F.5020204@mozilla.com> <51D65F8A.4040707@mansionfamily.plus.com> <51D677BD.5090307@mozilla.com> <51D73DF3.7030106@mansionfamily.plus.com> <51D9D71E.6050202@mansionfamily.plus.com> Message-ID: On Sun, Jul 7, 2013 at 11:06 PM, Bennie Kloosteman wrote: > "You think Linux is not well-engineered?" > > Nope .. its the same piece of 1970s crap that all the other popular OS use , > with trivial differences people make a bit deal about.. You really think the > difference between Vista and Linux is the kernel when you complain about > X.org ? XP ,Vista , Windows8 all basically have the same kernel some OS's > people loved others they hated but the difference is never the kernel. > Load up a copy of minwin and you can see. Linux only emulates a traditional Unix system on the surface. There are no equivalents to features like control groups, namespaces and many other features on traditional Unix. The implementations of asynchronous I/O between operating systems are very different paradigms too (epoll/kqueue-style vs. IOCP). The epoll event loop isn't just for I/O either, since in addition to files, sockets and pipes it also handles filesystem events (inotify), signals (signalfd), timers (timerfd) and arbitrary userland notifications (eventfd). Another example of functionality moving into kernel-space is the udev/evdev/drm stack. Wayland and Mir are full replacements for X.org, but they're only a thin IPC layer on top of the kernel. > That said it doesnt matter , the fact Runtimes like rust create tasks or > services like nginx manage there own threads and memory ( and even OS do > this with file systems) , basically means the kernel just becomes a big > device driver and the apps do what they like but the kernel really should > have been doing those things long ago. Instead it was optomized for almost > batch processing applications designed in the 70 where latency was more > important than throughput . Lazily committed RAM is very useful for batch > processing. Rust uses the kernel's implementation of threads and memory management as other applications do. The userspace threads are an abstraction of the underlying event loop (layered on top of the kernel's own event handling), not a replacement for real threads with pre-emption. The scheduler only implements cooperative scheduling itself, and relies on the operating system to provide "real" pre-emptive threads. > That said i fired up uclinux for a project a few years ago ( with no VM > kernel support on 86_64 so no copy on write for fork ) so no lazy > allocation either and ran some heavy load web service like tests and it was > so much faster despite uclinux having many older algoritms / techniques.. > > Ben Virtual memory is a significant expense, but it's an expense paid to make a robust multi-tasking operating system. Lazy allocation is a convenient optimization to make when you're already paying the price needed to implement it. From coder543 at gmail.com Sun Jul 7 21:13:33 2013 From: coder543 at gmail.com (Josh Leverette) Date: Sun, 7 Jul 2013 23:13:33 -0500 Subject: [rust-dev] Segmented stacks In-Reply-To: References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> <51D5F81F.5020204@mozilla.com> <51D65F8A.4040707@mansionfamily.plus.com> <51D677BD.5090307@mozilla.com> <51D73DF3.7030106@mansionfamily.plus.com> <51D9D71E.6050202@mansionfamily.plus.com> Message-ID: >From what I gather, you only really use Windows... yet you're trying to argue about Unix-like systems. They are not even similar to Windows at all, so your attempt to argue that in fact they're all the same is amusing... and saddening. I didn't switch away from Windows because I grew a neckbeard or anything. It was for practical reasons that applied to me, and because the other options had massive advantages (for me, personally) over Windows. If they were so similar, I would have gained nothing from switching. You're probably happiest with what Windows offers, and that's perfectly fine, but the differences between Windows and Linux/BSD/Solaris/OSX are far from superficial. More on topic though, all of this stuff is being handled (naturally) on a platform by platform basis as Graydon pointed out. Therefore, this whole thread seems moot. I think very little remains to be said on the subject of this thread. On Jul 7, 2013 10:06 PM, "Bennie Kloosteman" wrote: > "You think Linux is not well-engineered?" > > Nope .. its the same piece of 1970s crap that all the other popular OS use > , with trivial differences people make a bit deal about.. You really think > the difference between Vista and Linux is the kernel when you complain > about X.org ? XP ,Vista , Windows8 all basically have the same kernel > some OS's people loved others they hated but the difference is never the > kernel. Load up a copy of minwin and you can see. > > That said it doesnt matter , the fact Runtimes like rust create tasks or > services like nginx manage there own threads and memory ( and even OS do > this with file systems) , basically means the kernel just becomes a big > device driver and the apps do what they like but the kernel really should > have been doing those things long ago. Instead it was optomized for > almost batch processing applications designed in the 70 where latency was > more important than throughput . Lazily committed RAM is very useful for > batch processing. > > That said i fired up uclinux for a project a few years ago ( with no VM > kernel support on 86_64 so no copy on write for fork ) so no lazy > allocation either and ran some heavy load web service like tests and it > was so much faster despite uclinux having many older algoritms / > techniques.. > > Ben > > > On Mon, Jul 8, 2013 at 5:21 AM, Josh Leverette wrote: > >> You think Linux is not well-engineered? That statement just took the wind >> out of your sails. There are components that run *on top of *Linux (and >> similar Unix-like systems) that are poorly engineered, X.org chief among >> them, but that doesn't make the Linux kernel poorly engineered. Making >> intangible claims about Linux being both poorly designed and transient is a >> quick way to make your opinions fall into disregard. This is not the place >> for such a discussion, and I've never seen any substantive evidence to back >> up that train of thought. In fact, I don't think anyone has seen >> substantive evidence to back up that train of thought. >> >> Lazily committed RAM is useful, and the logic behind "resource X is >> plentiful, therefore use it liberally" is the same logic that resulted in >> something we now know as Windows Vista. Hey, RAM is getting so big these >> days, why not use more of it! >> >> There are edge cases that can cause problems with Lazy Commit, but you >> really believe there aren't worse problems with a non-Lazy Commit system? >> The grass isn't greener on the other side, unless you live in an edge >> case... and that's a strange place to live. >> >> >> On Sun, Jul 7, 2013 at 4:01 PM, james wrote: >> >>> On 05/07/2013 23:05, Daniel Micay wrote: >>> >>> On Fri, Jul 5, 2013 at 5:43 PM, james wrote: >>> >>> > On 05/07/2013 08:37, Graydon Hoare wrote: >>> >>> >>>> I agree that it's higher than it seems it "needs to be". But it will>> always be unnecessary overhead on x64; it really makes no sense there. The>> address space is enormous and it's all lazily committed. >>> >>> >>> I don't think you can rely on 'lazily committed'. Not on a system that is> properly engineered anyway. >>> >>> You can rely on it, it's the standard behaviour on Linux. The actual >>> consumed memory will be equal to the size of the pages that have been >>> touched. >>> >>> And that was entirely my point. As a Solaris programmer I thought the >>> lazy assignment and overcommit was a stupid idea on AIX and its still a >>> stupid idea on Linux. There is no good reason for an operating system to >>> fail a process for accessing memory that it has been told it can have, nor >>> for a process to be terminated because some other process uses memory. Its >>> not well-engineered, quite the opposite. And its particularly pointless >>> given that space is so cheap. Its not as if you have to actually wire up >>> backing store, or even wire up page tables - but you do have to make sure >>> that enough resources are available to make sure that you can do so later >>> on demand and won't run out. Preferably using swap that doesn't deadlock >>> when you try to use it. I don't think Linux is well engineered, and I >>> don't think the development process (if that word actually applies) will >>> ever fix its deficiencies. Even if it is standard on Linux, its a really >>> poor idea to assume thet the whole world does now and will continue to use >>> Linux as the only base for doing useful computing. >>> >>> >>> >>> _______________________________________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/listinfo/rust-dev >>> >>> >> >> >> -- >> Sincerely, >> Josh >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From coder543 at gmail.com Sun Jul 7 21:49:38 2013 From: coder543 at gmail.com (Josh Leverette) Date: Sun, 7 Jul 2013 23:49:38 -0500 Subject: [rust-dev] flatpipes question In-Reply-To: References: Message-ID: I'm having difficulty compiling even the first sample. Nothing I do can convince my rust 0.7 compiler of the existence of flatpipes... but I'm new to this whole thing anyways. The one thing that jumps out at me: should the second example have "||" after the word 'spawn' in the do statement? i.e. do task::spawn || { instead of do task::spawn { My understanding is that the empty vertical bars indicate an empty argument name list, so it should have no negative effect on the code, but it's worth testing, I suppose. What "use" or "extern mod" statements did you place at the top of the Rust files in order to get them to compile? I may not know much, but I'd like to learn, and I'd like to help when I can. According to the tutorial, both chan and port should be sendable types that can be transferred to the task's closure. I'm interested in what's going on here as well. On Sun, Jul 7, 2013 at 1:49 PM, Alexander Stavonin wrote: > There are two fragments of codes first one can be compiled without any > errors: > > let (port, chan) = flatpipes::serial::pipe_stream(); > do task::spawn || { > let value = @[1, 2, 3, 4, 5]; > chan.send(value) > } > let val = port.recv(); > io::println(fmt!("%?", val)); > > But second one provides errors: > > let (port, chan) = flatpipes::serial::pipe_stream(); > do task::spawn { > let val = port.recv(); > io::println(fmt!("Value: %?", val)); > } > let value = @[1, 2, 3, 4, 5]; > chan.send(value); > > tmp.rs:19:18: 19:22 error: value has non-owned type > `extra::flatpipes::FlatPort<@[int],extra::flatpipes::flatteners::DeserializingUnflattener,extra::flatpipes::bytepipes::PipeBytePort>` > tmp.rs:19 let val = port.recv(); > ^~~~ > > From my point of view, both fragments are equivalent, so, is it compiler > error or my misunderstanding? > > Kind regards, > Alexander > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -- Sincerely, Josh -------------- next part -------------- An HTML attachment was scrubbed... URL: From me at kevincantu.org Sun Jul 7 21:56:02 2013 From: me at kevincantu.org (Kevin Cantu) Date: Sun, 7 Jul 2013 21:56:02 -0700 Subject: [rust-dev] Chicago: Lambda Jam this week Message-ID: If anyone other Rust folks are also going to be at Lambda Jam Chicago this week, we should get a beer or something and hang out! I've just gotten into town. :) Kevin -------------- next part -------------- An HTML attachment was scrubbed... URL: From lindsey at composition.al Sun Jul 7 22:17:47 2013 From: lindsey at composition.al (Lindsey Kuper) Date: Mon, 8 Jul 2013 01:17:47 -0400 Subject: [rust-dev] Segmented stacks In-Reply-To: References: <51D59CB3.20400@gmail.com> <20130704170204.GA6224@atjola.homenet> <51D5F81F.5020204@mozilla.com> <51D65F8A.4040707@mansionfamily.plus.com> <51D677BD.5090307@mozilla.com> <51D73DF3.7030106@mansionfamily.plus.com> <51D9D71E.6050202@mansionfamily.plus.com> Message-ID: On Sun, Jul 7, 2013 at 11:06 PM, Bennie Kloosteman wrote: > "You think Linux is not well-engineered?" > > Nope .. its the same piece of 1970s crap that all the other popular OS use , > with trivial differences people make a bit deal about.. You really think the > difference between Vista and Linux is the kernel when you complain about > X.org ? On Mon, Jul 8, 2013 at 12:13 AM, Josh Leverette wrote: > From what I gather, you only really use Windows... yet you're trying to > argue about Unix-like systems. They are not even similar to Windows at all, > so your attempt to argue that in fact they're all the same is amusing... and > saddening. I didn't switch away from Windows because I grew a neckbeard or > anything. There are plenty of places where you can carry on in this vein, but this list is not one of them. As Graydon already pointed out, see https://github.com/mozilla/rust/wiki/Note-development-policy#conduct . If anyone is still interested in discussing segmented stacks with regard to Rust --- if indeed there is anything more to say --- perhaps it would be best to start a new thread. Lindsey From a.stavonin at gmail.com Sun Jul 7 23:43:51 2013 From: a.stavonin at gmail.com (Alexander Stavonin) Date: Mon, 8 Jul 2013 10:43:51 +0400 Subject: [rust-dev] flatpipes question In-Reply-To: References: Message-ID: Full source code: extern mod std; extern mod extra; use std::{task, io}; use extra::flatpipes; fn main() { let (port, chan) = flatpipes::serial::pipe_stream(); do task::spawn || { let value = @[1, 2, 3, 4, 5]; chan.send(value) } let val = port.recv(); io::println(fmt!("%?", val)); /*let (port, chan) = flatpipes::serial::pipe_stream();*/ /*do task::spawn || {*/ /*let val = port.recv();*/ /*io::println(fmt!("Value: %?", val));*/ /*}*/ /*let value = @[1, 2, 3, 4, 5];*/ /*chan.send(value);*/ } And compiler output: astavonin:/Users/../rust: rustc -v rustc 0.7 host: x86_64-apple-darwin astavonin:/Users/../rust: rustc test.rs warning: no debug symbols in executable (-arch x86_64) But, If you uncomment second block, you'll have next error: test.rs:19:18: 19:22 error: cannot capture variable of type `extra::flatpipes::FlatPort<@[int],extra::flatpipes::flatteners::DeserializingUnflattener,extra::flatpipes::bytepipes::PipeBytePort>`, which does not fulfill `Send`, in a bounded closure test.rs:19 let val = port.recv(); ^~~~ test.rs:19:18: 19:22 note: this closure's environment must satisfy `Send` test.rs:19 let val = port.recv(); ^~~~ error: aborting due to previous error Best regards, Alexander. 2013/7/8 Josh Leverette > I'm having difficulty compiling even the first sample. Nothing I do can > convince my rust 0.7 compiler of the existence of flatpipes... but I'm new > to this whole thing anyways. > > The one thing that jumps out at me: should the second example have "||" > after the word 'spawn' in the do statement? i.e. do task::spawn || { > instead of do task::spawn { > > My understanding is that the empty vertical bars indicate an empty > argument name list, so it should have no negative effect on the code, but > it's worth testing, I suppose. What "use" or "extern mod" statements did > you place at the top of the Rust files in order to get them to compile? I > may not know much, but I'd like to learn, and I'd like to help when I can. > > According to the tutorial, both chan and port should be sendable types > that can be transferred to the task's closure. > > I'm interested in what's going on here as well. > > > On Sun, Jul 7, 2013 at 1:49 PM, Alexander Stavonin wrote: > >> There are two fragments of codes first one can be compiled without any >> errors: >> >> let (port, chan) = flatpipes::serial::pipe_stream(); >> do task::spawn || { >> let value = @[1, 2, 3, 4, 5]; >> chan.send(value) >> } >> let val = port.recv(); >> io::println(fmt!("%?", val)); >> >> But second one provides errors: >> >> let (port, chan) = flatpipes::serial::pipe_stream(); >> do task::spawn { >> let val = port.recv(); >> io::println(fmt!("Value: %?", val)); >> } >> let value = @[1, 2, 3, 4, 5]; >> chan.send(value); >> >> tmp.rs:19:18: 19:22 error: value has non-owned type >> `extra::flatpipes::FlatPort<@[int],extra::flatpipes::flatteners::DeserializingUnflattener,extra::flatpipes::bytepipes::PipeBytePort>` >> tmp.rs:19 let val = port.recv(); >> ^~~~ >> >> From my point of view, both fragments are equivalent, so, is it >> compiler error or my misunderstanding? >> >> Kind regards, >> Alexander >> >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> > > > -- > Sincerely, > Josh > -------------- next part -------------- An HTML attachment was scrubbed... URL: From fredrik at haard.se Mon Jul 8 00:44:44 2013 From: fredrik at haard.se (=?UTF-8?B?RnJlZHJpayBIw6XDpXJk?=) Date: Mon, 8 Jul 2013 09:44:44 +0200 Subject: [rust-dev] Proposal for string encodings In-Reply-To: References: Message-ID: I've written a charmap/reverse mapping generator using unicode.org specs for standard encodings, and was intending to follow up with creating convenient interfaces before other things got in the way. I'll clean it up and make it compile with current version and put it on github. What I do is I parse the specifications and generate one .rs with the charmap for each encoding, and then add a trait Encodeable/Decodeable for ~str/~[u8] respectively, using those charmaps by name. 2013/7/6 Kevin Ballard : > I've been thinking about string encoding support lately, and the > approach I've decided to experiment with is representing a string > encoding as a pair of external Iterators. The encoder is an > Iterator that consumes an Iterator, and the decoder is an > Iterator that consumes an Iterator. A pair of conditions is > used to control error handling, with the default behavior to use > U+FFFD REPLACEMENT CHAR. > > Today I implemented this as a new module std::encoding, with a > proof-of-concept UTF-16 implementation. This is available on my fork > at https://github.com/kballard/rust/tree/encodings (current compiling > commit is https://github.com/kballard/rust/commit/54b5b50f0afd8d5dc329d01109c6b760754d56de; > I won't guarantee that the branch will always compile). > > Usage is slightly awkward at the moment due to the usage of > Iterator instead of Iterator<&u8> (and same for char). To convert > a UTF-16 &[u8] into a ~[char] you can say > > let res : ~[u8] = encoding::utf16.decode(src.iter().transform(|&x| > x)).collect(); > > I had hoped to provide a convenience method .decodeBytes() so you > could say `encoding::utf16.decodeBytes(src)` but the type system has > defeated my attempts to do this so far. I'm inclined to add an > .iter_clone() method to vectors, which would turn this into the > slightly simpler `encoding::utf16.decode(src.iter_clone()).collect()`. > > If anyone wants to look over what I have so far, I'd love to get your > feedback/suggestions/complaints. > > -Kevin > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -- /f I reject your reality and substitute my own. http://courteous.ly/yp3Zgd From corey at octayn.net Mon Jul 8 04:14:59 2013 From: corey at octayn.net (Corey Richardson) Date: Mon, 8 Jul 2013 07:14:59 -0400 Subject: [rust-dev] Representation of Types Message-ID: Hello, I'm working on resolving a type for rustdoc-ng, but I'm confused by how it works in the compiler. It seems the important data structures here are ast::Ty and ast::ty_, but I don't quite understand exactly what each of them are, especially as they form a recursive data structure. I also don't know what the variants of ty_ are. It seems ty_path is for structs/enums, and the rest is either pointers to, vectors of, tuples containing, or closures using a ty_path, but I'm not sure about this. Given a rustc::middle::resolve::CrateMap, a syntax::ast_map::map, and a syntax::ast::Ty, how can I determine what "real" type the given ast::Ty refers to? From pwalton at mozilla.com Mon Jul 8 04:19:39 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Mon, 08 Jul 2013 04:19:39 -0700 Subject: [rust-dev] Representation of Types In-Reply-To: References: Message-ID: <51DAA04B.5090503@mozilla.com> On 7/8/13 4:14 AM, Corey Richardson wrote: > Given a rustc::middle::resolve::CrateMap, a syntax::ast_map::map, and > a syntax::ast::Ty, how can I determine what "real" type the given > ast::Ty refers to? Typechecking uses the functions in `astconv.rs` (particularly `ast_ty_to_ty`) to transform an AST type into a type used for typechecking. I believe it writes the results into the type context, so you can retrieve it with `node_id_to_type` or similar. For rustdoc purposes you may not need the same notion of a type as typechecking uses. In that case you can just look up the def ID that resolve resolved each `ty_path` to; it should always resolve to a struct, enum, or typedef. Be warned, resolve will not strip out typedefs; that's the job of `astconv`. Patrick From corey at octayn.net Mon Jul 8 05:31:21 2013 From: corey at octayn.net (Corey Richardson) Date: Mon, 8 Jul 2013 08:31:21 -0400 Subject: [rust-dev] The module system desparately needs documentation Message-ID: It's quite powerful and fairly easy to use once you understand it, but understanding it is not simple because there is no documentation besides #rust and some code examples, afaik. Lots of newcomers are struggling with it once they get past the one-or-two file complexity level. From corey at octayn.net Mon Jul 8 06:04:17 2013 From: corey at octayn.net (Corey Richardson) Date: Mon, 8 Jul 2013 09:04:17 -0400 Subject: [rust-dev] Representation of Types In-Reply-To: <51DAA04B.5090503@mozilla.com> References: <51DAA04B.5090503@mozilla.com> Message-ID: On Mon, Jul 8, 2013 at 7:19 AM, Patrick Walton wrote: > On 7/8/13 4:14 AM, Corey Richardson wrote: >> >> Given a rustc::middle::resolve::CrateMap, a syntax::ast_map::map, and >> a syntax::ast::Ty, how can I determine what "real" type the given >> ast::Ty refers to? > > > Typechecking uses the functions in `astconv.rs` (particularly > `ast_ty_to_ty`) to transform an AST type into a type used for typechecking. > I believe it writes the results into the type context, so you can retrieve > it with `node_id_to_type` or similar. > I gather from the comments in middle/ty.rs that I'm going to have to run typeck? From coder543 at gmail.com Mon Jul 8 06:43:27 2013 From: coder543 at gmail.com (Josh Leverette) Date: Mon, 8 Jul 2013 08:43:27 -0500 Subject: [rust-dev] flatpipes question In-Reply-To: References: Message-ID: Now this is interesting. So, I took the second pipe's code and modified it to this: extern mod std; extern mod extra; use std::{task, io}; use extra::flatpipes; fn main() { let (port, chan) = flatpipes::serial::pipe_stream(); let portBox = ~port; do task::spawn || { let val = portBox.recv(); io::println(fmt!("Value: %?", val)); } let value = @[1, 2, 3, 4, 5]; chan.send(value); } When I tried to compile it, the error was as follows: pipe2.rs:10:18: 10:25 error: cannot capture variable of type `~extra::flatpipes::FlatPort<@[int],extra::flatpipes::flatteners::DeserializingUnflattener,extra::flatpipes::bytepipes::PipeBytePort>`, which does not fulfill `Send`, in a bounded closure pipe2.rs:10 let val = portBox.recv(); ^~~~~~~ pipe2.rs:10:18: 10:25 *note: this closure's environment must satisfy `Send`* pipe2.rs:10 let val = portBox.recv(); This might be the real reason it couldn't compile with the port.recv(), no? On Mon, Jul 8, 2013 at 1:43 AM, Alexander Stavonin wrote: > Full source code: > > extern mod std; > extern mod extra; > use std::{task, io}; > use extra::flatpipes; > > fn main() { > let (port, chan) = flatpipes::serial::pipe_stream(); > do task::spawn || { > let value = @[1, 2, 3, 4, 5]; > chan.send(value) > } > let val = port.recv(); > io::println(fmt!("%?", val)); > > /*let (port, chan) = flatpipes::serial::pipe_stream();*/ > /*do task::spawn || {*/ > /*let val = port.recv();*/ > /*io::println(fmt!("Value: %?", val));*/ > /*}*/ > /*let value = @[1, 2, 3, 4, 5];*/ > /*chan.send(value);*/ > } > > And compiler output: > > astavonin:/Users/../rust: rustc -v > rustc 0.7 > host: x86_64-apple-darwin > astavonin:/Users/../rust: rustc test.rs > warning: no debug symbols in executable (-arch x86_64) > > But, If you uncomment second block, you'll have next error: > > test.rs:19:18: 19:22 error: cannot capture variable of type > `extra::flatpipes::FlatPort<@[int],extra::flatpipes::flatteners::DeserializingUnflattener,extra::flatpipes::bytepipes::PipeBytePort>`, > which does not fulfill `Send`, in a bounded closure > test.rs:19 let val = port.recv(); > ^~~~ > test.rs:19:18: 19:22 note: this closure's environment must satisfy `Send` > test.rs:19 let val = port.recv(); > ^~~~ > error: aborting due to previous error > > > > Best regards, > Alexander. > > > 2013/7/8 Josh Leverette > >> I'm having difficulty compiling even the first sample. Nothing I do can >> convince my rust 0.7 compiler of the existence of flatpipes... but I'm new >> to this whole thing anyways. >> >> The one thing that jumps out at me: should the second example have "||" >> after the word 'spawn' in the do statement? i.e. do task::spawn || { >> instead of do task::spawn { >> >> My understanding is that the empty vertical bars indicate an empty >> argument name list, so it should have no negative effect on the code, but >> it's worth testing, I suppose. What "use" or "extern mod" statements did >> you place at the top of the Rust files in order to get them to compile? I >> may not know much, but I'd like to learn, and I'd like to help when I can. >> >> According to the tutorial, both chan and port should be sendable types >> that can be transferred to the task's closure. >> >> I'm interested in what's going on here as well. >> >> >> On Sun, Jul 7, 2013 at 1:49 PM, Alexander Stavonin wrote: >> >>> There are two fragments of codes first one can be compiled without any >>> errors: >>> >>> let (port, chan) = flatpipes::serial::pipe_stream(); >>> do task::spawn || { >>> let value = @[1, 2, 3, 4, 5]; >>> chan.send(value) >>> } >>> let val = port.recv(); >>> io::println(fmt!("%?", val)); >>> >>> But second one provides errors: >>> >>> let (port, chan) = flatpipes::serial::pipe_stream(); >>> do task::spawn { >>> let val = port.recv(); >>> io::println(fmt!("Value: %?", val)); >>> } >>> let value = @[1, 2, 3, 4, 5]; >>> chan.send(value); >>> >>> tmp.rs:19:18: 19:22 error: value has non-owned type >>> `extra::flatpipes::FlatPort<@[int],extra::flatpipes::flatteners::DeserializingUnflattener,extra::flatpipes::bytepipes::PipeBytePort>` >>> tmp.rs:19 let val = port.recv(); >>> ^~~~ >>> >>> From my point of view, both fragments are equivalent, so, is it >>> compiler error or my misunderstanding? >>> >>> Kind regards, >>> Alexander >>> >>> >>> _______________________________________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/listinfo/rust-dev >>> >>> >> >> >> -- >> Sincerely, >> Josh >> > > -- Sincerely, Josh -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthieu.monrocq at gmail.com Mon Jul 8 09:26:33 2013 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Mon, 8 Jul 2013 18:26:33 +0200 Subject: [rust-dev] Borrow lifetime assignment changed? In-Reply-To: <51D9D085.9020407@crsr.net> References: <51D83730.8040200@crsr.net> <51D9C572.7080802@mozilla.com> <51D9D085.9020407@crsr.net> Message-ID: On Sun, Jul 7, 2013 at 10:33 PM, Tommy M. McGuire wrote: > On 07/07/2013 02:45 PM, Graydon Hoare wrote: > > There is a specific rule in the C++ specification to address > > temporaries: they should live up until the end of the full expression > > they are part of. > > If it is difficult to get that working right, would it be easier if they > lived to the end of the block? That is the effect of naming them, right? > > (I always thought C++'s rule was more of a stunt or joke than a useful > rule---it's apparently harder to get right than I thought it was, it's > hard to explain to people, and it does nothing useful for me, > programming-wise.) > > It is very hard to get right indeed, especially because expressions can be nested within themselves and objects should be destroyed in the strict reverse order they were created. As I said, it regularly generates bugs in Clang (and I imagine gcc) because each time you introduce a new kind of node in the AST you need to make sure it plays right with this rule (among others) and the problem is generally subtle enough to get through the initial testing phase unnoticed. On the other hand, with RAII, it can be quite interesting; you can simulate a "with .... as name:" python statement somewhat for example "with(...).do([](auto& name) { ... })" -- Matthieu > -- > Tommy M. McGuire > mcguire at crsr.net > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Mon Jul 8 11:24:42 2013 From: banderson at mozilla.com (Brian Anderson) Date: Mon, 08 Jul 2013 11:24:42 -0700 Subject: [rust-dev] flatpipes question In-Reply-To: References: Message-ID: <51DB03EA.4030200@mozilla.com> On 07/08/2013 06:43 AM, Josh Leverette wrote: > > extern mod std; > extern mod extra; > use std::{task, io}; > use extra::flatpipes; > > fn main() { > let (port, chan) = flatpipes::serial::pipe_stream(); > let portBox = ~port; > do task::spawn || { > let val = portBox.recv(); > io::println(fmt!("Value: %?", val)); > } > let value = @[1, 2, 3, 4, 5]; > chan.send(value); > } The problem is that an @-box was added to the PipeBytePort type, which makes it unsendable, so at the moment flatpipe ports cannot be sent. Channels are still sendable. Here's the definition in question: pub struct PipeBytePort { port: comm::Port<~[u8]>, buf: @mut ~[u8] } From coder543 at gmail.com Mon Jul 8 11:40:35 2013 From: coder543 at gmail.com (Josh Leverette) Date: Mon, 8 Jul 2013 13:40:35 -0500 Subject: [rust-dev] flatpipes question In-Reply-To: <51DB03EA.4030200@mozilla.com> References: <51DB03EA.4030200@mozilla.com> Message-ID: Ah, thanks! Section 2.1 of this tutorial ( http://static.rust-lang.org/doc/tutorial-tasks.html) should probably be updated to make it clear that ports are (at least, temporarily) unsendable. I'm glad to see that there is a solid reason for the compiler error message. Bugs in a compiler are never fun. On Mon, Jul 8, 2013 at 1:24 PM, Brian Anderson wrote: > On 07/08/2013 06:43 AM, Josh Leverette wrote: > >> >> extern mod std; >> extern mod extra; >> use std::{task, io}; >> use extra::flatpipes; >> >> fn main() { >> let (port, chan) = flatpipes::serial::pipe_**stream(); >> let portBox = ~port; >> do task::spawn || { >> let val = portBox.recv(); >> io::println(fmt!("Value: %?", val)); >> } >> let value = @[1, 2, 3, 4, 5]; >> chan.send(value); >> } >> > > The problem is that an @-box was added to the PipeBytePort type, which > makes it unsendable, so at the moment flatpipe ports cannot be sent. > Channels are still sendable. Here's the definition in question: > > pub struct PipeBytePort { > port: comm::Port<~[u8]>, > buf: @mut ~[u8] > > } > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -- Sincerely, Josh -------------- next part -------------- An HTML attachment was scrubbed... URL: From marcianx at gmail.com Mon Jul 8 16:34:41 2013 From: marcianx at gmail.com (Ashish Myles) Date: Mon, 8 Jul 2013 19:34:41 -0400 Subject: [rust-dev] Why separate equivalent impls for &'self [A], ~[A], @[A] In-Reply-To: References: Message-ID: On Sat, Jul 6, 2013 at 10:26 PM, Daniel Micay wrote: > On Sat, Jul 6, 2013 at 10:09 PM, Ashish Myles wrote: >> Perhaps this was an oversight as the code base has developed >> organically. But in case it was intentional, I just wanted to check. >> >> libstd/to_str.rs defines each of the following impls >> impl<'self,A:ToStr> ToStr for &'self [A] >> impl ToStr for ~[A] >> impl ToStr for @[A] >> whereas only the first one seems to be needed to cover all array >> cases. To test this, I defined an equivalent MyToStr trait, defining >> only the implementation for &'self [A], and it seemed to work for all >> the array types. So just to check: is there any particular reason one >> would want to define all three with identical implementation? > > Vectors will coerce to slices, but the traits still need to be defined > on them for it to work in generic code where you only have a type via > a generic type parameter. Oh that's a great point. I have already run multiple times into struggling to understand the compiler rejection of my code until I realized that I simply didn't declare the generic type parameter as having defined the required traits. I suppose it's lower priority but it would be nice to have the feature of defining a trait implementation for all three types (&, ~, @) simultaneously. Using a private helper function not belonging to any trait seems to work for now. From a.stavonin at gmail.com Mon Jul 8 23:41:57 2013 From: a.stavonin at gmail.com (Alexander Stavonin) Date: Tue, 9 Jul 2013 10:41:57 +0400 Subject: [rust-dev] Rust-dev Digest, Vol 37, Issue 25 In-Reply-To: References: Message-ID: Brian, thank you for explanation. But, in that case I have one more question. If PipeBytePort is unsendable any more, how bidirectional, pipe_stream based communication could be organised? Best regards, Alexander. 2013/7/8 > > > Message: 1 > Date: Mon, 08 Jul 2013 11:24:42 -0700 > From: Brian Anderson > To: rust-dev at mozilla.org > Subject: Re: [rust-dev] flatpipes question > Message-ID: <51DB03EA.4030200 at mozilla.com> > Content-Type: text/plain; charset=ISO-8859-1; format=flowed > > On 07/08/2013 06:43 AM, Josh Leverette wrote: > > > > extern mod std; > > extern mod extra; > > use std::{task, io}; > > use extra::flatpipes; > > > > fn main() { > > let (port, chan) = flatpipes::serial::pipe_stream(); > > let portBox = ~port; > > do task::spawn || { > > let val = portBox.recv(); > > io::println(fmt!("Value: %?", val)); > > } > > let value = @[1, 2, 3, 4, 5]; > > chan.send(value); > > } > > The problem is that an @-box was added to the PipeBytePort type, which > makes it unsendable, so at the moment flatpipe ports cannot be sent. > Channels are still sendable. Here's the definition in question: > > pub struct PipeBytePort { > port: comm::Port<~[u8]>, > buf: @mut ~[u8] > } > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > > End of Rust-dev Digest, Vol 37, Issue 25 > **************************************** > -------------- next part -------------- An HTML attachment was scrubbed... URL: From fredrik at haard.se Tue Jul 9 02:21:53 2013 From: fredrik at haard.se (=?UTF-8?B?RnJlZHJpayBIw6XDpXJk?=) Date: Tue, 9 Jul 2013 11:21:53 +0200 Subject: [rust-dev] Where did unicode go? Message-ID: I'm trying to migrate to 0.7, and failing - I was using unicode::general_category::Cc, but since updating I cannot seem to find it in the docs (may very well be user error), and linking fails. Any hint's on what I should do instead? The offending code is if unicode::general_category::Cc(astr.char_at(0)) { ... } And the output from rustc: -------------- > rustc generate_encoding.rs error: linking with `cc` failed with code 1 note: cc arguments: -L/usr/local/lib/rustc/x86_64-apple-darwin/lib -m64 -o generate_encoding generate_encoding.o -L/usr/local/lib/rustc/x86_64-apple-darwin/lib -lstd-6c65cf4b443341b1-0.7 -Wl,-no_compact_unwind -lmorestack -lrustrt -Wl,-rpath, at executable_path/../../../../usr/local/lib/rustc/x86_64-apple-darwin/lib -Wl,-rpath,/usr/local/lib/rustc/x86_64-apple-darwin/lib note: Undefined symbols for architecture x86_64: "unicode::general_category::Cc::_236d8020bf63f514::_0$x2e7", referenced from: get_charmap::anon::expr_fn_4125 in generate_encoding.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) error: aborting due to previous error > rustc --version rustc 0.7 (e07ae9e 2013-07-07 19:35:00 -0700) host: x86_64-apple-darwin -- /f I reject your reality and substitute my own. http://courteous.ly/yp3Zgd From corey at octayn.net Tue Jul 9 03:45:25 2013 From: corey at octayn.net (Corey Richardson) Date: Tue, 9 Jul 2013 06:45:25 -0400 Subject: [rust-dev] Where did unicode go? In-Reply-To: References: Message-ID: On Tue, Jul 9, 2013 at 5:21 AM, Fredrik H??rd wrote: > I'm trying to migrate to 0.7, and failing - I was using > unicode::general_category::Cc, but since updating I cannot seem to > find it in the docs (may very well be user error), and linking fails. > > Any hint's on what I should do instead? > > The offending code is > > if unicode::general_category::Cc(astr.char_at(0)) { > ... > } > > And the output from rustc: > -------------- > > [snip] That's quite odd. The function is still there, but rustc should never generate a failure in the linker like that for "pure" Rust code. "Undefined symbols for architecture x86_64" makes me think you might have 32-bit libraries installed? From coder543 at gmail.com Tue Jul 9 05:08:21 2013 From: coder543 at gmail.com (Josh Leverette) Date: Tue, 9 Jul 2013 07:08:21 -0500 Subject: [rust-dev] Rust-dev Digest, Vol 37, Issue 25 In-Reply-To: References: Message-ID: Make a second pipestream inside the async task and send the new chan object through the chan object that was passed into the task. You'll have a port inside the task that can listen to the newly created chan object. On Jul 9, 2013 1:42 AM, "Alexander Stavonin" wrote: > Brian, thank you for explanation. But, in that case I have one more > question. If PipeBytePort is unsendable any more, how bidirectional, pipe_stream > based communication could be organised? > > > Best regards, > Alexander. > > 2013/7/8 >> >> >> Message: 1 >> Date: Mon, 08 Jul 2013 11:24:42 -0700 >> From: Brian Anderson >> To: rust-dev at mozilla.org >> Subject: Re: [rust-dev] flatpipes question >> Message-ID: <51DB03EA.4030200 at mozilla.com> >> Content-Type: text/plain; charset=ISO-8859-1; format=flowed >> >> On 07/08/2013 06:43 AM, Josh Leverette wrote: >> > >> > extern mod std; >> > extern mod extra; >> > use std::{task, io}; >> > use extra::flatpipes; >> > >> > fn main() { >> > let (port, chan) = flatpipes::serial::pipe_stream(); >> > let portBox = ~port; >> > do task::spawn || { >> > let val = portBox.recv(); >> > io::println(fmt!("Value: %?", val)); >> > } >> > let value = @[1, 2, 3, 4, 5]; >> > chan.send(value); >> > } >> >> The problem is that an @-box was added to the PipeBytePort type, which >> makes it unsendable, so at the moment flatpipe ports cannot be sent. >> Channels are still sendable. Here's the definition in question: >> >> pub struct PipeBytePort { >> port: comm::Port<~[u8]>, >> buf: @mut ~[u8] >> } >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> >> End of Rust-dev Digest, Vol 37, Issue 25 >> **************************************** >> > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From lucab at debian.org Tue Jul 9 05:16:24 2013 From: lucab at debian.org (Luca Bruno) Date: Tue, 9 Jul 2013 14:16:24 +0200 Subject: [rust-dev] Tutorial translations In-Reply-To: <51D4C11D.70703@mozilla.com> References: <51D4C11D.70703@mozilla.com> Message-ID: <20130709141624.468b3fc9@xantho> On Wed, 03 Jul 2013 17:26:05 -0700 Graydon Hoare wrote: > .po files aren't perfect, but they seem to be dominant in this space. > There are a lot of tools to work with them, show the drift from a > translation and its source, and reconstruct software and documentation > artifacts from the result. I think po4a might be applicable to the .md > files that hold our docs: > http://po4a.alioth.debian.org/ > > Someone who is familiar with these tools and workflows would be very > welcome here. We've had a few people ask and just haven't got around > to handling it yet. I spent some time to do the initial po4a configuration and submitting a PR [0] for it. The .pot templates are currently available in-tree [1]. As soon as people start asking/providing localizations, more languages can be enabled (I didn't enabled any, so far). [0] https://github.com/mozilla/rust/pull/7641 [1] https://github.com/mozilla/rust/tree/master/doc/po > I was hoping we'd set up a pootle server to translate .po files, > and/or use the existing pootle instance mozilla runs: > https://localize.mozilla.org/ If you are going to re-use the same infrastructure, you can just import the .pot. Otherwise, I can also suggest weblate [2], which has saner ACL handling and some degree of git and web hooking. [2] http://weblate.org/en/ Cheers, Luca -- .''`. | ~<[ Luca BRUNO ~ (kaeso) ]>~ : :' : | Email: lucab (AT) debian.org ~ Debian Developer `. `'` | GPG Key ID: 0x3BFB9FB3 ~ Free Software supporter `- | HAM-radio callsign: IZ1WGT ~ Networking sorcerer From graydon at mozilla.com Tue Jul 9 08:40:29 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 09 Jul 2013 08:40:29 -0700 Subject: [rust-dev] Tutorial translations In-Reply-To: <20130709141624.468b3fc9@xantho> References: <51D4C11D.70703@mozilla.com> <20130709141624.468b3fc9@xantho> Message-ID: <51DC2EED.1010305@mozilla.com> On 13-07-09 05:16 AM, Luca Bruno wrote: > I spent some time to do the initial po4a configuration and submitting a > PR [0] for it. The .pot templates are currently available in-tree [1]. > As soon as people start asking/providing localizations, more languages > can be enabled (I didn't enabled any, so far). > > [0] https://github.com/mozilla/rust/pull/7641 > [1] https://github.com/mozilla/rust/tree/master/doc/po Thank you _so much_ for this! This is great. -Graydon From pwalton at mozilla.com Wed Jul 10 11:32:08 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Wed, 10 Jul 2013 11:32:08 -0700 Subject: [rust-dev] Incremental and generational GC Message-ID: <51DDA8A8.9060707@mozilla.com> Hi everyone, (Warning: GC pointy-headedness ahead.) I've been thinking about what will be needed to support incremental and generational GC in Rust. To be clear, I don't think we should block on it now, but we should not make it unduly difficult for us to implement in the future. The hard parts of incremental and generational GC are the barriers. There is a different write barrier regarded for both. (I'm assuming incremental-update IGC, not snapshot-at-the-beginning, which is a harder barrier.) First, some terminology. Consider this picture: +-->B | A C A is the "referrer". Suppose that the mutator mutates it to this: B A------>C C is the "referent". For IGC and GGC, we need some sort of barrier. For incremental GC, we must maintain the tri-color invariant, which means that a black object must never point to a white object. There are two basic ways to do this: either a write barrier graying a white object referent or graying a black object referrer. In Rust, the latter would be the easiest to implement: whenever you borrow an `@mut` to `&mut` (which is what you need to do to mutate) we can gray the object if it's black. This does mean that we need to make sure that all contents of `@mut` are Freeze; otherwise, we won't trip the barrier. For generational GC, we must ensure that objects in the nursery pointed to by the tenured generation are either added to a remembered set or tenured. This is harder in Rust because we have to know both the generation of the referrer and the referent simultaneously. I believe that conservatively tenuring all objects that are mutated would be overconservative and defeat much of the purpose of GGC. The only thing that I can think of that would work is to use the MMU and do the generational GC barriers on a per-page basis. I believe that this is what Boehm does in its GGC mode. This to me seems the most risky part of this; I'm not sure what the performance implications of this are. Doing this will keep `Gc` and `GcMut` implicitly copyable without custom copy constructors, which is nice. It is true that we will not be able to perform the change that was agreed on to change `GcMut` to `Gc>`, since `Cell` is not `Freeze`. Thoughts? Patrick From graydon at mozilla.com Wed Jul 10 13:04:06 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 10 Jul 2013 13:04:06 -0700 Subject: [rust-dev] Incremental and generational GC In-Reply-To: <51DDA8A8.9060707@mozilla.com> References: <51DDA8A8.9060707@mozilla.com> Message-ID: <51DDBE36.3030500@mozilla.com> On 13-07-10 11:32 AM, Patrick Walton wrote: > I've been thinking about what will be needed to support incremental and > generational GC in Rust. To be clear, I don't think we should block on > it now, but we should not make it unduly difficult for us to implement > in the future. I figured we'd be doing the incremental-generational variant of mostly-copying (once we get mostly-copying working _at all_ -- we're a long ways from there). Trap on @-writes to heap, mask to page bits, compare generation numbers. With MMU or without, depending on environment. I assume you've read this: http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-91-8.pdf yes? -Graydon From niko at alum.mit.edu Wed Jul 10 13:07:51 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 10 Jul 2013 16:07:51 -0400 Subject: [rust-dev] Incremental and generational GC In-Reply-To: <51DDA8A8.9060707@mozilla.com> References: <51DDA8A8.9060707@mozilla.com> Message-ID: <20130710200751.GA26187@Mr-Bennet> Still chewing on this. Two questions below and one preliminary thought below. On Wed, Jul 10, 2013 at 11:32:08AM -0700, Patrick Walton wrote: > This does mean that we need to make sure that all contents of `@mut` > are Freeze; otherwise, we won't trip the barrier. This seems stricter than necessary. You don't want unsafe mutation a la Cell, but `@mut` should be ok. > For generational GC, we must ensure that objects in the nursery > pointed to by the tenured generation are either added to a remembered > set or tenured. This is harder in Rust because we have to know both > the generation of the referrer and the referent simultaneously. I > believe that conservatively tenuring all objects that are mutated > would be overconservative and defeat much of the purpose of GGC. I don't get this. My understanding of how GGC works is that whenever a tenured object is mutated, you flag it into a set. Then when you scan the nursery, you scan only this set to uncover new roots. This requires a write barrier. As you explained above, write barriers are fairly straightforward with `@mut`, but quite challenging if you replace `@mut` with Cell. Preliminary thought: I think we should either replace `@mut` with `Cell` or remove `Cell`. Near as I can tell, `Cell` today exists primarily to work-around limitations that all have better solutions in the works. Moving from `@mut` to `Cell` is a more flexible and orthogonal system, in that you can define the granularity of the write barriers and you have have `Gc>` and `Rc>` rather than each kind of opinter requiring a `Foo` and `FooMut` variant, all of which repeat basically the same logic. However, moving from `@mut` to `Cell` does seem to rule out write barriers, and hence will limit the ability to write maximally efficient garbage collectors. This may be ok, but it's definitely the kind of decision you want to make with your eyes open, so I'm glad you pointed this out! Niko From niko at alum.mit.edu Wed Jul 10 13:35:53 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 10 Jul 2013 16:35:53 -0400 Subject: [rust-dev] Incremental and generational GC In-Reply-To: <20130710200751.GA26187@Mr-Bennet> References: <51DDA8A8.9060707@mozilla.com> <20130710200751.GA26187@Mr-Bennet> Message-ID: <20130710203553.GB26187@Mr-Bennet> Argh. This is not the message I meant to send. I got a bit too clever with my mail client. Anyway, here is a somewhat more full response. This is a very good point that you raise. We have to be aware of the impact of our decisions on garbage collection; for whatever reason, it seems to be one of those language features that is completely non-orthogonal to everything else. The problem you raise is not specific to `Cell` (which I think will go away, unless it becomes the replacement for `@mut`). It seems to me that we cannot safely handle write barriers for any type that has internal mutation. For example, `RcMut`. Basically, to handle write barriers, we need to maintain the invariant that all mutable slots which contain a managed ponter are ultimately owned by the stack or by some other managed pointer. This implies that one cannot have an `RcMut` that contains an `@T` pointer, though an `Rc` is ok. Interestingly, as we have discussed before, even something like `Rc<@T>` introduces another challenge: the `@T` becomes a root. When walking the set of roots, then, the garbage collector must be able to traverse arbitrary user-defined smart pointers. This is solvable by having a trait that dereferences the smart pointer; we need such a trait anyway, if the smart pointer is to play nicely with autoderef, but there will be a bit of cleverness required to write everything up nicely. All of this leads me to wonder if smart pointers that contain managed data is just a bad combination. Suppose we have a trait Unmanaged, then we can define the smart pointer trait as something like: trait SmartPointer { fn deref<'a>(&'a self) -> &'a T; } and thus ensure that smart pointers are never used to store managed data, or at least make it harder. This avoids the need for the GC to traverse smart pointers at all and means that (if we stick with `@mut`, rather `Cell`) we can still handle write barriers. On the other hand, I also wonder if we shouldn't just accept that Rust's GC will be somewhat handicapped and cannot fully support incremental nor genreational techniques. We can still use generational techniques for immutable data. Given that GC is task-local, and that it is optional, this is perhaps acceptable. On the other other hand, I have to read and digest the thesis that Graydon sent. At least based on the summary, it does seem that the "mostly copying" technique addresses the issue. The thesis seems to use the MMU for write guards. Niko On Wed, Jul 10, 2013 at 04:07:51PM -0400, Niko Matsakis wrote: > Still chewing on this. Two questions below and one preliminary thought > below. > > On Wed, Jul 10, 2013 at 11:32:08AM -0700, Patrick Walton wrote: > > This does mean that we need to make sure that all contents of `@mut` > > are Freeze; otherwise, we won't trip the barrier. > > This seems stricter than necessary. You don't want unsafe mutation a > la Cell, but `@mut` should be ok. > > > For generational GC, we must ensure that objects in the nursery > > pointed to by the tenured generation are either added to a remembered > > set or tenured. This is harder in Rust because we have to know both > > the generation of the referrer and the referent simultaneously. I > > believe that conservatively tenuring all objects that are mutated > > would be overconservative and defeat much of the purpose of GGC. > > I don't get this. My understanding of how GGC works is that whenever a > tenured object is mutated, you flag it into a set. Then when you scan > the nursery, you scan only this set to uncover new roots. This > requires a write barrier. As you explained above, write barriers are > fairly straightforward with `@mut`, but quite challenging if you > replace `@mut` with Cell. > > Preliminary thought: > > I think we should either replace `@mut` with `Cell` or remove > `Cell`. Near as I can tell, `Cell` today exists primarily to > work-around limitations that all have better solutions in the works. > > Moving from `@mut` to `Cell` is a more flexible and orthogonal system, > in that you can define the granularity of the write barriers and you > have have `Gc>` and `Rc>` rather than each kind of > opinter requiring a `Foo` and `FooMut` variant, all of which repeat > basically the same logic. > > However, moving from `@mut` to `Cell` does seem to rule out write > barriers, and hence will limit the ability to write maximally > efficient garbage collectors. This may be ok, but it's definitely the > kind of decision you want to make with your eyes open, so I'm glad you > pointed this out! > > > > > Niko > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From niko at alum.mit.edu Wed Jul 10 13:47:00 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 10 Jul 2013 16:47:00 -0400 Subject: [rust-dev] Incremental and generational GC In-Reply-To: <51DDA8A8.9060707@mozilla.com> References: <51DDA8A8.9060707@mozilla.com> Message-ID: <20130710204700.GC26187@Mr-Bennet> Also, to spell out a bit of background that may not be clear, if I understand pcwalton correctly, the problem scenario he is envisioning is as follows. Imagine that you have a function `modify` that takes a borrowed pointer to a cell and mutates its contents: fn modify(x: &Cell<@T>, y: @T) { *x.as_mut() = y; } Naturally, `modify)` could be used with a cell that resides anywhere, such as the stack etc. But this cell might also reside in managed data: let tenured: @Cell<@T> = ...; let nursery: @T = @...; modify(&*tenured, nursery) In this scenario, we are creating an edge from a tenured object to one in the nursery, but when do we trip the write guard? We borrowed the tenured object immutably, so there is no write guard there. The write place would be in `modify()`, but `modify()` is not specific to managed data, so we don't want to add any sorts of write guards there, as they would affect all writes. There are various options I see to rule out this scenario: - Use MMU for write barriers. - Add write guards to `modify()` and try to eliminate them statically whenever possible (inter-procedural analysis). - Forbid managed data from *owning* values with internal mutation, like `Cell` or `RcMut`. - Forbid `Cell` and friends from containing managed data. - Don't use a GC scheme that requires write barriers. Niko On Wed, Jul 10, 2013 at 11:32:08AM -0700, Patrick Walton wrote: > Hi everyone, > > (Warning: GC pointy-headedness ahead.) > > I've been thinking about what will be needed to support incremental > and generational GC in Rust. To be clear, I don't think we should > block on it now, but we should not make it unduly difficult for us to > implement in the future. > > The hard parts of incremental and generational GC are the barriers. > There is a different write barrier regarded for both. (I'm assuming > incremental-update IGC, not snapshot-at-the-beginning, which is a > harder barrier.) > > First, some terminology. Consider this picture: > > +-->B > | > A C > > A is the "referrer". Suppose that the mutator mutates it to this: > > B > > A------>C > > C is the "referent". > > For IGC and GGC, we need some sort of barrier. > > For incremental GC, we must maintain the tri-color invariant, which > means that a black object must never point to a white object. There > are two basic ways to do this: either a write barrier graying a white > object referent or graying a black object referrer. In Rust, the > latter would be the easiest to implement: whenever you borrow an > `@mut` to `&mut` (which is what you need to do to mutate) we can gray > the object if it's black. This does mean that we need to make sure > that all contents of `@mut` are Freeze; otherwise, we won't trip the > barrier. > > For generational GC, we must ensure that objects in the nursery > pointed to by the tenured generation are either added to a remembered > set or tenured. This is harder in Rust because we have to know both > the generation of the referrer and the referent simultaneously. I > believe that conservatively tenuring all objects that are mutated > would be overconservative and defeat much of the purpose of GGC. > > The only thing that I can think of that would work is to use the MMU > and do the generational GC barriers on a per-page basis. I believe > that this is what Boehm does in its GGC mode. This to me seems the > most risky part of this; I'm not sure what the performance > implications of this are. > > Doing this will keep `Gc` and `GcMut` implicitly copyable without > custom copy constructors, which is nice. It is true that we will not > be able to perform the change that was agreed on to change `GcMut` > to `Gc>`, since `Cell` is not `Freeze`. > > Thoughts? > > Patrick > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From graydon at mozilla.com Wed Jul 10 13:52:47 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 10 Jul 2013 13:52:47 -0700 Subject: [rust-dev] Incremental and generational GC In-Reply-To: <20130710204700.GC26187@Mr-Bennet> References: <51DDA8A8.9060707@mozilla.com> <20130710204700.GC26187@Mr-Bennet> Message-ID: <51DDC99F.9060603@mozilla.com> On 13-07-10 01:47 PM, Niko Matsakis wrote: > - Use MMU for write barriers. > - Add write guards to `modify()` and try to eliminate them statically > whenever possible (inter-procedural analysis). Yeah, I figured we'd do this. Trap @-writes when they might-be-to-the-heap. Mask to page boundary, check generation numbers, update. The MMU is also certainly possible if the environment permits it. > - Forbid managed data from *owning* values with internal mutation, like `Cell` or `RcMut`. > - Forbid `Cell` and friends from containing managed data. These seem a little arbitrary. The first was how we had it for a while (and it prohibits cycle-formation, pleasantly) but people complained. The latter might fly, I'm not sure. I expect there are too many use cases, but that's pure speculation on my part. > - Don't use a GC scheme that requires write barriers. That's where we're starting out. We'll see how it goes. -Graydon From niko at alum.mit.edu Wed Jul 10 13:55:53 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 10 Jul 2013 16:55:53 -0400 Subject: [rust-dev] Incremental and generational GC In-Reply-To: <51DDA8A8.9060707@mozilla.com> References: <51DDA8A8.9060707@mozilla.com> Message-ID: <20130710205401.GD26187@Mr-Bennet> Hmm, on IRC strcat pointed out another option. Imagine that we pushed all mutability into `Cell`. Then when `Cell` borrows as mut, it could have some code like this: if contains_managed::() { // contains_managed is an intrinsic test of the type T write_barrier(); } We would have to design the write barrier code to be able to cheaply check whether a given pointer is managed or not, but that's not a big deal (this requirement is already present). I didn't list this option because I considered it to be the same as guarding all writes, but of course it is not. It imposes additional overhead on all users of Cell, but *only* on users of Cell, and only when the values in the cell contain managed pointers. Technically, this design does not require pushing mutability into `Cell`, but if we do that we gain the advantage that Cell is the only one who has to worry about tripping write barriers. Niko On Wed, Jul 10, 2013 at 11:32:08AM -0700, Patrick Walton wrote: > Hi everyone, > > (Warning: GC pointy-headedness ahead.) > > I've been thinking about what will be needed to support incremental > and generational GC in Rust. To be clear, I don't think we should > block on it now, but we should not make it unduly difficult for us to > implement in the future. > > The hard parts of incremental and generational GC are the barriers. > There is a different write barrier regarded for both. (I'm assuming > incremental-update IGC, not snapshot-at-the-beginning, which is a > harder barrier.) > > First, some terminology. Consider this picture: > > +-->B > | > A C > > A is the "referrer". Suppose that the mutator mutates it to this: > > B > > A------>C > > C is the "referent". > > For IGC and GGC, we need some sort of barrier. > > For incremental GC, we must maintain the tri-color invariant, which > means that a black object must never point to a white object. There > are two basic ways to do this: either a write barrier graying a white > object referent or graying a black object referrer. In Rust, the > latter would be the easiest to implement: whenever you borrow an > `@mut` to `&mut` (which is what you need to do to mutate) we can gray > the object if it's black. This does mean that we need to make sure > that all contents of `@mut` are Freeze; otherwise, we won't trip the > barrier. > > For generational GC, we must ensure that objects in the nursery > pointed to by the tenured generation are either added to a remembered > set or tenured. This is harder in Rust because we have to know both > the generation of the referrer and the referent simultaneously. I > believe that conservatively tenuring all objects that are mutated > would be overconservative and defeat much of the purpose of GGC. > > The only thing that I can think of that would work is to use the MMU > and do the generational GC barriers on a per-page basis. I believe > that this is what Boehm does in its GGC mode. This to me seems the > most risky part of this; I'm not sure what the performance > implications of this are. > > Doing this will keep `Gc` and `GcMut` implicitly copyable without > custom copy constructors, which is nice. It is true that we will not > be able to perform the change that was agreed on to change `GcMut` > to `Gc>`, since `Cell` is not `Freeze`. > > Thoughts? > > Patrick > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From pwalton at mozilla.com Wed Jul 10 14:15:05 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Wed, 10 Jul 2013 14:15:05 -0700 Subject: [rust-dev] Incremental and generational GC In-Reply-To: <20130710205401.GD26187@Mr-Bennet> References: <51DDA8A8.9060707@mozilla.com> <20130710205401.GD26187@Mr-Bennet> Message-ID: <51DDCED9.8090807@mozilla.com> On 7/10/13 1:55 PM, Niko Matsakis wrote: > Technically, this design does not require pushing mutability into > `Cell`, but if we do that we gain the advantage that Cell is the only > one who has to worry about tripping write barriers. That's genius. +1. Patrick From erick.tryzelaar at gmail.com Wed Jul 10 14:25:48 2013 From: erick.tryzelaar at gmail.com (Erick Tryzelaar) Date: Wed, 10 Jul 2013 14:25:48 -0700 Subject: [rust-dev] Incremental and generational GC In-Reply-To: <20130710205401.GD26187@Mr-Bennet> References: <51DDA8A8.9060707@mozilla.com> <20130710205401.GD26187@Mr-Bennet> Message-ID: On Wed, Jul 10, 2013 at 1:55 PM, Niko Matsakis wrote: > We would have to design the write barrier code to be able to cheaply > check whether a given pointer is managed or not, but that's not a big deal (this requirement is already present). > This may be treading into constant-expr territory, but could this `contains_managed::()` be an intrinsic that is compiled away for non-managed types? -------------- next part -------------- An HTML attachment was scrubbed... URL: From coder543 at gmail.com Wed Jul 10 14:37:27 2013 From: coder543 at gmail.com (Josh Leverette) Date: Wed, 10 Jul 2013 16:37:27 -0500 Subject: [rust-dev] Broken tutorial code? Message-ID: I'm kinda working my way through The Rust Language Tutorial, and the sample in section 4.3 "Loops" seems broken. The code is as follows. let mut x = 5;loop { x += x - 3; if x % 5 == 0 { break; } println(int::to_str(x)); } If I wrap my main function around this code, it won't compile because it says that int::to_str(x) is unresolved. Specifically... test.rs:7:12: 7:23 error: unresolved name test.rs:7 println(int::to_str(x)); ^~~~~~~~~~~ test.rs:7:12: 7:23 error: use of undeclared module `int` test.rs:7 println(int::to_str(x)); ^~~~~~~~~~~ test.rs:7:12: 7:23 error: unresolved name `int::to_str`. test.rs:7 println(int::to_str(x)); If I try changing it to x.to_str(), then it gets upset because x's type is ambiguous and it can't decide between all of the many numeric types as to which one should receive the to_str() call. I fixed it by declaring "x" to be an int and then just saying x.to_str()... but why was int::to_str unresolved? -- Sincerely, Josh -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Wed Jul 10 14:45:25 2013 From: corey at octayn.net (Corey Richardson) Date: Wed, 10 Jul 2013 17:45:25 -0400 Subject: [rust-dev] Broken tutorial code? In-Reply-To: References: Message-ID: On Wed, Jul 10, 2013 at 5:37 PM, Josh Leverette wrote: > I fixed it by declaring "x" to be an int and then just saying x.to_str()... > but why was int::to_str unresolved? > Because the `int` module wasn't in scope. Thus the error "use of undeclared module `int`". `use std::int;` brings it in scope. But, I don't know that that free function still exists... generally you want the method (there's a free-function crusade going on). From danielmicay at gmail.com Wed Jul 10 14:53:49 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Wed, 10 Jul 2013 17:53:49 -0400 Subject: [rust-dev] Incremental and generational GC In-Reply-To: References: <51DDA8A8.9060707@mozilla.com> <20130710205401.GD26187@Mr-Bennet> Message-ID: On Wed, Jul 10, 2013 at 5:25 PM, Erick Tryzelaar wrote: > On Wed, Jul 10, 2013 at 1:55 PM, Niko Matsakis wrote: >> >> We would have to design the write barrier code to be able to cheaply >> check whether a given pointer is managed or not, but that's not a big >> >> deal (this requirement is already present). > > > > This may be treading into constant-expr territory, but could this > `contains_managed::()` be an intrinsic that is compiled away for > non-managed types? It evaluates to a constant like our `size_of` intrinsic. Although, intrinsics are currently `alwaysinline` functions instead of expanding in-place. At an opt-level above 0, LLVM will always discard the dead code path. From pwalton at mozilla.com Wed Jul 10 14:59:54 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Wed, 10 Jul 2013 14:59:54 -0700 Subject: [rust-dev] Copyability and repeated vector expressions Message-ID: <51DDD95A.8010700@mozilla.com> Hi everyone, Currently there's a problem with repeated vector expressions (`[0, ..n]`): the value must be copyable. I would like to change this to implicit copyability changing as part of the migration to `Clone`, which makes this even more restrictive. This makes it impossible (without writing a very long literal) to have something reasonable like `[None, ..4096]` with the value as `Option<~T>`, since `Option<~T>` is not implicitly copyable. The easiest way that I can see to fix this is to treat `EXPR` in `[EXPR, ..COUNT]` as evaluated once for each `COUNT`. Essentially it becomes a thunk. This makes me slightly nervous, but I don't see anything wrong with it semantically. Thoughts? Patrick From niko at alum.mit.edu Wed Jul 10 15:01:12 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 10 Jul 2013 18:01:12 -0400 Subject: [rust-dev] Incremental and generational GC Message-ID: Yes Niko (Sent from a cramped, unreliable keyboard) -------- Original message -------- Subject: Re: [rust-dev] Incremental and generational GC From: Erick Tryzelaar To: Niko Matsakis CC: Patrick Walton ,"rust-dev at mozilla.org" On Wed, Jul 10, 2013 at 1:55 PM, Niko Matsakis wrote: We would have to design the write barrier code to be able to cheaply check whether a given pointer is managed or not, but that's not a big? deal (this requirement is already present). This may be treading into constant-expr territory, but could this `contains_managed::()` be an intrinsic that is compiled away for non-managed types? -------------- next part -------------- An HTML attachment was scrubbed... URL: From ben.striegel at gmail.com Wed Jul 10 15:33:05 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Wed, 10 Jul 2013 18:33:05 -0400 Subject: [rust-dev] Copyability and repeated vector expressions In-Reply-To: <51DDD95A.8010700@mozilla.com> References: <51DDD95A.8010700@mozilla.com> Message-ID: The bug for this is at https://github.com/mozilla/rust/issues/5244 . -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Wed Jul 10 15:38:18 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Wed, 10 Jul 2013 18:38:18 -0400 Subject: [rust-dev] Copyability and repeated vector expressions In-Reply-To: <51DDD95A.8010700@mozilla.com> References: <51DDD95A.8010700@mozilla.com> Message-ID: On Wed, Jul 10, 2013 at 5:59 PM, Patrick Walton wrote: > Hi everyone, > > Currently there's a problem with repeated vector expressions (`[0, ..n]`): > the value must be copyable. I would like to change this to implicit > copyability changing as part of the migration to `Clone`, which makes this > even more restrictive. > > This makes it impossible (without writing a very long literal) to have > something reasonable like `[None, ..4096]` with the value as `Option<~T>`, > since `Option<~T>` is not implicitly copyable. > > The easiest way that I can see to fix this is to treat `EXPR` in `[EXPR, > ..COUNT]` as evaluated once for each `COUNT`. Essentially it becomes a > thunk. This makes me slightly nervous, but I don't see anything wrong with > it semantically. > > Thoughts? > > Patrick How about we start by allowing the subset of expressions that are constant expressions? I think it would be a reasonable limitation. From danielmicay at gmail.com Wed Jul 10 15:44:26 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Wed, 10 Jul 2013 18:44:26 -0400 Subject: [rust-dev] Copyability and repeated vector expressions In-Reply-To: References: <51DDD95A.8010700@mozilla.com> Message-ID: On Wed, Jul 10, 2013 at 6:38 PM, Daniel Micay wrote: > On Wed, Jul 10, 2013 at 5:59 PM, Patrick Walton wrote: >> Hi everyone, >> >> Currently there's a problem with repeated vector expressions (`[0, ..n]`): >> the value must be copyable. I would like to change this to implicit >> copyability changing as part of the migration to `Clone`, which makes this >> even more restrictive. >> >> This makes it impossible (without writing a very long literal) to have >> something reasonable like `[None, ..4096]` with the value as `Option<~T>`, >> since `Option<~T>` is not implicitly copyable. >> >> The easiest way that I can see to fix this is to treat `EXPR` in `[EXPR, >> ..COUNT]` as evaluated once for each `COUNT`. Essentially it becomes a >> thunk. This makes me slightly nervous, but I don't see anything wrong with >> it semantically. >> >> Thoughts? >> >> Patrick > > How about we start by allowing the subset of expressions that are > constant expressions? I think it would be a reasonable limitation. Actually, I guess that doesn't matter if we're using `Clone`... but how would it work in constants? From coder543 at gmail.com Thu Jul 11 04:24:27 2013 From: coder543 at gmail.com (Josh Leverette) Date: Thu, 11 Jul 2013 06:24:27 -0500 Subject: [rust-dev] Broken tutorial code? In-Reply-To: References: Message-ID: Does it really make sense for me to be able to use the type 'int' if I haven't declared the module for it? Or the opposite perspective, does it really make sense for me to not be able to use the functions in int's module if I can use int? I understand it's a built-in, implicit type, but it still feels inconsistent. On Jul 10, 2013 4:45 PM, "Corey Richardson" wrote: > On Wed, Jul 10, 2013 at 5:37 PM, Josh Leverette > wrote: > > I fixed it by declaring "x" to be an int and then just saying > x.to_str()... > > but why was int::to_str unresolved? > > > > Because the `int` module wasn't in scope. Thus the error "use of > undeclared module `int`". `use std::int;` brings it in scope. But, I > don't know that that free function still exists... generally you want > the method (there's a free-function crusade going on). > -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Thu Jul 11 04:29:21 2013 From: corey at octayn.net (Corey Richardson) Date: Thu, 11 Jul 2013 07:29:21 -0400 Subject: [rust-dev] Broken tutorial code? In-Reply-To: References: Message-ID: On Thu, Jul 11, 2013 at 7:24 AM, Josh Leverette wrote: > Does it really make sense for me to be able to use the type 'int' if I > haven't declared the module for it? Or the opposite perspective, does it > really make sense for me to not be able to use the functions in int's module > if I can use int? I understand it's a built-in, implicit type, but it still > feels inconsistent. > Thing is, there shouldn't be any useful free functions there, everything dealing with numerics should be coming from std::num or methods on the types. From pnkfelix at mozilla.com Thu Jul 11 04:30:58 2013 From: pnkfelix at mozilla.com (Felix S. Klock II) Date: Thu, 11 Jul 2013 13:30:58 +0200 Subject: [rust-dev] Incremental and generational GC In-Reply-To: <51DDBE36.3030500@mozilla.com> References: <51DDA8A8.9060707@mozilla.com> <51DDBE36.3030500@mozilla.com> Message-ID: <51DE9772.9070104@mozilla.com> On 10/07/2013 22:04, Graydon Hoare wrote: > On 13-07-10 11:32 AM, Patrick Walton wrote: > >> I've been thinking about what will be needed to support incremental and >> generational GC in Rust. To be clear, I don't think we should block on >> it now, but we should not make it unduly difficult for us to implement >> in the future. > I figured we'd be doing the incremental-generational variant of > mostly-copying (once we get mostly-copying working _at all_ -- we're a > long ways from there). Trap on @-writes to heap, mask to page bits, > compare generation numbers. With MMU or without, depending on environment. > > I assume you've read this: > > http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-91-8.pdf This is also relevant, I think (and more recent): Antony L. Hosking. 2006. Portable, mostly-concurrent, mostly-copying garbage collection for multi-processors. In /Proceedings of the 5th international symposium on Memory management/ (ISMM '06). ACM, New York, NY, USA, 40-51. DOI=10.1145/1133956.1133963 http://doi.acm.org/10.1145/1133956.1133963 http://dl.acm.org/citation.cfm?id=1133963 Cheers, -Felix (who has not yet caught up with the rest of the thread) -- irc: pnkfelix on irc.mozilla.org email: {fklock, pnkfelix}@mozilla.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From coder543 at gmail.com Thu Jul 11 04:40:33 2013 From: coder543 at gmail.com (Josh Leverette) Date: Thu, 11 Jul 2013 06:40:33 -0500 Subject: [rust-dev] Broken tutorial code? In-Reply-To: References: Message-ID: Ok. That makes sense... and is there a tutorial where I can learn my way around the module system? I was trying things like "use int" because I didn't realize I should say "use std::int" when "use std" is implied in every program by default. On Jul 11, 2013 6:29 AM, "Corey Richardson" wrote: > On Thu, Jul 11, 2013 at 7:24 AM, Josh Leverette > wrote: > > Does it really make sense for me to be able to use the type 'int' if I > > haven't declared the module for it? Or the opposite perspective, does it > > really make sense for me to not be able to use the functions in int's > module > > if I can use int? I understand it's a built-in, implicit type, but it > still > > feels inconsistent. > > > > Thing is, there shouldn't be any useful free functions there, > everything dealing with numerics should be coming from std::num or > methods on the types. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From pnkfelix at mozilla.com Thu Jul 11 05:29:56 2013 From: pnkfelix at mozilla.com (Felix S. Klock II) Date: Thu, 11 Jul 2013 14:29:56 +0200 Subject: [rust-dev] Incremental and generational GC In-Reply-To: <51DE9772.9070104@mozilla.com> References: <51DDA8A8.9060707@mozilla.com> <51DDBE36.3030500@mozilla.com> <51DE9772.9070104@mozilla.com> Message-ID: <51DEA544.4060308@mozilla.com> On 11/07/2013 13:30, Felix S. Klock II wrote: > On 10/07/2013 22:04, Graydon Hoare wrote: >> I assume you've read this: >> http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-91-8.pdf > This is also relevant, I think (and more recent): > > > Antony L. Hosking. 2006. Portable, mostly-concurrent, mostly-copying > garbage collection for multi-processors. In /Proceedings of the 5th > international symposium on Memory management/ (ISMM '06). ACM, New > York, NY, USA, 40-51. DOI=10.1145/1133956.1133963 > http://doi.acm.org/10.1145/1133956.1133963 > > http://dl.acm.org/citation.cfm?id=1133963 > Caveat: The latter paper that I cited is for a Modula-3 compiler/runtime (i.e., compiler support for the GC is definitely provided; in other words: "cooperative software environment"). The former paper that Graydon cited is for the explicitly uncooperative environment of C++; no hardware nor compiler support. I presume Rust falls somewhere between these two extremes, so both may be relevant. Cheers, -Felix, (still playing catchup) -- irc: pnkfelix on irc.mozilla.org email: {fklock,pnkfelix}@mozilla.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Thu Jul 11 05:32:03 2013 From: corey at octayn.net (Corey Richardson) Date: Thu, 11 Jul 2013 08:32:03 -0400 Subject: [rust-dev] Broken tutorial code? In-Reply-To: References: Message-ID: On Thu, Jul 11, 2013 at 7:40 AM, Josh Leverette wrote: > Ok. That makes sense... and is there a tutorial where I can learn my way > around the module system? I was trying things like "use int" because I > didn't realize I should say "use std::int" when "use std" is implied in > every program by default. > Not really, unfortunately. One is desparately needed. `use std` isn't actually implied, just `extern mod std` and `use std::prelude::*`. Furthermore, `use std` wouldn't bring the children of std into scope, that would be `use std::*`. > On Jul 11, 2013 6:29 AM, "Corey Richardson" wrote: >> >> On Thu, Jul 11, 2013 at 7:24 AM, Josh Leverette >> wrote: >> > Does it really make sense for me to be able to use the type 'int' if I >> > haven't declared the module for it? Or the opposite perspective, does it >> > really make sense for me to not be able to use the functions in int's >> > module >> > if I can use int? I understand it's a built-in, implicit type, but it >> > still >> > feels inconsistent. >> > >> >> Thing is, there shouldn't be any useful free functions there, >> everything dealing with numerics should be coming from std::num or >> methods on the types. From thadguidry at gmail.com Thu Jul 11 07:02:04 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Thu, 11 Jul 2013 09:02:04 -0500 Subject: [rust-dev] Incremental and generational GC In-Reply-To: <51DEA544.4060308@mozilla.com> References: <51DDA8A8.9060707@mozilla.com> <51DDBE36.3030500@mozilla.com> <51DE9772.9070104@mozilla.com> <51DEA544.4060308@mozilla.com> Message-ID: I do not know much about GC, but it seems that there are basic categories of GC needs (goals). One need that popped up in my reading is that concerning the difference between Pause times and how it affects Real Time needs: Stop the Word > .5 sec (typically) Incremental near >.4 ms Real-time < .4ms I found this PowerPoint to be interesting, just from a perspective of visualizing the problem space itself: http://www.research.ibm.com/metronome/talks/Bacon03RealtimeTalk.ppt and this one: http://www.cs.cmu.edu/~blelloch/papers/SBH05.pdf And in reading what others have found and what I found, it made me curious with some general questions to all (I have no idea what I'm talking about, but learning here): 1. Is it in everyone's experience that the main limiting factor in a GC is within the FFI and the limits of "when" objects can be relocated ? Is that the highest level need ? 2. Would one of the goals of Rust be eventually to have Real Time GC that could be used in say Real-time embedded systems, like in automobile core engine systems (where Java has a place now)? 3. I would love to see a summary of all the buzzwords that Rust's eventual goals of GC would be able to handle, and what the real goals will be...laid out, and the reasons for each of those goals. Do we have this type of summary yet floating around ? (thanks for schooling me in advance...lol) On Thu, Jul 11, 2013 at 7:29 AM, Felix S. Klock II wrote: > On 11/07/2013 13:30, Felix S. Klock II wrote: > > On 10/07/2013 22:04, Graydon Hoare wrote: > > I assume you've read this: > http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-91-8.pdf > > This is also relevant, I think (and more recent): > > > Antony L. Hosking. 2006. Portable, mostly-concurrent, mostly-copying > garbage collection for multi-processors. In *Proceedings of the 5th > international symposium on Memory management* (ISMM '06). ACM, New York, > NY, USA, 40-51. DOI=10.1145/1133956.1133963 > http://doi.acm.org/10.1145/1133956.1133963 > > http://dl.acm.org/citation.cfm?id=1133963 > > Caveat: The latter paper that I cited is for a Modula-3 compiler/runtime > (i.e., compiler support for the GC is definitely provided; in other words: > "cooperative software environment"). > > The former paper that Graydon cited is for the explicitly uncooperative > environment of C++; no hardware nor compiler support. > > I presume Rust falls somewhere between these two extremes, so both may be > relevant. > > Cheers, > -Felix, (still playing catchup) > > > -- > irc: pnkfelix on irc.mozilla.org > email: {fklock, pnkfelix}@mozilla.com > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -- -Thad Thad on Freebase.com Thad on LinkedIn -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Thu Jul 11 11:25:23 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Thu, 11 Jul 2013 11:25:23 -0700 Subject: [rust-dev] Incremental and generational GC In-Reply-To: <51DDA8A8.9060707@mozilla.com> References: <51DDA8A8.9060707@mozilla.com> Message-ID: <51DEF893.1030104@mozilla.com> OK, after talking with Felix and Niko (thanks!) here's a proposal. * Whenever we borrow an `@mut` to `&mut`, add it to a "borrowed set" for the duration of the borrow. * Objects in the borrowed set are grayed before each incremental GC slice. * Objects in the borrowed set are scanned during each minor collection, even if they're tenured. * When removing an object from the borrowed set (because the borrowed is done), add it to a remembered set. Objects in the remembered set are scanned during minor collections. * There are no other write barriers. I believe (although I haven't thought about it too hard) that this suffices to make generational and incremental GC work in Rust's mostly-copying setting. Patrick From niko at alum.mit.edu Thu Jul 11 12:12:45 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Thu, 11 Jul 2013 15:12:45 -0400 Subject: [rust-dev] Incremental and generational GC In-Reply-To: <51DEF893.1030104@mozilla.com> References: <51DDA8A8.9060707@mozilla.com> <51DEF893.1030104@mozilla.com> Message-ID: <20130711191245.GI26187@Mr-Bennet> Some comments inline (mostly for my own clarification). > * Whenever we borrow an `@mut` to `&mut`, add it to a "borrowed set" > for the duration of the borrow. Presuming we adopt `Cell` in place of `@mut`, then this changes to "when borrowing a Cell as mutable, check if the cell is located within managed memory and add the cell to the borrowed set". It is interesting to note that if we adopt `Cell`, then the borrowed and remembered sets need not be sets of managed boxes but rather can be sets of cells. The distinction is only that you don't have to scan the full object. It may be better to ignore this fact. > * Objects in the borrowed set are grayed before each incremental GC slice. The thesis that Graydon forwarded uses a different approach. If we adopted their approach, I think we would (1) immediately promote all pages reachable from stack and (2) promote any managed boxes as soon as they are borrowed (whether mutably or immutably). Promoting here means pinning the containing pages and then scanning their contents: any nursery objects found within would be copied into tenured pages and rewritten. This involves a read barrier, which seems undesirable. If we limit ourselves to write barriers, as you suggested, then what you wrote sounds about right. Presumably we still begin by pinning all pages reachable from the stack. We then do some work and eventually resume execution. When a cell in a block object is mutably borrowed, we pin its pages and mark it grey. Whenever we wish to resume scanning, we must re-scan the stack because the user may have borrowed white objects onto the stack and they must now be pinned. OK, that's a bit hand-wavy, but I think I can see how it could work. > * Objects in the borrowed set are scanned during each minor > collection, even if they're tenured. I wouldn't add a non-tenured object to the borrowed set. What's the point. > * When removing an object from the borrowed set (because the borrowed > is done), add it to a remembered set. Objects in the remembered set > are scanned during minor collections. You only need to add to the remembered set if the new value contains objects in the nursery. This amounts to eagerly scanning the cell rather than waiting until the minor collection. I'm not sure if it's worth it, but if you don't do it, there is no reason to distinguish the borrowed and remembered sets. > * There are no other write barriers. Right. > I believe (although I haven't thought about it too hard) that this > suffices to make generational and incremental GC work in Rust's > mostly-copying setting. Agreed. Niko From steve at steveklabnik.com Thu Jul 11 12:16:44 2013 From: steve at steveklabnik.com (Steve Klabnik) Date: Thu, 11 Jul 2013 15:16:44 -0400 Subject: [rust-dev] Broken tutorial code? In-Reply-To: References: Message-ID: I've been slowly trying to fill out the headers to each of the modules, so at least you know what's in them all. From thadguidry at gmail.com Thu Jul 11 12:28:27 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Thu, 11 Jul 2013 14:28:27 -0500 Subject: [rust-dev] Incremental and generational GC In-Reply-To: <20130711191245.GI26187@Mr-Bennet> References: <51DDA8A8.9060707@mozilla.com> <51DEF893.1030104@mozilla.com> <20130711191245.GI26187@Mr-Bennet> Message-ID: > * Objects in the borrowed set are grayed before each incremental GC slice. > *mutator* In a garbage-collected system, the part that executes the user code, which allocates objects and modifies, or *mutates*, them. For purposes of describing incremental garbage collection, the system is divided into the *mutator* and the *collector(2) *. These can be separate threads of computation, or interleaved within the same thread. The user code issues allocation requests, but the allocator code is usually considered part of the collector. Indeed, one of the major ways of scheduling the other work of the collector is to perform a little of it at every allocation. While the mutator mutates, it implicitly frees storage by overwriting references . How will Rust deal with the mutator (the part that modifies user code and mutates it ) ? From a high level, will it be run as separate computation threads or within the same computation thread ? -- -Thad Thad on Freebase.com Thad on LinkedIn -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Thu Jul 11 14:48:30 2013 From: corey at octayn.net (Corey Richardson) Date: Thu, 11 Jul 2013 17:48:30 -0400 Subject: [rust-dev] Another rustdoc_ng call for help Message-ID: I'm stuck again (surprise!) this time resolving external modules. Testcase and log: https://gist.github.com/cmr/e396e61f936dd36dd5ba, code: https://github.com/cmr/rustdoc_ng/tree/wip. I cannot see where I am diverging from rustc behavior-wise (in the get_ast_and_resolve function), but clearly I am doing *something* wrong. From pnkfelix at mozilla.com Thu Jul 11 16:00:47 2013 From: pnkfelix at mozilla.com (Felix Klock) Date: Thu, 11 Jul 2013 16:00:47 -0700 (PDT) Subject: [rust-dev] Incremental and generational GC In-Reply-To: <20130711191245.GI26187@Mr-Bennet> References: <51DDA8A8.9060707@mozilla.com> <51DEF893.1030104@mozilla.com> <20130711191245.GI26187@Mr-Bennet> Message-ID: <1205370641.784045.1373583647311.JavaMail.zimbra@mozilla.com> Niko (cc'ing Patrick and rust-dev; resending from correct account)- > > * Objects in the borrowed set are scanned during each minor > > collection, even if they're tenured. > > I wouldn't add a non-tenured object to the borrowed set. What's the > point. What if (1.) the borrowed-object is in the nursery at the time of the borrow, and (2.) then is tenured during a minor gc that occurs during the dynamic extent of the borrow, and (3.) there are more writes to the newly tenured object during the dynamic extent of the borrow? Or in (rough) code: let cell : &Cell = ...; // cell is young and in the nursery let ref : &T = cell.as_mut(); // cell is still in the nursery ... // cell is tenured into the older generation, and has no refs into nursery ... // (i.e. its referents in nursery are also tenured here), so cell is not ... // added to remembered-set nor borrowed-set. ... *ref = new_infant(); // now cell is in tenured space and has a ref to infant in nursery; ... // but there is no meta-data telling GC to scan cell at next GC... ... // Nothing keeping baby alive. ... compute(*ref); // Boom! Cheers, -Felix ----- Original Message ----- From: "Niko Matsakis" To: "Patrick Walton" Cc: rust-dev at mozilla.org Sent: Thursday, July 11, 2013 9:12:45 PM Subject: Re: [rust-dev] Incremental and generational GC Some comments inline (mostly for my own clarification). > * Whenever we borrow an `@mut` to `&mut`, add it to a "borrowed set" > for the duration of the borrow. Presuming we adopt `Cell` in place of `@mut`, then this changes to "when borrowing a Cell as mutable, check if the cell is located within managed memory and add the cell to the borrowed set". It is interesting to note that if we adopt `Cell`, then the borrowed and remembered sets need not be sets of managed boxes but rather can be sets of cells. The distinction is only that you don't have to scan the full object. It may be better to ignore this fact. > * Objects in the borrowed set are grayed before each incremental GC slice. The thesis that Graydon forwarded uses a different approach. If we adopted their approach, I think we would (1) immediately promote all pages reachable from stack and (2) promote any managed boxes as soon as they are borrowed (whether mutably or immutably). Promoting here means pinning the containing pages and then scanning their contents: any nursery objects found within would be copied into tenured pages and rewritten. This involves a read barrier, which seems undesirable. If we limit ourselves to write barriers, as you suggested, then what you wrote sounds about right. Presumably we still begin by pinning all pages reachable from the stack. We then do some work and eventually resume execution. When a cell in a block object is mutably borrowed, we pin its pages and mark it grey. Whenever we wish to resume scanning, we must re-scan the stack because the user may have borrowed white objects onto the stack and they must now be pinned. OK, that's a bit hand-wavy, but I think I can see how it could work. > * Objects in the borrowed set are scanned during each minor > collection, even if they're tenured. I wouldn't add a non-tenured object to the borrowed set. What's the point. > * When removing an object from the borrowed set (because the borrowed > is done), add it to a remembered set. Objects in the remembered set > are scanned during minor collections. You only need to add to the remembered set if the new value contains objects in the nursery. This amounts to eagerly scanning the cell rather than waiting until the minor collection. I'm not sure if it's worth it, but if you don't do it, there is no reason to distinguish the borrowed and remembered sets. > * There are no other write barriers. Right. > I believe (although I haven't thought about it too hard) that this > suffices to make generational and incremental GC work in Rust's > mostly-copying setting. Agreed. Niko _______________________________________________ Rust-dev mailing list Rust-dev at mozilla.org https://mail.mozilla.org/listinfo/rust-dev From niko at alum.mit.edu Thu Jul 11 18:02:08 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Thu, 11 Jul 2013 21:02:08 -0400 Subject: [rust-dev] Incremental and generational GC In-Reply-To: <1205370641.784045.1373583647311.JavaMail.zimbra@mozilla.com> References: <51DDA8A8.9060707@mozilla.com> <51DEF893.1030104@mozilla.com> <20130711191245.GI26187@Mr-Bennet> <1205370641.784045.1373583647311.JavaMail.zimbra@mozilla.com> Message-ID: <20130712010208.GQ26187@Mr-Bennet> That's a good point, I hadn't considered the possibility that something could become tenured during the borrow. Niko On Thu, Jul 11, 2013 at 04:00:47PM -0700, Felix Klock wrote: > Niko (cc'ing Patrick and rust-dev; resending from correct account)- > > > > * Objects in the borrowed set are scanned during each minor > > > collection, even if they're tenured. > > > > I wouldn't add a non-tenured object to the borrowed set. What's the > > point. > > What if (1.) the borrowed-object is in the nursery at the time of the borrow, and (2.) then is tenured during a minor gc that occurs during the dynamic extent of the borrow, and (3.) there are more writes to the newly tenured object during the dynamic extent of the borrow? > > Or in (rough) code: > > let cell : &Cell = ...; // cell is young and in the nursery > let ref : &T = cell.as_mut(); // cell is still in the nursery > ... > // cell is tenured into the older generation, and has no refs into nursery > ... // (i.e. its referents in nursery are also tenured here), so cell is not > ... // added to remembered-set nor borrowed-set. > ... > *ref = new_infant(); // now cell is in tenured space and has a ref to infant in nursery; > ... // but there is no meta-data telling GC to scan cell at next GC... > ... > // Nothing keeping baby alive. > ... > compute(*ref); // Boom! > > Cheers, > -Felix > > > > > ----- Original Message ----- > From: "Niko Matsakis" > To: "Patrick Walton" > Cc: rust-dev at mozilla.org > Sent: Thursday, July 11, 2013 9:12:45 PM > Subject: Re: [rust-dev] Incremental and generational GC > > Some comments inline (mostly for my own clarification). > > > * Whenever we borrow an `@mut` to `&mut`, add it to a "borrowed set" > > for the duration of the borrow. > > Presuming we adopt `Cell` in place of `@mut`, then this changes to > "when borrowing a Cell as mutable, check if the cell is located within > managed memory and add the cell to the borrowed set". > > It is interesting to note that if we adopt `Cell`, then the borrowed > and remembered sets need not be sets of managed boxes but rather can > be sets of cells. The distinction is only that you don't have to scan > the full object. It may be better to ignore this fact. > > > * Objects in the borrowed set are grayed before each incremental GC slice. > > The thesis that Graydon forwarded uses a different approach. If we > adopted their approach, I think we would (1) immediately promote all > pages reachable from stack and (2) promote any managed boxes as soon > as they are borrowed (whether mutably or immutably). Promoting here > means pinning the containing pages and then scanning their contents: > any nursery objects found within would be copied into tenured pages > and rewritten. This involves a read barrier, which seems undesirable. > > If we limit ourselves to write barriers, as you suggested, then what > you wrote sounds about right. Presumably we still begin by pinning all > pages reachable from the stack. We then do some work and eventually > resume execution. When a cell in a block object is mutably borrowed, > we pin its pages and mark it grey. Whenever we wish to resume > scanning, we must re-scan the stack because the user may have borrowed > white objects onto the stack and they must now be pinned. > > OK, that's a bit hand-wavy, but I think I can see how it could work. > > > * Objects in the borrowed set are scanned during each minor > > collection, even if they're tenured. > > I wouldn't add a non-tenured object to the borrowed set. What's the > point. > > > * When removing an object from the borrowed set (because the borrowed > > is done), add it to a remembered set. Objects in the remembered set > > are scanned during minor collections. > > You only need to add to the remembered set if the new value contains > objects in the nursery. This amounts to eagerly scanning the cell > rather than waiting until the minor collection. I'm not sure if it's > worth it, but if you don't do it, there is no reason to distinguish > the borrowed and remembered sets. > > > * There are no other write barriers. > > Right. > > > I believe (although I haven't thought about it too hard) that this > > suffices to make generational and incremental GC work in Rust's > > mostly-copying setting. > > Agreed. > > > Niko > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From pnkfelix at mozilla.com Fri Jul 12 00:32:12 2013 From: pnkfelix at mozilla.com (Felix Klock) Date: Fri, 12 Jul 2013 00:32:12 -0700 (PDT) Subject: [rust-dev] Incremental and generational GC In-Reply-To: References: <51DDA8A8.9060707@mozilla.com> <51DEF893.1030104@mozilla.com> <20130711191245.GI26187@Mr-Bennet> Message-ID: <59303.814740.1373614332795.JavaMail.zimbra@mozilla.com> Thad (cc'ing rust-dev)- > How will Rust deal with the mutator (the part that modifies user code and > mutates it ) ? From a high level, will it be run as separate computation > threads or within the same computation thread ? The current goal is for the mutator and GC to be coroutines on the same computation thread. I do not know if we'll eventually try for concurrent GC; I'm not convinced it would pay for itself in the context of Rust, in the sense of providing significant benefit over a good incremental GC coroutine on each task. A conversation with thiez on IRC [1] made me realize that the terminology here can be confusing; in particular, the write-barriers under discussion are not memory barrier intrinsics (aka memory fences) [2]. These are rather software write-barriers, for maintaining thread-local GC meta-data. Cheers, -Felix [1] https://botbot.me/mozilla/rust/msg/4437567/ [2] http://en.wikipedia.org/wiki/Memory_barrier ----- Original Message ----- From: "Thad Guidry" To: "Niko Matsakis" Cc: rust-dev at mozilla.org, "Patrick Walton" Sent: Thursday, July 11, 2013 9:28:27 PM Subject: Re: [rust-dev] Incremental and generational GC > * Objects in the borrowed set are grayed before each incremental GC slice. mutator In a garbage-collected system, the part that executes the user code, which allocates objects and modifies, or mutates , them. For purposes of describing incremental garbage collection , the system is divided into the mutator and the collector (2) . These can be separate threads of computation, or interleaved within the same thread. The user code issues allocation requests, but the allocator code is usually considered part of the collector. Indeed, one of the major ways of scheduling the other work of the collector is to perform a little of it at every allocation. While the mutator mutates, it implicitly frees storage by overwriting references . How will Rust deal with the mutator (the part that modifies user code and mutates it ) ? From a high level, will it be run as separate computation threads or within the same computation thread ? -- -Thad Thad on Freebase.com Thad on LinkedIn _______________________________________________ Rust-dev mailing list Rust-dev at mozilla.org https://mail.mozilla.org/listinfo/rust-dev From bklooste at gmail.com Fri Jul 12 01:33:55 2013 From: bklooste at gmail.com (Bennie Kloosteman) Date: Fri, 12 Jul 2013 16:33:55 +0800 Subject: [rust-dev] Incremental and generational GC In-Reply-To: <51DEF893.1030104@mozilla.com> References: <51DDA8A8.9060707@mozilla.com> <51DEF893.1030104@mozilla.com> Message-ID: No cardtable ? Most generational GCs use a write barrier to mark pages accessed that way only objects in accessed pages need to be checked for higher to lower generation references http://blogs.msdn.com/b/abhinaba/archive/2009/03/02/back-to-basics-generational-garbage-collection.aspx Java does the same. Thad there are ways of massively reducing stop the world , basically by using threads and having safe points .. but those GCs are a huge task to write . For advanced GCs the stop the world is for the stack scan. Its worth noted multi threaded marks can significantly reduce GC times which can matter eg 50-100ms you may not notice but 200-400ms you will.. On Fri, Jul 12, 2013 at 2:25 AM, Patrick Walton wrote: > OK, after talking with Felix and Niko (thanks!) here's a proposal. > > * Whenever we borrow an `@mut` to `&mut`, add it to a "borrowed set" for > the duration of the borrow. > > * Objects in the borrowed set are grayed before each incremental GC slice. > > * Objects in the borrowed set are scanned during each minor collection, > even if they're tenured. > > * When removing an object from the borrowed set (because the borrowed is > done), add it to a remembered set. Objects in the remembered set are > scanned during minor collections. > > * There are no other write barriers. > > I believe (although I haven't thought about it too hard) that this > suffices to make generational and incremental GC work in Rust's > mostly-copying setting. > > Patrick > > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From niko at alum.mit.edu Fri Jul 12 06:02:25 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Fri, 12 Jul 2013 09:02:25 -0400 Subject: [rust-dev] Incremental and generational GC In-Reply-To: References: <51DDA8A8.9060707@mozilla.com> <51DEF893.1030104@mozilla.com> Message-ID: <20130712130225.GR26187@Mr-Bennet> The descriptions we've been using are quite abstract but I assume we'll use a card table or similar abstraction. "Adding to the remembered set" or "borrowed set" probably means, in practice, flagging the relevant card. Niko On Fri, Jul 12, 2013 at 04:33:55PM +0800, Bennie Kloosteman wrote: > No cardtable ? Most generational GCs use a write barrier to mark pages > accessed that way only objects in accessed pages need to be checked for > higher to lower generation references > > http://blogs.msdn.com/b/abhinaba/archive/2009/03/02/back-to-basics-generational-garbage-collection.aspx > > Java does the same. > > Thad there are ways of massively reducing stop the world , basically by > using threads and having safe points .. but those GCs are a huge task to > write . For advanced GCs the stop the world is for the stack scan. > > Its worth noted multi threaded marks can significantly reduce GC times > which can matter eg 50-100ms you may not notice but 200-400ms you will.. > > > On Fri, Jul 12, 2013 at 2:25 AM, Patrick Walton wrote: > > > OK, after talking with Felix and Niko (thanks!) here's a proposal. > > > > * Whenever we borrow an `@mut` to `&mut`, add it to a "borrowed set" for > > the duration of the borrow. > > > > * Objects in the borrowed set are grayed before each incremental GC slice. > > > > * Objects in the borrowed set are scanned during each minor collection, > > even if they're tenured. > > > > * When removing an object from the borrowed set (because the borrowed is > > done), add it to a remembered set. Objects in the remembered set are > > scanned during minor collections. > > > > * There are no other write barriers. > > > > I believe (although I haven't thought about it too hard) that this > > suffices to make generational and incremental GC work in Rust's > > mostly-copying setting. > > > > Patrick > > > > > > ______________________________**_________________ > > Rust-dev mailing list > > Rust-dev at mozilla.org > > https://mail.mozilla.org/**listinfo/rust-dev > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From kballard at gmail.com Fri Jul 12 19:27:22 2013 From: kballard at gmail.com (Kevin Ballard) Date: Fri, 12 Jul 2013 19:27:22 -0700 Subject: [rust-dev] Where did unicode go? In-Reply-To: References: Message-ID: It's still there, but it is no longer public. I'm surprised you didn't get an error sooner than link time. On Tue, Jul 9, 2013 at 3:45 AM, Corey Richardson wrote: > On Tue, Jul 9, 2013 at 5:21 AM, Fredrik H??rd wrote: >> I'm trying to migrate to 0.7, and failing - I was using >> unicode::general_category::Cc, but since updating I cannot seem to >> find it in the docs (may very well be user error), and linking fails. >> >> Any hint's on what I should do instead? >> >> The offending code is >> >> if unicode::general_category::Cc(astr.char_at(0)) { >> ... >> } >> >> And the output from rustc: >> -------------- >> >> [snip] > > That's quite odd. The function is still there, but rustc should never > generate a failure in the linker like that for "pure" Rust code. > "Undefined symbols for architecture x86_64" makes me think you might > have 32-bit libraries installed? > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From michaelwoerister at gmail.com Sat Jul 13 07:27:46 2013 From: michaelwoerister at gmail.com (Michael Woerister) Date: Sat, 13 Jul 2013 16:27:46 +0200 Subject: [rust-dev] Removing codemap::spanned Message-ID: <51E163E2.70507@gmail.com> Hi everyone, I want to help clean up the Rust codebase and one thing I stumbled across a few times in the last weeks is the 'spanned' generic struct from libsyntax::codemap: pub struct spanned { node: T, span: span } It is used quite often to conveniently add a span field to types in libsyntax::ast following a common pattern: pub type crate = spanned; #[deriving(Eq, Encodable, Decodable)] pub struct crate_ { module: _mod, attrs: ~[attribute], config: crate_cfg, } This may be convenient for the creator of these types---for the user, however, it often adds a bit of cumbersome indirection because the fields of the type have to be accessed like this: "crate.node.attrs" when it would be more intuitive to just write "crate.attrs". One can work around this of course, but especially for newcomers this setup can be a little confusing. So, I thought it might be a good idea if I tried to remove the spanned struct altogether and added the span field directly to the types that are wrapped at the moment. If needed, I would also add a Spanned trait that allows to abstract over anything having a span. Because this would affect quite a bit of the codebase (albeit not semantically) I thought, I'd better ask beforehand if you people think this is a good idea. Or maybe I am missing a reason for keeping the spanned struct around? Thanks for reading, Michael From clements at brinckerhoff.org Sat Jul 13 09:23:56 2013 From: clements at brinckerhoff.org (John Clements) Date: Sat, 13 Jul 2013 09:23:56 -0700 Subject: [rust-dev] Removing codemap::spanned In-Reply-To: <51E163E2.70507@gmail.com> References: <51E163E2.70507@gmail.com> Message-ID: <9C4997E7-C641-47E9-A329-AE8B6F1001B4@brinckerhoff.org> On Jul 13, 2013, at 7:27 AM, Michael Woerister wrote: > Hi everyone, > I want to help clean up the Rust codebase and one thing I stumbled across a few times in the last weeks is the 'spanned' generic struct from libsyntax::codemap: > > pub struct spanned { node: T, span: span } > > It is used quite often to conveniently add a span field to types in libsyntax::ast following a common pattern: > > pub type crate = spanned; > > #[deriving(Eq, Encodable, Decodable)] > pub struct crate_ { > module: _mod, > attrs: ~[attribute], > config: crate_cfg, > } > > This may be convenient for the creator of these types---for the user, however, it often adds a bit of cumbersome indirection because the fields of the type have to be accessed like this: "crate.node.attrs" when it would be more intuitive to just write "crate.attrs". One can work around this of course, but especially for newcomers this setup can be a little confusing. > > So, I thought it might be a good idea if I tried to remove the spanned struct altogether and added the span field directly to the types that are wrapped at the moment. If needed, I would also add a Spanned trait that allows to abstract over anything having a span. > Because this would affect quite a bit of the codebase (albeit not semantically) I thought, I'd better ask beforehand if you people think this is a good idea. Or maybe I am missing a reason for keeping the spanned struct around? I don't want to put words in peoples' mouths, but I think I've heard people suggesting that we just use a side table for this. Do we have tables with weakly held keys? John From pwalton at mozilla.com Sat Jul 13 09:25:37 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Sat, 13 Jul 2013 09:25:37 -0700 Subject: [rust-dev] Removing codemap::spanned In-Reply-To: <51E163E2.70507@gmail.com> References: <51E163E2.70507@gmail.com> Message-ID: <51E17F81.1040502@mozilla.com> On 7/13/13 7:27 AM, Michael Woerister wrote: > So, I thought it might be a good idea if I tried to remove the > spanned struct altogether and added the span field directly to the > types that are wrapped at the moment. If needed, I would also add a > Spanned trait that allows to abstract over anything having a span. > Because this would affect quite a bit of the codebase (albeit not > semantically) I thought, I'd better ask beforehand if you people think > this is a good idea. Or maybe I am missing a reason for keeping the > spanned struct around? I might prefer to just use a compressed side table for memory usage reasons. Can we measure how much space the spans are taking up in the AST? Patrick From kballard at gmail.com Sat Jul 13 13:19:51 2013 From: kballard at gmail.com (Kevin Ballard) Date: Sat, 13 Jul 2013 13:19:51 -0700 Subject: [rust-dev] Test suite uses too many open fds Message-ID: Last night I tracked down why `make check-stage2-std` no longer works on my computer. This is documented in issue https://github.com/mozilla/rust/issues/7772. In summary, the test runner now uses num_cpus*2 threads instead of 4 threads, which ends up being 16 on my machine, and this causes the process to run out of fds. Why is the test suite using so many fds? lsof says most of them are PIPEs. What are those being used for? -Kevin From corey at octayn.net Sat Jul 13 14:51:56 2013 From: corey at octayn.net (Corey Richardson) Date: Sat, 13 Jul 2013 17:51:56 -0400 Subject: [rust-dev] This Week in Rust Message-ID: Content copied from http://cmr.github.io/blog/2013/07/13/this-week-in-rust/ -- Hello and welcome to the sixth issue of *This Week in Rust*, a weekly overview of Rust and its community. # What's cooking on master? Issue churn this week was -17! A total of 63 PRs were merged this week, twice as many as last week. Not bad! ## Breaking changes - The [task local storage (TLS) API](https://github.com/mozilla/rust/pull/7677) was cleaned up (there's still [one PR](https://github.com/mozilla/rust/pull/7751) in the queue that finishes it up). - [DList was modernized](https://github.com/mozilla/rust/pull/7652). - [`extra::json` now uses `Iterator` rather than a `@Reader`](https://github.com/mozilla/rust/pull/7704) - [Various free-standing functions in f32 etc were removed](https://github.com/mozilla/rust/pull/7117) - [ref bindings in irrefutable patterns has been tightened up](https://github.com/mozilla/rust/pull/7262). This potentially fixes *and breaks* code. It's breaking because the compiler now rejects incorrect programs that it did not before. - [str no longer encodes invalid utf-8](https://github.com/mozilla/rust/pull/7612). - [`extra::rope` was removed](https://github.com/mozilla/rust/pull/7629) - [`extra::net_ip` and so on were removed](https://github.com/mozilla/rust/pull/7594). They were redundant names for `extra::net::ip` and such - [`Iterator::size_hint`'s lower bound is no longer an Option](https://github.com/mozilla/rust/pull/7570) ## Notable compiler additions, bugfixes, and cleanup - [Unnecessary basic blocks were removed](https://github.com/mozilla/rust/pull/7763). This makes for much easier to read unoptimized IR. - [Use of `*int`/`*uint` is now properly warned](https://github.com/mozilla/rust/pull/7734) in FFI functions. - [More default method fixes](https://github.com/mozilla/rust/pull/7725). - A [needless copy](https://github.com/mozilla/rust/pull/7717) was removed from immediate values (I'm pretty sure LLVM optimized it away when optimizations were on, not positive). - A [lint for overqualified names](https://github.com/mozilla/rust/pull/7706) was added. - [SIMD arithmetic](https://github.com/mozilla/rust/pull/7705) was implemented. - A [graph abstraction and CFG](https://github.com/mozilla/rust/pull/7688) was introduced, to unify how the various pieces of the compiler use graphs. - [The maximum lifetime of stack closures](https://github.com/mozilla/rust/pull/7455) is now constrained. Not quite sure what that means, but it fixes a segfault. - [repr doesn't infinite loop](https://github.com/mozilla/rust/pull/7683) on zero-sized structs (ie, unit structs). - [Type parameter pretty printing](https://github.com/mozilla/rust/pull/7698) was fixed, it now prints the type name rather than `'a` and `'b` and soforth. - [`mut` in default method arguments is now allowed](https://github.com/mozilla/rust/pull/7631). - [IR for calls with immediate return values](https://github.com/mozilla/rust/pull/7645) was improved. - [Exchange allocation headers (ie, the headers on `~T`) were removed](https://github.com/mozilla/rust/pull/7605). This was a heroic effort by strcat and Luqman. - [`-Z trans-stats` now reports perf-function statistics](https://github.com/mozilla/rust/pull/7456) - [Scopes were decoupled from LLVM basic blocks](https://github.com/mozilla/rust/pull/7636), improving unoptimized builds, and allowing more things in optimized builds to be inlined. - [An infinite loop when recursively including modules](https://github.com/mozilla/rust/pull/7585) was fixed. - An [ICE involving struct-like enum variants](https://github.com/mozilla/rust/pull/7557) was fixed. - The buildsystem [cleans up old libraries](https://github.com/mozilla/rust/pull/7637) when it needs to. - [A bunch of managed boxes](https://github.com/mozilla/rust/pull/7615) were removed from the AST. ## Notable library additions, bugfixes, and cleanup - [`print!` and `println!` macros](https://github.com/mozilla/rust/pull/7775) were added (though [#7779](https://github.com/mozilla/rust/issues/7779) renames them). - [Ord now uses default methods](https://github.com/mozilla/rust/pull/7765), allowing you to get default implementations for everything but `lt`. - [`extra::Bitv` now takes `&[bool]` rather than `~[uint]`](https://github.com/mozilla/rust/pull/7730). - [x64 now uses large stacks (4 MiB) by default](https://github.com/mozilla/rust/pull/7728). - [`is_utf8` is now 22% faster](https://github.com/mozilla/rust/pull/7696) - [Metrics reporting and ratcheting](https://github.com/mozilla/rust/pull/7623) was added to the test harness. - A [DoubleEndedIterator](https://github.com/mozilla/rust/pull/7707) was added. - A [`mut_split` method was added](https://github.com/mozilla/rust/pull/7691) to partition a `&mut [T]` into two pieces. - We [now have pointer arithmetic](https://github.com/mozilla/rust/pull/7631). - A [month's work of runtime work](https://github.com/mozilla/rust/pull/7265) landed. - [A safe, cross-platform `mmap` wrapper](https://github.com/mozilla/rust/pull/7528) was added. - [SmallIntMap and SmallIntSet have external iterators](https://github.com/mozilla/rust/pull/7614). - [JSON parsing got 93% faster](https://github.com/mozilla/rust/pull/7608) - [Deque](https://github.com/mozilla/rust/pull/7562) got a good cleanup and speedup. - [vec now implements `pop_opt` and `shift_opt` methods](https://github.com/mozilla/rust/pull/7602). - A [`peek_` adaptor](https://github.com/mozilla/rust/pull/7604) was added, which calls a closure on ever item before returning it. Mostly useful for debugging your iterators. ## Documentation etc - [vim](https://github.com/mozilla/rust/pull/7742) [improvements](https://github.com/mozilla/rust/pull/7665) landed. - [`po4a` support for translation](https://github.com/mozilla/rust/pull/7641) was added. - [`libc::c_void` is better documented](https://github.com/mozilla/rust/pull/7690). - [Man pages](https://github.com/mozilla/rust/pull/7632) for all the tools are now included. - The [iterator tutorial](https://github.com/mozilla/rust/pull/7736) was extended. # Meetings The [Tuesday meeting](https://github.com/mozilla/rust/wiki/Meeting-weekly-2013-07-09) was all about split stacks and FFI. It's complex and above my ability to summarize, but from what I can tell no real consensus was made. But, it's the best enumeration of all the various issues surrounding split stacks that I've seen. # Discussion + Blog posts >From now on I'm going to just link to the reddit thread if there is one, as it often has additional comments or insights. - [A simple, self-contained example of using a shared library](https://gist.github.com/jmptable/5980297) - [Experimental Actor Library (reddit)](http://www.reddit.com/r/rust/comments/1i3c15/experimental_actor_library_in_rust/) - [Herb Sutter describes Rust (reddit)](http://www.reddit.com/r/rust/comments/1i30sw/herb_sutter_describes_rust_c_questions_and/) - [Philosophy and "for" loops (reddit)](http://www.reddit.com/r/rust/comments/1i2y9e/philosophy_and_for_loops_more_from_go_and_rust/) - [Reddit thread about the weekly meeting](http://www.reddit.com/r/rust/comments/1hy6l9/meetingweekly20130709_split_stacks_ffi/) - [BZIP2 bindings (reddit)](http://www.reddit.com/r/rust/comments/1hxp2s/little_bzip2_binding_library_as_well_as_a_bigger/) - [Proposal for an additional use case of the "in" keyword besides for loops (reddit)](http://www.reddit.com/r/rust/comments/1hsqf5/proposal_for_an_additional_use_case_of_the_in/) - [Technical Q&A on Servo (reddit)](http://www.reddit.com/r/rust/comments/1i6ykh/technical_qa_on_servo/) From fredrik at haard.se Sat Jul 13 14:54:59 2013 From: fredrik at haard.se (=?UTF-8?B?RnJlZHJpayBIw6XDpXJk?=) Date: Sat, 13 Jul 2013 23:54:59 +0200 Subject: [rust-dev] Where did unicode go? In-Reply-To: References: Message-ID: Hm, ok. What is the reason it's not public anymore, and is there another way to access the same functionality? > > 2013/7/13 Kevin Ballard : > > It's still there, but it is no longer public. I'm surprised you didn't > > get an error sooner than link time. > > > > On Tue, Jul 9, 2013 at 3:45 AM, Corey Richardson wrote: > >> On Tue, Jul 9, 2013 at 5:21 AM, Fredrik H??rd wrote: > >>> I'm trying to migrate to 0.7, and failing - I was using > >>> unicode::general_category::Cc, but since updating I cannot seem to > >>> find it in the docs (may very well be user error), and linking fails. > >>> > >>> Any hint's on what I should do instead? > >>> > >>> The offending code is > >>> > >>> if unicode::general_category::Cc(astr.char_at(0)) { > >>> ... > >>> } > >>> > >>> And the output from rustc: > >>> -------------- > >>> > >>> [snip] > >> > >> That's quite odd. The function is still there, but rustc should never > >> generate a failure in the linker like that for "pure" Rust code. > >> "Undefined symbols for architecture x86_64" makes me think you might > >> have 32-bit libraries installed? > >> _______________________________________________ > >> Rust-dev mailing list > >> Rust-dev at mozilla.org > >> https://mail.mozilla.org/listinfo/rust-dev > > > > -- > /f > > I reject your reality and substitute my own. > http://courteous.ly/yp3Zgd -------------- next part -------------- An HTML attachment was scrubbed... URL: From jack at metajack.im Sat Jul 13 19:39:52 2013 From: jack at metajack.im (Jack Moffitt) Date: Sat, 13 Jul 2013 20:39:52 -0600 Subject: [rust-dev] bikeshedding println() and friends Message-ID: I saw https://github.com/mozilla/rust/pull/7779 come up today and commented on it. I got to thinking about it some, and since the bug doesn't seem the right place for such discussion, I wanted to bring it up here. The PR proposes to rename print!() and println!() to printf!() and printfln!(). The original macros exist to replace uses of print() and println() that look like: println(fmt!("blah blah %s", s)); Having a good default way to print things is very important, and it's one of the first things people will see of the language. I think it's worth bikeshedding it a bit to see if we can't come up with something better than the status quo. I propose instead: 1) Do away with the formatting stuff as the default. print!() and println!() should just take a variable number of arguments, and each one should be printed in its default string representation with a space between each one. This is how Clojure's (and Python's?) print and println work. This would change code like this: println!("The result is %f", foo); to this: println!("The result is", foo) It's much easier. There are no formatting codes to remember and it does exaclty what you want in most cases. Consider: println!(a, ,b, c, "d=", d); This seems great for the standard printf-style debugging. If formatting is needed, it's easy to get to: println!("My name is", name, "and I scored", fmt!("%0.2f", score)); 2) Since println!() is likely to be used the most often, I feel like it should have a shorter name. Ie, we should call it just print!(), and have a newline-less version with a different name, or perhaps a different style of invocation of the macro. As some data to ponder, I went through the Servo code and all its dependencies: - The dependencies of servo use println 42 times, 24 of which also use fmt!(). None of these need to use fmt!() at all, they could just use the default string representation. - Servo itself uses println about 10 times, only two of which need fmt!(). These two uses are both fancy formatted output for the profiler. Changing all these uses to print!() in the codebase (aside from the two profiler fmt!()s) would make things much nicer looking. jack. From pwalton at mozilla.com Sat Jul 13 20:08:23 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Sat, 13 Jul 2013 20:08:23 -0700 Subject: [rust-dev] bikeshedding println() and friends In-Reply-To: References: Message-ID: <1201ca6d-8464-4c0c-804c-5765b353e9c5@email.android.com> Keep in mind that fmt!'s interface is misdesigned at the moment: with the current interface the result is allocated on the heap even when the output is destined for a file or the screen. This is one of the bugs that resulted in poor performance (an order of magnitude slower than Python) on Chris Leary's benchmark. Fixing this will probably require having something like writefln or printfln. Jack Moffitt wrote: >I saw https://github.com/mozilla/rust/pull/7779 come up today and >commented on it. I got to thinking about it some, and since the bug >doesn't seem the right place for such discussion, I wanted to bring it >up here. > >The PR proposes to rename print!() and println!() to printf!() and >printfln!(). The original macros exist to replace uses of print() and >println() that look like: println(fmt!("blah blah %s", s)); > >Having a good default way to print things is very important, and it's >one of the first things people will see of the language. I think it's >worth bikeshedding it a bit to see if we can't come up with something >better than the status quo. > >I propose instead: > >1) Do away with the formatting stuff as the default. print!() and >println!() should just take a variable number of arguments, and each >one should be printed in its default string representation with a >space between each one. This is how Clojure's (and Python's?) print >and println work. > >This would change code like this: println!("The result is %f", foo); >to this: println!("The result is", foo) > >It's much easier. There are no formatting codes to remember and it >does exaclty what you want in most cases. Consider: println!(a, ,b, c, >"d=", d); This seems great for the standard printf-style debugging. > >If formatting is needed, it's easy to get to: >println!("My name is", name, "and I scored", fmt!("%0.2f", score)); > >2) Since println!() is likely to be used the most often, I feel like >it should have a shorter name. Ie, we should call it just print!(), >and have a newline-less version with a different name, or perhaps a >different style of invocation of the macro. > > >As some data to ponder, I went through the Servo code and all its >dependencies: > >- The dependencies of servo use println 42 times, 24 of which also use >fmt!(). None of these need to use fmt!() at all, they could just use >the default string representation. > >- Servo itself uses println about 10 times, only two of which need >fmt!(). These two uses are both fancy formatted output for the >profiler. > >Changing all these uses to print!() in the codebase (aside from the >two profiler fmt!()s) would make things much nicer looking. > >jack. >_______________________________________________ >Rust-dev mailing list >Rust-dev at mozilla.org >https://mail.mozilla.org/listinfo/rust-dev -- Sent from my Android phone with K-9 Mail. Please excuse my brevity. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bjzaba at yahoo.com.au Sat Jul 13 22:51:25 2013 From: bjzaba at yahoo.com.au (Brendan Zabarauskas) Date: Sun, 14 Jul 2013 15:51:25 +1000 Subject: [rust-dev] bikeshedding println() and friends In-Reply-To: <1201ca6d-8464-4c0c-804c-5765b353e9c5@email.android.com> References: <1201ca6d-8464-4c0c-804c-5765b353e9c5@email.android.com> Message-ID: <88E2E031-E249-4AFC-BA88-7ABE008BCF1C@yahoo.com.au> Not to mention all the allocation that goes on in num::strconv :/ Some work on that could possibly result in a speed up. I'm a fan of sticking with the fmt! style - it separates the data from the representation as opposed to mixing the two. But maybe I'm just an old fuddy-duddy. ~Brendan On 14/07/2013, at 1:08 PM, Patrick Walton wrote: > Keep in mind that fmt!'s interface is misdesigned at the moment: with the current interface the result is allocated on the heap even when the output is destined for a file or the screen. This is one of the bugs that resulted in poor performance (an order of magnitude slower than Python) on Chris Leary's benchmark. Fixing this will probably require having something like writefln or printfln. > > Jack Moffitt wrote: > I saw https://github.com/mozilla/rust/pull/7779 come up today and > commented on it. I got to thinking about it some, and since the bug > doesn't seem the right place for such discussion, I wanted to bring it > up here. > > The PR proposes to rename print!() and println!() to printf!() and > printfln!(). The original macros exist to replace uses of print() and > println() that look like: println(fmt!("blah blah %s", s)); > > Having a good default way to print things is very important, and it's > one of the first things people will see of the language. I think it's > worth bikeshedding it a bit to see if we can't come up with something > better than the status quo. > > I propose instead: > > 1) Do away with the formatting stuff as the default. print!() and > println!() sh > ould > just take a variable number of arguments, and each > one should be printed in its default string representation with a > space between each one. This is how Clojure's (and Python's?) print > and println work. > > This would change code like this: println!("The result is %f", foo); > to this: println!("The result is", foo) > > It's much easier. There are no formatting codes to remember and it > does exaclty what you want in most cases. Consider: println!(a, ,b, c, > "d=", d); This seems great for the standard printf-style debugging. > > If formatting is needed, it's easy to get to: > println!("My name is", name, "and I scored", fmt!("%0.2f", score)); > > 2) Since println!() is likely to be used the most often, I feel like > it should have a shorter name. Ie, we should call it just print!(), > and have a newline-less version with a different name, or perhaps a > different style of invocation of the macro. > > > As > some data to ponder, I went through the Servo code and all its dependencies: > > - The dependencies of servo use println 42 times, 24 of which also use > fmt!(). None of these need to use fmt!() at all, they could just use > the default string representation. > > - Servo itself uses println about 10 times, only two of which need > fmt!(). These two uses are both fancy formatted output for the > profiler. > > Changing all these uses to print!() in the codebase (aside from the > two profiler fmt!()s) would make things much nicer looking. > > jack. > > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -- > Sent from my Android phone with K-9 Mail. Please excuse my brevity. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From bjzaba at yahoo.com.au Sat Jul 13 23:03:55 2013 From: bjzaba at yahoo.com.au (Brendan Zabarauskas) Date: Sun, 14 Jul 2013 16:03:55 +1000 Subject: [rust-dev] bikeshedding println() and friends In-Reply-To: References: Message-ID: <032A85BC-7CD3-4BB3-8F52-E1817697CF4F@yahoo.com.au> Actually, your suggestion would actually be quite nice for quit print debugging. often I doe want to just do: `println(x)`. What about: - print!, println! -> comma separated list of values, converted to a string - printf!, printfln! -> wraps fmt! Simples. ~Brendan On 14/07/2013, at 12:39 PM, Jack Moffitt wrote: > I saw https://github.com/mozilla/rust/pull/7779 come up today and > commented on it. I got to thinking about it some, and since the bug > doesn't seem the right place for such discussion, I wanted to bring it > up here. > > The PR proposes to rename print!() and println!() to printf!() and > printfln!(). The original macros exist to replace uses of print() and > println() that look like: println(fmt!("blah blah %s", s)); > > Having a good default way to print things is very important, and it's > one of the first things people will see of the language. I think it's > worth bikeshedding it a bit to see if we can't come up with something > better than the status quo. > > I propose instead: > > 1) Do away with the formatting stuff as the default. print!() and > println!() should just take a variable number of arguments, and each > one should be printed in its default string representation with a > space between each one. This is how Clojure's (and Python's?) print > and println work. > > This would change code like this: println!("The result is %f", foo); > to this: println!("The result is", foo) > > It's much easier. There are no formatting codes to remember and it > does exaclty what you want in most cases. Consider: println!(a, ,b, c, > "d=", d); This seems great for the standard printf-style debugging. > > If formatting is needed, it's easy to get to: > println!("My name is", name, "and I scored", fmt!("%0.2f", score)); > > 2) Since println!() is likely to be used the most often, I feel like > it should have a shorter name. Ie, we should call it just print!(), > and have a newline-less version with a different name, or perhaps a > different style of invocation of the macro. > > > As some data to ponder, I went through the Servo code and all its dependencies: > > - The dependencies of servo use println 42 times, 24 of which also use > fmt!(). None of these need to use fmt!() at all, they could just use > the default string representation. > > - Servo itself uses println about 10 times, only two of which need > fmt!(). These two uses are both fancy formatted output for the > profiler. > > Changing all these uses to print!() in the codebase (aside from the > two profiler fmt!()s) would make things much nicer looking. > > jack. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From bklooste at gmail.com Sat Jul 13 23:29:41 2013 From: bklooste at gmail.com (Bennie Kloosteman) Date: Sun, 14 Jul 2013 14:29:41 +0800 Subject: [rust-dev] bikeshedding println() and friends In-Reply-To: <1201ca6d-8464-4c0c-804c-5765b353e9c5@email.android.com> References: <1201ca6d-8464-4c0c-804c-5765b353e9c5@email.android.com> Message-ID: The C printf way is very primative .. no new languages have used it in ages and even C++ tried to replace it with cout and overloading . I prefer the Java /C# way which is best from a coding simplicity and safety point of view but can handle different cases. stream.Write ( str1 + str2 +string3) ( you can go Console.WriteLine or File but these use a stream underneath so i dont think it would make a huge difference in performance ) I dont like print (str1 , str2 ,str3 ) as much because its not as obvious what the method does eg in C# if str1+str2 ..etc etc is too slow in a big loop you go to var str =string.Format ( "This is a long string with many inserts {0} at different points {1} , val0 , val1 ...) ; stream.Write (str); and if that is still too slow use stringbuilder to write direcly to the stream. and if that is still too slow build your own char array It may be needed for the lib to give ok performance but i would call it somehing obscure like internal_print so its not the default option for every c programmer ..the default / easiest option needs to be the easiest and safest one to program .. which c printf style is not.. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bjzaba at yahoo.com.au Sun Jul 14 00:03:26 2013 From: bjzaba at yahoo.com.au (Brendan Zabarauskas) Date: Sun, 14 Jul 2013 17:03:26 +1000 Subject: [rust-dev] bikeshedding println() and friends In-Reply-To: References: <1201ca6d-8464-4c0c-804c-5765b353e9c5@email.android.com> Message-ID: <4587955A-4F25-49DF-9423-33A24885DE78@yahoo.com.au> > .. no new languages have used it in ages http://golang.org/pkg/fmt/ On 14/07/2013, at 4:29 PM, Bennie Kloosteman wrote: > The C printf way is very primative .. no new languages have used it in ages and even C++ tried to replace it with cout and overloading . > > I prefer the Java /C# way which is best from a coding simplicity and safety point of view but can handle different cases. > > stream.Write ( str1 + str2 +string3) ( you can go Console.WriteLine or File but these use a stream underneath so i dont think it would make a huge difference in performance ) > > I dont like print (str1 , str2 ,str3 ) as much because its not as obvious what the method does eg in C# if str1+str2 ..etc etc is too slow in a big loop you go to > > var str =string.Format ( "This is a long string with many inserts {0} at different points {1} , val0 , val1 ...) ; > stream.Write (str); > > and if that is still too slow use stringbuilder to write direcly to the stream. > and if that is still too slow build your own char array > > > It may be needed for the lib to give ok performance but i would call it somehing obscure like internal_print so its not the default option for every c programmer ..the default / easiest option needs to be the easiest and safest one to program .. which c printf style is not.. > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From simon.sapin at exyr.org Sun Jul 14 00:40:10 2013 From: simon.sapin at exyr.org (Simon Sapin) Date: Sun, 14 Jul 2013 08:40:10 +0100 Subject: [rust-dev] bikeshedding println() and friends In-Reply-To: References: Message-ID: <51E255DA.4030501@exyr.org> Le 14/07/2013 03:39, Jack Moffitt a ?crit : > I propose instead: > > 1) Do away with the formatting stuff as the default. print!() and > println!() should just take a variable number of arguments, and each > one should be printed in its default string representation with a > space between each one. This is how Clojure's (and Python's?) print > and println work. > > This would change code like this: println!("The result is %f", foo); > to this: println!("The result is", foo) > > It's much easier. There are no formatting codes to remember and it > does exaclty what you want in most cases. Consider: println!(a, ,b, c, > "d=", d); This seems great for the standard printf-style debugging. > > If formatting is needed, it's easy to get to: > println!("My name is", name, "and I scored", fmt!("%0.2f", score)); > > 2) Since println!() is likely to be used the most often, I feel like > it should have a shorter name. Ie, we should call it just print!(), > and have a newline-less version with a different name, or perhaps a > different style of invocation of the macro. I like this. For comparison, Python 3 has a single print() function that takes a variable number of positional parameters (including zero), and two optional keyword-only parameters sep=' ' and end='\n'. In my experience 'end' is not used often. When it is, it is most often set to the emtpty string. 'sep' is even less used. So maybe it?s okay to not have so much flexibility, and require complex cases to fall back on fmt!() -- Simon Sapin From ben.striegel at gmail.com Sun Jul 14 09:49:55 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Sun, 14 Jul 2013 12:49:55 -0400 Subject: [rust-dev] bikeshedding println() and friends In-Reply-To: References: Message-ID: I think Jack's proposal is fine, but as Bennie notes I think it's still worth discussing whether C#-style formatting would be a better fit for us than C-style formatting. > I'm a fan of sticking with the fmt! style Patrick mentions that fmt! currently requires a heap allocation to work, is this a fundamental limitation of separating formatting from printing? Whatever the final interface ends up as, I want to make sure that the "nice and easy" way of printing a string to the screen isn't a potential performance hazard. -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Sun Jul 14 10:03:00 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Sun, 14 Jul 2013 13:03:00 -0400 Subject: [rust-dev] bikeshedding println() and friends In-Reply-To: References: Message-ID: On Sun, Jul 14, 2013 at 12:49 PM, Benjamin Striegel wrote: > I think Jack's proposal is fine, but as Bennie notes I think it's still > worth discussing whether C#-style formatting would be a better fit for us > than C-style formatting. > >> I'm a fan of sticking with the fmt! style > > Patrick mentions that fmt! currently requires a heap allocation to work, is > this a fundamental limitation of separating formatting from printing? > Whatever the final interface ends up as, I want to make sure that the "nice > and easy" way of printing a string to the screen isn't a potential > performance hazard. It's not a fundamental limitation. Formatting and conversion to something byte/string-like should output to a generic stream type parameter. Strings and byte vectors can implement the trait needed to act as one of those generic streams. From danielmicay at gmail.com Sun Jul 14 10:09:18 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Sun, 14 Jul 2013 13:09:18 -0400 Subject: [rust-dev] bikeshedding println() and friends In-Reply-To: References: <1201ca6d-8464-4c0c-804c-5765b353e9c5@email.android.com> Message-ID: On Sun, Jul 14, 2013 at 2:29 AM, Bennie Kloosteman wrote: > The C printf way is very primative .. no new languages have used it in > ages and even C++ tried to replace it with cout and overloading . Scala, Go and D have compile-time checked, type-safe format strings for I/O. > I prefer the Java /C# way which is best from a coding simplicity and > safety point of view but can handle different cases. > > stream.Write ( str1 + str2 +string3) ( you can go Console.WriteLine or > File but these use a stream underneath so i dont think it would make a huge > difference in performance ) Allocations on output do make a huge difference in performance, Rust is proving that true right now. > I dont like print (str1 , str2 ,str3 ) as much because its not as > obvious what the method does eg in C# if str1+str2 ..etc etc is too slow > in a big loop you go to > > var str =string.Format ( "This is a long string with many inserts {0} at > different points {1} , val0 , val1 ...) ; > stream.Write (str); > > and if that is still too slow use stringbuilder to write direcly to the > stream. > and if that is still too slow build your own char array All of this is much slower than just writing directly to a stream. > It may be needed for the lib to give ok performance but i would call it > somehing obscure like internal_print so its not the default option for every > c programmer ..the default / easiest option needs to be the easiest and > safest one to program .. which c printf style is not.. Format strings are entirely safe. They're checked at compile-time and encourage separating the formatting from the input. You would be hard-pressed to do internationalization without them. From slabode at aim.com Sun Jul 14 10:10:02 2013 From: slabode at aim.com (SiegeLord) Date: Sun, 14 Jul 2013 13:10:02 -0400 Subject: [rust-dev] bikeshedding println() and friends In-Reply-To: References: Message-ID: <51E2DB6A.9070405@aim.com> On 07/13/2013 10:39 PM, Jack Moffitt wrote: > 1) Do away with the formatting stuff as the default. print!() and > println!() should just take a variable number of arguments, and each > one should be printed in its default string representation with a > space between each one. This is how Clojure's (and Python's?) print > and println work. > > This would change code like this: println!("The result is %f", foo); > to this: println!("The result is", foo) > > It's much easier. There are no formatting codes to remember and it > does exaclty what you want in most cases. Consider: println!(a, ,b, c, > "d=", d); This seems great for the standard printf-style debugging. Well, you could also do it D's way: writefln("The result is %s", foo); Where "%s" grabs the "default string representation" (note that is is very unlike "%?" in Rust). You (in all cases your proposal would work) don't need to remember any other formatting codes. Or you can do Tango's way (a D library): Stdout.formatln("The result is {}", foo); Where "{}" does the same as above. I think separating formatting from values is a valid approach that I sometimes (but not always) prefer using. Just like Brendan in another email, I'd prefer both the formatting and the non-formatting macros to exist, with the following semantics: print!(a, b, c); // grabs the default string representation and puts a space between each one print!(); // prints nothing printf!("a = %f", a); // prints using the format string printf!("a"); // prints just the format string printf!(a); // illegal (or, alternatively grabs the default string representation of a and uses it as the format string, especially if you want to use this for gettext-like functionality) printf!(a, b); // same as above printf!(); // illegal Speaking of "default string representation", it'd be only useful if it is obtained via a trait like ToStr (but with a writer interface, for efficiency). Using "%?" outside of debugging is almost never what I want (it's unsafe anyway). It'd allow for an efficient implementation of fmt! too (when used with this macro). > > If formatting is needed, it's easy to get to: > println!("My name is", name, "and I scored", fmt!("%0.2f", score)); > > 2) Since println!() is likely to be used the most often, I feel like > it should have a shorter name. Ie, we should call it just print!(), > and have a newline-less version with a different name, or perhaps a > different style of invocation of the macro. I'd prefer "ln" to stay, as it makes it clear what is happening. As a newcomer to python (and bash with it's echo) I always have to double check whether or not it outputs a newline. I like the documentation benefit of keeping the name. -SL From danielmicay at gmail.com Sun Jul 14 10:16:44 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Sun, 14 Jul 2013 13:16:44 -0400 Subject: [rust-dev] bikeshedding println() and friends In-Reply-To: References: Message-ID: On Sat, Jul 13, 2013 at 10:39 PM, Jack Moffitt wrote: > I saw https://github.com/mozilla/rust/pull/7779 come up today and > commented on it. I got to thinking about it some, and since the bug > doesn't seem the right place for such discussion, I wanted to bring it > up here. > > The PR proposes to rename print!() and println!() to printf!() and > printfln!(). The original macros exist to replace uses of print() and > println() that look like: println(fmt!("blah blah %s", s)); > > Having a good default way to print things is very important, and it's > one of the first things people will see of the language. I think it's > worth bikeshedding it a bit to see if we can't come up with something > better than the status quo. > > I propose instead: > > 1) Do away with the formatting stuff as the default. print!() and > println!() should just take a variable number of arguments, and each > one should be printed in its default string representation with a > space between each one. This is how Clojure's (and Python's?) print > and println work. > > This would change code like this: println!("The result is %f", foo); > to this: println!("The result is", foo) > > It's much easier. There are no formatting codes to remember and it > does exaclty what you want in most cases. Consider: println!(a, ,b, c, > "d=", d); This seems great for the standard printf-style debugging. > > If formatting is needed, it's easy to get to: > println!("My name is", name, "and I scored", fmt!("%0.2f", score)); > > 2) Since println!() is likely to be used the most often, I feel like > it should have a shorter name. Ie, we should call it just print!(), > and have a newline-less version with a different name, or perhaps a > different style of invocation of the macro. > > > As some data to ponder, I went through the Servo code and all its dependencies: > > - The dependencies of servo use println 42 times, 24 of which also use > fmt!(). None of these need to use fmt!() at all, they could just use > the default string representation. > > - Servo itself uses println about 10 times, only two of which need > fmt!(). These two uses are both fancy formatted output for the > profiler. > > Changing all these uses to print!() in the codebase (aside from the > two profiler fmt!()s) would make things much nicer looking. > > jack. Without format strings as the primary way to do output, I think we'll fall down really short on the ability to do internationalization. From hatahet at gmail.com Sun Jul 14 13:25:22 2013 From: hatahet at gmail.com (Ziad Hatahet) Date: Sun, 14 Jul 2013 13:25:22 -0700 Subject: [rust-dev] bikeshedding println() and friends In-Reply-To: References: <1201ca6d-8464-4c0c-804c-5765b353e9c5@email.android.com> Message-ID: On Sun, Jul 14, 2013 at 10:09 AM, Daniel Micay wrote: > Scala, Go and D have compile-time checked, type-safe format strings for > I/O. > > > Unless I am missing something, Go does not check format strings at compile time. -- Ziad -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Sun Jul 14 13:56:47 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Sun, 14 Jul 2013 16:56:47 -0400 Subject: [rust-dev] bikeshedding println() and friends In-Reply-To: References: <1201ca6d-8464-4c0c-804c-5765b353e9c5@email.android.com> Message-ID: On Sun, Jul 14, 2013 at 4:25 PM, Ziad Hatahet wrote: > On Sun, Jul 14, 2013 at 10:09 AM, Daniel Micay > wrote: >> >> Scala, Go and D have compile-time checked, type-safe format strings for >> I/O. >> >> > > Unless I am missing something, Go does not check format strings at compile > time. > > -- > Ziad Right, instead of handling invalid formatter/type combinations at compile-time, formatters are ignored if there's no implementation of them for that type (defaulting to reflection-based printing if not overridden). Rust implements it with compile-time checks though, like the other languages. It really needs to be converted to trait-based formatters primarily based on output streams. From steven at ashley.net.nz Sun Jul 14 14:06:47 2013 From: steven at ashley.net.nz (Steven Ashley) Date: Mon, 15 Jul 2013 09:06:47 +1200 Subject: [rust-dev] bikeshedding println() and friends In-Reply-To: References: Message-ID: On Sunday, July 14, 2013, Benjamin Striegel wrote: > I think Jack's proposal is fine, but as Bennie notes I think it's still > worth discussing whether C#-style formatting would be a better fit for us > than C-style formatting. > C# style formatting has the (dis?)advantage that it is possible to duplicate and reorder values by only changing the format string. This is sometimes useful for crude internationalization and localization. Are these sorts of use cases within the scope of this discussion? Will dynamic format strings even be possible? I imagine developers needing this sort of functionality may be better off using a dedicated i18n library. Steven -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Sun Jul 14 14:10:25 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Sun, 14 Jul 2013 17:10:25 -0400 Subject: [rust-dev] bikeshedding println() and friends In-Reply-To: References: Message-ID: On Sun, Jul 14, 2013 at 5:06 PM, Steven Ashley wrote: > On Sunday, July 14, 2013, Benjamin Striegel wrote: >> >> I think Jack's proposal is fine, but as Bennie notes I think it's still >> worth discussing whether C#-style formatting would be a better fit for us >> than C-style formatting. > > > C# style formatting has the (dis?)advantage that it is possible to duplicate > and reorder values by only changing the format string. This is sometimes > useful for crude internationalization and localization. > > Are these sorts of use cases within the scope of this discussion? > > Will dynamic format strings even be possible? > > I imagine developers needing this sort of functionality may be better off > using a dedicated i18n library. > > Steven Compile-time checked format strings for i18n are feasible and would be pretty awesome. The syntax extension could load the format strings from an external file and validate that the formatters line up with the same parameters expected by the one in the source. Dispatching based on the current locale needs to be dynamic, but an i18n format syntax extension could just set up the code to do that itself. From graydon at mozilla.com Sun Jul 14 16:50:11 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Sun, 14 Jul 2013 16:50:11 -0700 Subject: [rust-dev] bikeshedding println() and friends In-Reply-To: References: Message-ID: <51E33933.206@mozilla.com> On 13-07-14 10:16 AM, Daniel Micay wrote: > Without format strings as the primary way to do output, I think we'll > fall down really short on the ability to do internationalization. I agree. I18n requires the ability to switch around parameter-order substantially across a large-ish (sentence-sized) chunk of text; doing it clause-by-clause doesn't work. It depends if you're talking logging or user-visible stuff. Logging by "dumping a sequence of unprocessed values" is definitely fastest, and I'd be happy to make the simplest variants of log!() or GLOBAL_LOG.put() or whatever assemble values in memory without formatting, without i18n, without anything clever. Indeed, logging can often get by tacking fixed-size entries like a 2-3-word enum onto a log buffer with pointers to numbers, timestamps, static strings and such. Many logging systems do this. But for the user-visible output, console output or UI messages or such, I want to move us towards an i18n-friendly-by-default style. It's just running up technical debt for everyone to defer that indefinitely. I agree that a things like the current %?, or a {n} style format placeholder that calls "default representation" on any parameter will continue to be helpful. It should do so statically though, not via the current visitor mechanism. The whole thing needs to be rewritten to use traits (and to not allocate, and to target IO streams). -Graydon From jack at metajack.im Sun Jul 14 23:30:38 2013 From: jack at metajack.im (Jack Moffitt) Date: Mon, 15 Jul 2013 00:30:38 -0600 Subject: [rust-dev] bikeshedding println() and friends In-Reply-To: <51E33933.206@mozilla.com> References: <51E33933.206@mozilla.com> Message-ID: >> Without format strings as the primary way to do output, I think we'll >> fall down really short on the ability to do internationalization. I didn't suggest we remove fmt!, but that we make the default println! not do formatted output by itself. My motivation is to make the tool you reach for first solve 80% of the use cases and be as simple as possible. Support for i18n is a great thing, and I hope we provide it out of the box, but it's a lot more complicated than printfln(). Do we want that complexity in the basic print function? If so, what are the proposals for managing that complexity? As an addendum, I think debug! and friends should work similarly. I'll also note that there's no debugln! and I haven't seen any complaints about that. having debug! and debugf! seems reasonable if people really feel strongly that they need formatted output in printf style. jack. From michaelwoerister at gmail.com Mon Jul 15 00:39:50 2013 From: michaelwoerister at gmail.com (Michael Woerister) Date: Mon, 15 Jul 2013 09:39:50 +0200 Subject: [rust-dev] Removing codemap::spanned In-Reply-To: <51E17F81.1040502@mozilla.com> References: <51E163E2.70507@gmail.com> <51E17F81.1040502@mozilla.com> Message-ID: <51E3A746.9050608@gmail.com> On 13.07.2013 18:25, Patrick Walton wrote: > On 7/13/13 7:27 AM, Michael Woerister wrote: >> So, I thought it might be a good idea if I tried to remove the >> spanned struct altogether and added the span field directly to the >> types that are wrapped at the moment. If needed, I would also add a >> Spanned trait that allows to abstract over anything having a span. >> Because this would affect quite a bit of the codebase (albeit not >> semantically) I thought, I'd better ask beforehand if you people think >> this is a good idea. Or maybe I am missing a reason for keeping the >> spanned struct around? > > I might prefer to just use a compressed side table for memory usage > reasons. Can we measure how much space the spans are taking up in the > AST? > > Patrick > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev Thinking about it, side table or not, the spanned struct would go away in its current form anyway, right? So it should be a step in the right direction, to gradually remove its usages. Since spanned affects how nodes using it are accessed in general (because of the .node indirection), this would also affect parts of the code that don't use spanning information. My motivation for removing spanned is that code using any type wrapped in it would become cleaner. Implementing a side table approach would then be a consequent step, building on the removal of spanned. -Michael From bklooste at gmail.com Mon Jul 15 04:05:51 2013 From: bklooste at gmail.com (Bennie Kloosteman) Date: Mon, 15 Jul 2013 19:05:51 +0800 Subject: [rust-dev] bikeshedding println() and friends In-Reply-To: References: <1201ca6d-8464-4c0c-804c-5765b353e9c5@email.android.com> Message-ID: Go and D are basically C with a few add ons so it makes sense thet want to keep things the same that does not mean they are good ... and none of those are major languages .. String builder can use streams but streams are slower then direct output ... . You can use string.Format both of which i mentioned ... HOWEVER .. the fastest way is only really relevant to a small amount of code though it is important for libs . The default and obvious methods should be the easiest to use for someone who has nver seen C or Rust and the most easy to maintain , ... So to me its not really relevant that the printf is there thouigh it is important that its hard to find and rarely used :-) Defaulting to printf style is building premature optomization front and centre into the language just because some authors are the most familiar with it .. Note C# does have format strings it uses {0} , {1} for the params since the compile knows the type anyway ...seems a lotr smarter to me... when you want to do more extensive format these days you have to take linguistic formats it to account anyway ( yen with 2 decimal points looks stupid...so then you need something much more complicated anyway. On Mon, Jul 15, 2013 at 1:09 AM, Daniel Micay wrote: > On Sun, Jul 14, 2013 at 2:29 AM, Bennie Kloosteman > wrote: > > The C printf way is very primative .. no new languages have used it > in > > ages and even C++ tried to replace it with cout and overloading . > > Scala, Go and D have compile-time checked, type-safe format strings for > I/O. > > > I prefer the Java /C# way which is best from a coding simplicity and > > safety point of view but can handle different cases. > > > > stream.Write ( str1 + str2 +string3) ( you can go Console.WriteLine or > > File but these use a stream underneath so i dont think it would make a > huge > > difference in performance ) > > Allocations on output do make a huge difference in performance, Rust > is proving that true right now. > > > I dont like print (str1 , str2 ,str3 ) as much because its not as > > obvious what the method does eg in C# if str1+str2 ..etc etc is too > slow > > in a big loop you go to > > > > var str =string.Format ( "This is a long string with many inserts {0} at > > different points {1} , val0 , val1 ...) ; > > stream.Write (str); > > > > and if that is still too slow use stringbuilder to write direcly to the > > stream. > > and if that is still too slow build your own char array > > All of this is much slower than just writing directly to a stream. > > > It may be needed for the lib to give ok performance but i would call it > > somehing obscure like internal_print so its not the default option for > every > > c programmer ..the default / easiest option needs to be the easiest and > > safest one to program .. which c printf style is not.. > > Format strings are entirely safe. They're checked at compile-time and > encourage separating the formatting from the input. You would be > hard-pressed to do internationalization without them. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From coder543 at gmail.com Mon Jul 15 05:51:39 2013 From: coder543 at gmail.com (Josh Leverette) Date: Mon, 15 Jul 2013 07:51:39 -0500 Subject: [rust-dev] bikeshedding println() and friends In-Reply-To: References: <1201ca6d-8464-4c0c-804c-5765b353e9c5@email.android.com> Message-ID: Would you please explain to me how printf is confusing? When a person is just starting out with programming, one of the first things they learn is how to use functions. How make functions, call functions... the works. printf *is a function*. People who are new to programming are implicitly more comfortable with functions than with the awkward cout method that C++ uses. Printf actually makes quite a bit of sense, but more importantly, or actually *most importantly*, when you're learning a language for the first time the means of printing to a console is among the first objectives taught. There is a classic program known as "Hello World" which hinges upon this concept. Regardless of the implementation, *it will be taught* to newcomers. That's not a concern, at all. I'm also confused as to how printf is hard to find or rarely used, but more importantly why it matters whether they've seen C or Rust before or not. Look at the wikipedia page: http://en.wikipedia.org/wiki/Printf_format_string#Programming_languages_with_printf It is used in *everything*. If we don't teach it to them, then they'll just have to learn about it later. To recap, - printf is *the standard* and obvious way of the majority of programming languages - printf is well documented on the internet - the aforementioned documentation is easy to find - printf is not difficult, and hinges on comprehension of very basic programming concepts, such as variables - printf performs well, so with all of these advantages and the good performance, why mess with a good thing? Why do you hate printf so passionately? It is a tried and true solution that works brilliantly. On Mon, Jul 15, 2013 at 6:05 AM, Bennie Kloosteman wrote: > Go and D are basically C with a few add ons so it makes sense thet want to > keep things the same that does not mean they are good ... and none of those > are major languages .. > > String builder can use streams but streams are slower then direct output > ... . You can use string.Format both of which i mentioned ... HOWEVER .. > the fastest way is only really relevant to a small amount of code though > it is important for libs . The default and obvious methods should be the > easiest to use for someone who has nver seen C or Rust and the most easy > to maintain , ... So to me its not really relevant that the printf is > there thouigh it is important that its hard to find and rarely used :-) > Defaulting to printf style is building premature optomization front and > centre into the language just because some authors are the most familiar > with it .. > > Note C# does have format strings it uses {0} , {1} for the params since > the compile knows the type anyway ...seems a lotr smarter to me... when you > want to do more extensive format these days you have to take linguistic > formats it to account anyway ( yen with 2 decimal points looks stupid...so > then you need something much more complicated anyway. > > > > > On Mon, Jul 15, 2013 at 1:09 AM, Daniel Micay wrote: > >> On Sun, Jul 14, 2013 at 2:29 AM, Bennie Kloosteman >> wrote: >> > The C printf way is very primative .. no new languages have used >> it in >> > ages and even C++ tried to replace it with cout and overloading . >> >> Scala, Go and D have compile-time checked, type-safe format strings for >> I/O. >> >> > I prefer the Java /C# way which is best from a coding simplicity and >> > safety point of view but can handle different cases. >> > >> > stream.Write ( str1 + str2 +string3) ( you can go Console.WriteLine >> or >> > File but these use a stream underneath so i dont think it would make a >> huge >> > difference in performance ) >> >> Allocations on output do make a huge difference in performance, Rust >> is proving that true right now. >> >> > I dont like print (str1 , str2 ,str3 ) as much because its not as >> > obvious what the method does eg in C# if str1+str2 ..etc etc is too >> slow >> > in a big loop you go to >> > >> > var str =string.Format ( "This is a long string with many inserts {0} >> at >> > different points {1} , val0 , val1 ...) ; >> > stream.Write (str); >> > >> > and if that is still too slow use stringbuilder to write direcly to the >> > stream. >> > and if that is still too slow build your own char array >> >> All of this is much slower than just writing directly to a stream. >> >> > It may be needed for the lib to give ok performance but i would call it >> > somehing obscure like internal_print so its not the default option for >> every >> > c programmer ..the default / easiest option needs to be the easiest and >> > safest one to program .. which c printf style is not.. >> >> Format strings are entirely safe. They're checked at compile-time and >> encourage separating the formatting from the input. You would be >> hard-pressed to do internationalization without them. >> > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -- Sincerely, Josh -------------- next part -------------- An HTML attachment was scrubbed... URL: From j.boggiano at seld.be Mon Jul 15 06:03:39 2013 From: j.boggiano at seld.be (Jordi Boggiano) Date: Mon, 15 Jul 2013 15:03:39 +0200 Subject: [rust-dev] rustdoc_ng and normalization of documentation Message-ID: <51E3F32B.8030909@seld.be> Heya, I have been planning/scheming a new doc web frontend to go with cmr's rustdoc_ng and in the process I ran into the question of normalization and structuring of the documentation blocks. If we take the net::tcp::accept function for example [1], it has fairly extensive documentation but the way it is rendered in the web docs is just a 1:1 markdown to html conversion. For me the "Arguments" and "Returns" blocks should come before the example in the documentation, because this is usually shorter and more important. In the source though keeping these close to the bottom is pretty nice because it keeps them closer to the function signature and the code itself. I see a few options to handle this going forward: - Full reorganization of the doc blocks with special tags/annotations ? la javadoc [2], I am not a particular fan of that but for special things it does serve it's purpose and has the advantage of being somewhat widespread. - We standardize on a few heading names like Arguments/Returns/Example/Changes so that those blocks can be extracted and displayed in the preferred order in the docs, and whatever remains is appended after. - Stand-still / keep a free-form format What would everyone prefer? Any other approach? [1] http://static.rust-lang.org/doc/extra/net_tcp.html#function-accept [2] http://en.wikipedia.org/wiki/Javadoc Cheers -- Jordi Boggiano @seldaek - http://nelm.io/jordi From corey at octayn.net Mon Jul 15 06:07:37 2013 From: corey at octayn.net (Corey Richardson) Date: Mon, 15 Jul 2013 09:07:37 -0400 Subject: [rust-dev] rustdoc_ng and normalization of documentation In-Reply-To: <51E3F32B.8030909@seld.be> References: <51E3F32B.8030909@seld.be> Message-ID: On Mon, Jul 15, 2013 at 9:03 AM, Jordi Boggiano wrote: > [snip] > - Full reorganization of the doc blocks with special tags/annotations ? > la javadoc [2], I am not a particular fan of that but for special things > it does serve it's purpose and has the advantage of being somewhat > widespread. > For some things, we can attach an attribute to the item. For example, https://github.com/mozilla/rust/issues/723 would be included in the documentation somehow, rather than the Javadoc-like solution of in-comment annotation. From j.boggiano at seld.be Mon Jul 15 06:18:56 2013 From: j.boggiano at seld.be (Jordi Boggiano) Date: Mon, 15 Jul 2013 15:18:56 +0200 Subject: [rust-dev] rustdoc_ng and normalization of documentation In-Reply-To: References: <51E3F32B.8030909@seld.be> Message-ID: <51E3F6C0.1080005@seld.be> On 15.07.2013 15:07, Corey Richardson wrote: > On Mon, Jul 15, 2013 at 9:03 AM, Jordi Boggiano wrote: >> [snip] >> - Full reorganization of the doc blocks with special tags/annotations ? >> la javadoc [2], I am not a particular fan of that but for special things >> it does serve it's purpose and has the advantage of being somewhat >> widespread. >> > > For some things, we can attach an attribute to the item. For example, > https://github.com/mozilla/rust/issues/723 would be included in the > documentation somehow, rather than the Javadoc-like solution of > in-comment annotation. Interesting indeed, and definitely when possible I would favor real annotations to in-comment ones, that way the code won't compile unless the docs format is valid. However as bjz mentioned [1] it would be nice to have more metadata attached to it like an alternative and date/version at which it will disappear. [1] https://github.com/mozilla/rust/issues/723#issuecomment-10351828 Cheers -- Jordi Boggiano @seldaek - http://nelm.io/jordi From niko at alum.mit.edu Mon Jul 15 06:57:28 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Mon, 15 Jul 2013 09:57:28 -0400 Subject: [rust-dev] Removing codemap::spanned In-Reply-To: <9C4997E7-C641-47E9-A329-AE8B6F1001B4@brinckerhoff.org> References: <51E163E2.70507@gmail.com> <9C4997E7-C641-47E9-A329-AE8B6F1001B4@brinckerhoff.org> Message-ID: <20130715135728.GI7851@Mr-Bennet> On Sat, Jul 13, 2013 at 09:23:56AM -0700, John Clements wrote: > I don't want to put words in peoples' mouths, but I think I've heard > people suggesting that we just use a side table for this. Do we have > tables with weakly held keys? We don't, but I presume such a table would be indexed with node-ids anyhow. We don't generally delete AST anyhow, except possibly things that are #[cfg]'d out? In any case, if this were an issue, we could "GC" the span table after macro expansion. Niko From niko at alum.mit.edu Mon Jul 15 07:00:22 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Mon, 15 Jul 2013 10:00:22 -0400 Subject: [rust-dev] bikeshedding println() and friends In-Reply-To: <88E2E031-E249-4AFC-BA88-7ABE008BCF1C@yahoo.com.au> References: <1201ca6d-8464-4c0c-804c-5765b353e9c5@email.android.com> <88E2E031-E249-4AFC-BA88-7ABE008BCF1C@yahoo.com.au> Message-ID: <20130715140022.GJ7851@Mr-Bennet> On Sun, Jul 14, 2013 at 03:51:25PM +1000, Brendan Zabarauskas wrote: > I'm a fan of sticking with the fmt! style - it separates the data > from the representation as opposed to mixing the two. But maybe I'm > just an old fuddy-duddy. +1 for format strings, though I'm not wedded to the precise C conventions. I particularly dislike intermixing expressions and the string. I often have things like this: debug!(fmt!("Entering %s: foo=%s bar=%s", some_long_expression.id.to_str(), foo.repr(tcx, ...), ...)); When expressions get long, it's very ugly for them to be mixed in with the string. Niko From bjzaba at yahoo.com.au Mon Jul 15 07:17:07 2013 From: bjzaba at yahoo.com.au (Brendan Zabarauskas) Date: Tue, 16 Jul 2013 00:17:07 +1000 Subject: [rust-dev] bikeshedding println() and friends In-Reply-To: <20130715140022.GJ7851@Mr-Bennet> References: <1201ca6d-8464-4c0c-804c-5765b353e9c5@email.android.com> <88E2E031-E249-4AFC-BA88-7ABE008BCF1C@yahoo.com.au> <20130715140022.GJ7851@Mr-Bennet> Message-ID: <0BFB455D-5C7F-4F21-82FA-8EFB2109077A@yahoo.com.au> > I'm not wedded to the precise C conventions. Yes, the discussions with aatch, dbaupp, kimundi etc. were discussing possible options for the format syntax. https://mail.mozilla.org/pipermail/rust-dev/2013-May/003999.html ~Brendan On 16/07/2013, at 12:00 AM, Niko Matsakis wrote: > On Sun, Jul 14, 2013 at 03:51:25PM +1000, Brendan Zabarauskas wrote: >> I'm a fan of sticking with the fmt! style - it separates the data >> from the representation as opposed to mixing the two. But maybe I'm >> just an old fuddy-duddy. > > +1 for format strings, though I'm not wedded to the precise C > conventions. > > I particularly dislike intermixing expressions and the string. > I often have things like this: > > debug!(fmt!("Entering %s: foo=%s bar=%s", > some_long_expression.id.to_str(), > foo.repr(tcx, ...), > ...)); > > When expressions get long, it's very ugly for them to be mixed > in with the string. > > > > > Niko > From raphael.catolino at gmail.com Mon Jul 15 08:38:16 2013 From: raphael.catolino at gmail.com (raphael catolino) Date: Mon, 15 Jul 2013 17:38:16 +0200 Subject: [rust-dev] Signal handling Message-ID: Hi everyone, I've been writing an interface for the linux Unix-domain socket api. Upon the program termination I must ensure that any socket file created must be unlinked. To deal with that I added a call to unlink in the destructor of the struct I use to hold the socket descriptor. This works well when the program terminates normally, however when it's terminated by a signal, the destructor isn't called and the file never gets unlinked. So I added an interface for the sigaction api which allows me to catch stuff like SIGINT/SIGTERM but when I call a function in libstd from inside the handler, it ends up calling abort(). I can call local functions as long as they don't call more complex functions, and I can call native libc functions as well (unlink works just fine actually). Is that to be expected because of rust implementation? As i understood, the stack segments representation in memory differs from the C one, but I'm not sure if that means rust code can't work in a signal handler stack. Or maybe just a problem with the context from inside the signal handler? btw here are some back traces i get when trying to call println() or send() from the signal handler : http://pastebin.mozilla.org/2635629 http://pastebin.mozilla.org/2635630 Raphael -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Mon Jul 15 10:34:32 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Mon, 15 Jul 2013 10:34:32 -0700 Subject: [rust-dev] Removing codemap::spanned In-Reply-To: <51E3A746.9050608@gmail.com> References: <51E163E2.70507@gmail.com> <51E17F81.1040502@mozilla.com> <51E3A746.9050608@gmail.com> Message-ID: <51E432A8.7010204@mozilla.com> On 7/15/13 12:39 AM, Michael Woerister wrote: > Thinking about it, side table or not, the spanned struct would go > away in its current form anyway, right? So it should be a step in the > right direction, to gradually remove its usages. Since spanned > affects how nodes using it are accessed in general (because of the .node > indirection), this would also affect parts of the code that don't use > spanning information. My motivation for removing spanned is that code > using any type wrapped in it would become cleaner. Implementing a side > table approach would then be a consequent step, building on the removal > of spanned. Sounds right to me. Patrick From michaelwoerister at gmail.com Mon Jul 15 10:43:55 2013 From: michaelwoerister at gmail.com (Michael Woerister) Date: Mon, 15 Jul 2013 19:43:55 +0200 Subject: [rust-dev] Removing codemap::spanned In-Reply-To: <51E432A8.7010204@mozilla.com> References: <51E163E2.70507@gmail.com> <51E17F81.1040502@mozilla.com> <51E3A746.9050608@gmail.com> <51E432A8.7010204@mozilla.com> Message-ID: <51E434DB.2070005@gmail.com> On 15.07.2013 19:34, Patrick Walton wrote: > On 7/15/13 12:39 AM, Michael Woerister wrote: >> Thinking about it, side table or not, the spanned struct would go >> away in its current form anyway, right? So it should be a step in the >> right direction, to gradually remove its usages. Since spanned >> affects how nodes using it are accessed in general (because of the .node >> indirection), this would also affect parts of the code that don't use >> spanning information. My motivation for removing spanned is that code >> using any type wrapped in it would become cleaner. Implementing a side >> table approach would then be a consequent step, building on the removal >> of spanned. > > Sounds right to me. > > Patrick Thanks for your response. I'll give it a try and hopefully you'll see some corresponding pull requests over the next few days. -Michael From alex at crichton.co Mon Jul 15 11:23:48 2013 From: alex at crichton.co (Alex Crichton) Date: Mon, 15 Jul 2013 11:23:48 -0700 Subject: [rust-dev] Making `lang_item`s optional Message-ID: It's awesome to have a lot of syntactic sugar for the compiler for things like overloading operators, automatic borrows (@mut in a lib), etc. What's unfortunate is that each of these features requires a new `lang_item` to be defined by the compiler *and* any crate which is compiled. To alleviate this problem, I think it'd be a really slick idea to make all `lang_item` attributes optional. The phases of compilation would only change such that when one is required, then an error is emitted saying that a `lang_item` needs to be implemented. It would have the span of the ast which caused the `lang_item` to be required, so it would be pretty easy to infer what would need to happen. This would make `zero.rs` even smaller than it is today, and it would also allow our `lang_item` count to grow quickly without causing unnecessary burden on users who don't use `libstd`. Any new `lang_item` wouldn't be available to someone immediately, but it's not required for their project to implement it if they don't want. This is kind of in the vain of getting as close to a "runtime-less" hello-world as possible. Currently you can combine `zero.rs` with `libc`, but `zero.rs` is a few hundred lines of mostly empty traits and functions which are never used or just abort anyway. Good chunks of it are probably still required, though. Do others think that this is a good idea? I still think that it's a good idea to at least attempt to keep the lang_item count reasonable, but at some point it's also nice to have overloaded syntax for various operators. From steven at ashley.net.nz Mon Jul 15 12:24:32 2013 From: steven at ashley.net.nz (Steven Ashley) Date: Tue, 16 Jul 2013 07:24:32 +1200 Subject: [rust-dev] bikeshedding println() and friends In-Reply-To: References: <1201ca6d-8464-4c0c-804c-5765b353e9c5@email.android.com> Message-ID: On Monday, July 15, 2013, Bennie Kloosteman wrote: > Note C# does have format strings it uses {0} , {1} for the params since > the compile knows the type anyway ...seems a lotr smarter to me... when you > want to do more extensive format these days you have to take linguistic > formats it to account anyway ( yen with 2 decimal points looks stupid...so > then you need something much more complicated anyway. > For the record C# style format strings support per item formatting and alignment. The form is: {index[,alignment][:formatString]} To print a price right aligned and padded with spaces to 10 characters you could do String.Format("Price {0,10:$#.##}", price). String.Format actually calls item.ToString(String format, IFormatProvider cultureInfo) for each substitution before applying padding and alignment. In this way the formatter can be easily taught how to format user defined types. You can find this detailed on msdn here: http://msdn.microsoft.com/en-us/library/txafckwd.aspx Steven -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Mon Jul 15 13:03:10 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 15 Jul 2013 13:03:10 -0700 Subject: [rust-dev] bikeshedding println() and friends In-Reply-To: References: <51E33933.206@mozilla.com> Message-ID: <51E4557E.9080609@mozilla.com> On 13-07-14 11:30 PM, Jack Moffitt wrote: >>> Without format strings as the primary way to do output, I think we'll >>> fall down really short on the ability to do internationalization. > > I didn't suggest we remove fmt!, but that we make the default println! > not do formatted output by itself. My motivation is to make the tool > you reach for first solve 80% of the use cases and be as simple as > possible. Ok. Maybe we / I misread. I was responding to this: "Do away with the formatting stuff as the default." "change code like this: println!("The result is %f", foo); to this: println!("The result is", foo)" These sound like they're ... in the wrong spirit, to me. Obviously some output should be un- or lightly-formatted (logging, diagnostic, raw-data output, json, tabular stuff, etc.) but that's a linguistic example that looks like it's intended for an end-user. That's the primary case for l10n-friendly format strings. I don't want to be nudging any users away from l10n-friendly by default in cases like that; I want to be nudging them _towards_ l10n-friendly. > Support for i18n is a great thing, and I hope we provide it out of the > box, but it's a lot more complicated than printfln(). Do we want that > complexity in the basic print function? If so, what are the proposals > for managing that complexity? It's not a _lot_ more complicated than printfln(), no. It's a little more, in the sense that handling leapseconds is a little more complexity than not, and handling UTF8 is a little more complexity than handling ASCII. But I don't think that means we get to ignore them. And I think they're better dealt with sooner than later. In C programs gettext has got it down to printf(_("my name is %s"), x). Gettext and printf are known to be inadequate but in ways mostly addressed by Java and later CLDR/ICU-style messageformat strings[1][2] which have a similarly benign interface to the programmer, and that similarly reduce the problem to "what mini-language you support in the format strings". So the proposal I have put forth in previous threads, which I'll repeat here, is "best current practice with message catalogues", which means: - .po files (the tools for managing strings are familar / loved) - format strings with nestable {n} placeholders rather than non-nesting %-placeholders, and simple conditional forms borrowed from the work Java and ICU/CLDR have done in this field. For tracking work, I refer you to bugs: https://github.com/mozilla/rust/issues/4630 https://github.com/mozilla/rust/issues/2249 (metabug) New format library sketch: https://github.com/Aatch/rust-fmt Mailing list thread messages I posted on it: https://mail.mozilla.org/pipermail/rust-dev/2013-May/004064.html https://mail.mozilla.org/pipermail/rust-dev/2013-May/004086.html https://mail.mozilla.org/pipermail/rust-dev/2013-May/004093.html https://mail.mozilla.org/pipermail/rust-dev/2013-May/004100.html Not-very-fleshed-out library-work page pointing to prior art: https://github.com/mozilla/rust/wiki/Lib-fmt I'm happy to have people look into this, it needs to be done (and is actually a cost center in our current code). It falls in the same bucket as the IO library as a surface-UI thing that is very high visibility, early-contact, and must be Done Right before we finalize APIs / commit to backwards compatibility. But I want to make it l10n-friendly by default. > As an addendum, I think debug! and friends should work similarly. I'll > also note that there's no debugln! and I haven't seen any complaints > about that. having debug! and debugf! seems reasonable if people > really feel strongly that they need formatted output in printf style. Yeah, the \n / ln / fln thing is a red herring. I'm fine with all such variants existing, and for debugging / logging to hit the unformatted path. They're perf critical[3]. -Graydon [1] https://github.com/SlexAxton/messageformat.js [2] https://docs.google.com/presentation/d/1ZyN8-0VXmod5hbHveq-M1AeQ61Ga3BmVuahZjbmbBxo/pub [3] (Concerning perf: there's a reasonable sub-argument in here that static compilation of a format string to a sequence of format-trait-calls is going to carry a major perf advantage over _any_ runtime interpretation. I think this is a very subtle balance to get right if we want to support runtime .po-string loading, and minimize code bloat on cold code paths caused by format strings. It may require careful measurement and some combination of cached runtime-compilations and &Trait / vtbl dispatch. Or it might be something we have to surface to the user, how they compile-down a format string. I think it's similar to the set of issues we'll encounter when doing a regexp library.) From graydon at mozilla.com Mon Jul 15 13:24:13 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 15 Jul 2013 13:24:13 -0700 Subject: [rust-dev] Removing codemap::spanned In-Reply-To: <51E434DB.2070005@gmail.com> References: <51E163E2.70507@gmail.com> <51E17F81.1040502@mozilla.com> <51E3A746.9050608@gmail.com> <51E432A8.7010204@mozilla.com> <51E434DB.2070005@gmail.com> Message-ID: <51E45A6D.5030407@mozilla.com> On 13-07-15 10:43 AM, Michael Woerister wrote: > Thanks for your response. I'll give it a try and hopefully you'll see > some corresponding pull requests over the next few days. I suspect you'll want to make a trait `Spanned` that the various spanned-types implement, such that code that generically acts on "Some spanned thing" can continue to work. Not sure, just a hunch. (spanned predates having traits at all, so if there's a better way to approach this in current idioms, go right ahead) -Graydon From graydon at mozilla.com Mon Jul 15 13:25:08 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 15 Jul 2013 13:25:08 -0700 Subject: [rust-dev] Conduct again (was Re: bikeshedding println() and friends) In-Reply-To: References: <1201ca6d-8464-4c0c-804c-5765b353e9c5@email.android.com> Message-ID: <51E45AA4.7030708@mozilla.com> On 13-07-07 08:06 PM, Bennie Kloosteman wrote: > "You think Linux is not well-engineered?" > > Nope .. its the same piece of 1970s crap that all the other popular OS > use , with trivial differences people make a bit deal about.. On 13-07-15 04:05 AM, Bennie Kloosteman wrote: > Go and D are basically C with a few add ons so it makes sense thet want > to keep things the same that does not mean they are good ... and none of > those are major languages .. This is 2 threads in 2 weeks in which you've thrown random slander on other people's hard work in passing. Doing so lowers the tone of mailing list threads from polite and constructive to dismissive and combative, hurts and scares some people off participating altogether, and wastes everyone's time cooling their emotions back down. I want to clarify: this is not acceptable behavior here. The 3rd, 4th and 6th points in our code of conduct[1] try to make this very clear. Please tone it down. There are nearly 800 busy people reading this list. Their time and consideration is a gift. -Graydon [1] https://github.com/mozilla/rust/wiki/Note-development-policy From noamraph at gmail.com Mon Jul 15 13:29:04 2013 From: noamraph at gmail.com (Noam Yorav-Raphael) Date: Mon, 15 Jul 2013 23:29:04 +0300 Subject: [rust-dev] bikeshedding println() and friends In-Reply-To: <51E4557E.9080609@mozilla.com> References: <51E33933.206@mozilla.com> <51E4557E.9080609@mozilla.com> Message-ID: On 15 July 2013 23:03, Graydon Hoare wrote: > > - format strings with nestable {n} placeholders rather than > non-nesting %-placeholders, and simple conditional forms borrowed > from the work Java and ICU/CLDR have done in this field. Would "{}" placeholders work as well (the first means {0}, the second {1}, and so on)? I really miss them in python 2.6 - they were added in python 2.7. Noam -------------- next part -------------- An HTML attachment was scrubbed... URL: From jon.mb at proinbox.com Sun Jul 14 09:15:58 2013 From: jon.mb at proinbox.com (John Mija) Date: Sun, 14 Jul 2013 17:15:58 +0100 Subject: [rust-dev] Renamed print/println Message-ID: <51E2CEBE.9010405@proinbox.com> Into a recent commit, has been renamed print!()/println!() to printf!()/printfln!() https://github.com/mozilla/rust/commit/3b0258916d28a1215acf9a0c78f6760cc67f935c Why do not have print!(), println!() and printf!()? If somebody wants a line in printf!(), he can use "\n" character. From svetoslav at neykov.name Sun Jul 14 13:04:40 2013 From: svetoslav at neykov.name (Svetoslav Neykov) Date: Sun, 14 Jul 2013 23:04:40 +0300 Subject: [rust-dev] Rust on bare metal ARM - sample project Message-ID: <000101ce80cd$60dbc670$22935350$@neykov.name> Hello, My interest in Rust is from the point of view of an embedded microcontrollers running bare metal programs with no underlying OS. I decided to explore what the language offers in that space by creating an actual running program. For the target I used STM32F4Discovery board since it has an ARM CPU which is already supported by the compiler. What is special about this board with comparison to the Android port is that it has only 192K internal memory (no SDRAM) and no MMU. You can find the project at https://github.com/neykov/armboot. For the first step I chose the fastest approach possible - to generate an intermediate .ll, convert it to assembler and compile it with the gcc cross-compiler for the target (arm-none-eabi). One change was required to the compiler to skip the generation of function prologue for split stacks (see https://raw.github.com/neykov/armboot/master/rustc.patch). This version supports only static memory allocation, though heap access (owned pointers) is easily implemented (i.e. use malloc/free linked to newlib). Zero.rs is used so no managed pointers and garbage collection. The generation of the executable file is automated. After generation the .ll file is corrected so it works with unpatched llvm 3.4 and the .note.rustc section is removed so it doesn't take space on the target device. Major points from the effort: . I ported a basic C program to equivalent safe Rust program (see main.rs vs blinky.c). It is interesting because it uses an interrupt callback for the actual blinking logic. . The platform definitions were needed - like IO register locations and memory layout. I created a subset of them, mostly by hand, taking the output from rust-bindgen for the structures. All the #defines and enums had to be created as macros so as not to allocate actual memory on the device if declared as static (which I tried and ran out of memory J ). This is somewhat cumbersome since it requires adding "!()" but not a huge problem. . "unsafe" is not a normal block and doesn't return a value, can't be used as an expression. This made it impossible to wrap the unsafe casts from fixed memory locations to borrowed pointers in macros. Instead I had to use inline functions and assign the resulting value to a local function variable. . No "volatile" equivalent in Rust - currently all code is compiled with disabled optimizations so IO code is not optimized away. Another possible workaround is to use extern "C" functions to do the actual hardware communication. . I couldn't move the platform code to a separate library since macros can't be exported (I saw that this is still a work in progress according to #3114 so not a long term problem). . There were problems with the code comments in the original source files (i.e. see https://github.com/neykov/armboot/blob/master/sys/inc/stm32f4xx.h). I got compile-time errors because of the special symbol combinations in them which are reserved in Rust. . No core/std since I used zero.rs. As a future development I will look into adding support for the arm-none-eabi target by the Rust compiler and getting at least part of "core" working on the target device in memory constrained environment. Svetoslav -------------- next part -------------- An HTML attachment was scrubbed... URL: From thadguidry at gmail.com Mon Jul 15 13:35:43 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Mon, 15 Jul 2013 15:35:43 -0500 Subject: [rust-dev] Removing codemap::spanned In-Reply-To: <51E45A6D.5030407@mozilla.com> References: <51E163E2.70507@gmail.com> <51E17F81.1040502@mozilla.com> <51E3A746.9050608@gmail.com> <51E432A8.7010204@mozilla.com> <51E434DB.2070005@gmail.com> <51E45A6D.5030407@mozilla.com> Message-ID: > (spanned predates having traits at all, so if there's a better way to > approach this in current idioms, go right ahead) > > -Graydon > > Oooo, That's a good thing to know and have documented somewhere in the tutorial under Traits as a note. Can you add that Daniel ? I mean the idiom difference that Graydon is mentioning between the two. That would be good to have as a note in the tutorial. -- -Thad Thad on Freebase.com Thad on LinkedIn -------------- next part -------------- An HTML attachment was scrubbed... URL: From jack at metajack.im Mon Jul 15 13:36:36 2013 From: jack at metajack.im (Jack Moffitt) Date: Mon, 15 Jul 2013 14:36:36 -0600 Subject: [rust-dev] bikeshedding println() and friends In-Reply-To: <51E4557E.9080609@mozilla.com> References: <51E33933.206@mozilla.com> <51E4557E.9080609@mozilla.com> Message-ID: > "change code like this: println!("The result is %f", foo); > to this: println!("The result is", foo)" > > These sound like they're ... in the wrong spirit, to me. Obviously some > output should be un- or lightly-formatted (logging, diagnostic, raw-data > output, json, tabular stuff, etc.) but that's a linguistic example that > looks like it's intended for an end-user. That's the primary case for > l10n-friendly format strings. I don't want to be nudging any users away > from l10n-friendly by default in cases like that; I want to be nudging > them _towards_ l10n-friendly. Perhaps this boils down to what people work on most. In Servo, print! et al are only used for debugging and logging. We have no command line interface to speak of, and no need to have translated format strings. That go to stdout/stderr. We will make plenty of use of string formatting to generate strings for display in dialogs I'm sure. I think all the code in Servo's C/C++ dependencies uses printf for diagnostics and debugging (SkDebugf, SkPrintf from Skia as an example). However, in Rust, stdout is the UI, and i18n string formatting is clearly very important there. I think compilers are in the tail of the distribution in that they want both i18n formatted string handling and that stdout/stderr are their interfaces. Keep in mind that my proposal was specifically about print*! and debug! (and friends) and not at all about fmt! or anything else. jack. From pwalton at mozilla.com Mon Jul 15 13:37:23 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Mon, 15 Jul 2013 13:37:23 -0700 Subject: [rust-dev] Rust on bare metal ARM - sample project In-Reply-To: <000101ce80cd$60dbc670$22935350$@neykov.name> References: <000101ce80cd$60dbc670$22935350$@neykov.name> Message-ID: <51E45D83.9060905@mozilla.com> On 7/14/13 1:04 PM, Svetoslav Neykov wrote: > ??unsafe? is not a normal block and doesn?t return a value, can?t be > used as an expression. This made it impossible to wrap the unsafe casts > from fixed memory locations to borrowed pointers in macros. Instead I > had to use inline functions and assign the resulting value to a local > function variable. This should not be the case. There may be a bug in the way macros interact with unsafe checking. Do you have a test case by any chance? Patrick From graydon at mozilla.com Mon Jul 15 14:04:24 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 15 Jul 2013 14:04:24 -0700 Subject: [rust-dev] bikeshedding println() and friends In-Reply-To: References: <51E33933.206@mozilla.com> <51E4557E.9080609@mozilla.com> Message-ID: <51E463D8.30109@mozilla.com> On 13-07-15 01:36 PM, Jack Moffitt wrote: > Perhaps this boils down to what people work on most. In Servo, print! > et al are only used for debugging and logging. Oh dear. Paging bug https://github.com/mozilla/rust/issues/3309, the debug! facilities are not working if that's true :( > Keep in mind that my proposal was specifically about print*! and > debug! (and friends) and not at all about fmt! or anything else. Ok. So long as formatting (and l10n-friendly formatting) remains as easily-within-reach as anything else, I don't mind writing printf or iprintf rather than print. -Graydon From steven at ashley.net.nz Mon Jul 15 14:25:30 2013 From: steven at ashley.net.nz (Steven Ashley) Date: Tue, 16 Jul 2013 09:25:30 +1200 Subject: [rust-dev] Renamed print/println In-Reply-To: <51E2CEBE.9010405@proinbox.com> References: <51E2CEBE.9010405@proinbox.com> Message-ID: A possible use case for printfln may be to ensure that a new line is always written in the case where the format string comes from a .po file and is translated into many different languages. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bjzaba at yahoo.com.au Mon Jul 15 16:33:49 2013 From: bjzaba at yahoo.com.au (Brendan Zabarauskas) Date: Tue, 16 Jul 2013 09:33:49 +1000 Subject: [rust-dev] Renamed print/println In-Reply-To: References: <51E2CEBE.9010405@proinbox.com> Message-ID: <64DA38B9-5897-4EC2-8DB2-126B3D366379@yahoo.com.au> print!()/println!() and printf!()/printfln!() sounds good to me. Adding an extra 'f' isn't much of a hassle for fmt! functionality. ~Brendan On 16/07/2013, at 7:25 AM, Steven Ashley wrote: > A possible use case for printfln may be to ensure that a new line is always written in the case where the format string comes from a .po file and is translated into many different languages. _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From corey at octayn.net Mon Jul 15 16:38:47 2013 From: corey at octayn.net (Corey Richardson) Date: Mon, 15 Jul 2013 19:38:47 -0400 Subject: [rust-dev] Renamed print/println In-Reply-To: <64DA38B9-5897-4EC2-8DB2-126B3D366379@yahoo.com.au> References: <51E2CEBE.9010405@proinbox.com> <64DA38B9-5897-4EC2-8DB2-126B3D366379@yahoo.com.au> Message-ID: On Mon, Jul 15, 2013 at 7:33 PM, Brendan Zabarauskas wrote: > print!()/println!() and printf!()/printfln!() sounds good to me. Adding an extra 'f' isn't much of a hassle for fmt! functionality. > Way I see it is if I can type less than `println(fmt!("%?, foo));`, I'm happy :) That is basically the only time I use fmt!, for debugging. I haven't really written anything that needs interaction with user that isn't done with command arguments. From bjzaba at yahoo.com.au Mon Jul 15 16:52:39 2013 From: bjzaba at yahoo.com.au (Brendan Zabarauskas) Date: Tue, 16 Jul 2013 09:52:39 +1000 Subject: [rust-dev] Renamed print/println In-Reply-To: References: <51E2CEBE.9010405@proinbox.com> <64DA38B9-5897-4EC2-8DB2-126B3D366379@yahoo.com.au> Message-ID: Indeed. `println(fmt!("%?, foo));` requires great deal of keyboard gymnastics. And yes the most common use case will most likely be for debugging, so the ergonomics should fit with that. ~Brendan On 16/07/2013, at 9:38 AM, Corey Richardson wrote: > On Mon, Jul 15, 2013 at 7:33 PM, Brendan Zabarauskas > wrote: >> print!()/println!() and printf!()/printfln!() sounds good to me. Adding an extra 'f' isn't much of a hassle for fmt! functionality. >> > > Way I see it is if I can type less than `println(fmt!("%?, foo));`, > I'm happy :) That is basically the only time I use fmt!, for > debugging. I haven't really written anything that needs interaction > with user that isn't done with command arguments. From dbau.pp at gmail.com Mon Jul 15 17:28:51 2013 From: dbau.pp at gmail.com (Huon Wilson) Date: Tue, 16 Jul 2013 10:28:51 +1000 Subject: [rust-dev] Making `lang_item`s optional In-Reply-To: References: Message-ID: <51E493C3.7020206@gmail.com> On 16/07/13 04:23, Alex Crichton wrote: > It's awesome to have a lot of syntactic sugar for the compiler for things like > overloading operators, automatic borrows (@mut in a lib), etc. What's > unfortunate is that each of these features requires a new `lang_item` to be > defined by the compiler *and* any crate which is compiled. > > To alleviate this problem, I think it'd be a really slick idea to make all > `lang_item` attributes optional. The phases of compilation would only change > such that when one is required, then an error is emitted saying that a > `lang_item` needs to be implemented. It would have the span of the ast which > caused the `lang_item` to be required, so it would be pretty easy to infer what > would need to happen. > > This would make `zero.rs` even smaller than it is today, and it would also allow > our `lang_item` count to grow quickly without causing unnecessary burden on > users who don't use `libstd`. Any new `lang_item` wouldn't be available to > someone immediately, but it's not required for their project to implement it > if they don't want. > > This is kind of in the vain of getting as close to a "runtime-less" hello-world > as possible. Currently you can combine `zero.rs` with `libc`, but `zero.rs` is a > few hundred lines of mostly empty traits and functions which are never used or > just abort anyway. Good chunks of it are probably still required, though. > > Do others think that this is a good idea? I still think that it's a > good idea to at least attempt to keep the lang_item count reasonable, > but at some point it's also nice to have overloaded syntax for various > operators. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev +1 This would be very useful for splitting std into zero-std ('libcore'?) and runtime-std where the former are things that don't need the runtime (or even don't need libc at all), e.g. most of the Iterators and the adaptors, utility types like Option, a pile of helper methods/functions on &str and &[], etc etc. This would make using zero.rs far nicer, without having to have a lot of duplicated code. Huon From jens at nockert.se Mon Jul 15 21:27:45 2013 From: jens at nockert.se (Jens Nockert) Date: Tue, 16 Jul 2013 06:27:45 +0200 Subject: [rust-dev] OpenCL-style accessors, casts. Message-ID: <7FAF959C-7564-4691-A16D-98C90B238AB2@nockert.se> Hello rust-dev! I implemented OpenCL-style[0] accessors for SIMD types in Rust[1], the code quality isn't near /merge-worthy yet, but I wanted some input. For some code-examples, go to https://github.com/jensnockert/rust/tree/simd/src/test/run-pass/simd-test and check it out, you should be able to get the idea of how they work. Note that I didn't add any actual syntax for vector types yet (since it would be highly controversial and I don't know what would be the best option), so I just added a simd!(name: T * n) syntax extension that declares a new type that maps down to a LLVM . My preference for syntax right now would be simd!(n x T) if I can get that to parse, or simd!(T, ..n). And then you would declare a type with type f32x4 = simd(4 x f32); and it would magically work. Another option would be some variant of the [T, ..n] syntax used for fixed-length vectors. Introducing a new t, ty_simd_vec(t, uint), instead of using the current #[simd] struct { ? }, is yet another thing that is controversial about the patch and this needs a bit of explanation of the problem with #[simd] struct { ? }. To be able to make these accessors work, you unfortunately need to be able to generate anonymous types in the compiler, x.even for example (take the even-indexed elements of a vector) may be a type that is undeclared. And if you want to be able to pretty-print that, you need to be able to generate a type without a name, which makes #[simd] struct { ? } impossible. You could just pre-declare all possible options up to 256-bit long, which probably would only be a hundred types or so, but would feel a bit silly. There are also other operations that could generate (possibly) unnamed types, like a == b, which should generate a i1-vector, or a shufflevector intrinsic that could generate vectors of any length. Ps. I didn't think of #[simd] (T, T, T, T) &c. before implementing (sanxiyn gave me that idea), but I still think that is probably a worse idea than adding SIMD as an additional type with actual syntax. [0]: http://www.khronos.org/files/opencl-quick-reference-card.pdf, page 2, "Vector Component Addressing" [1]: https://github.com/jensnockert/rust/tree/simd From jens at nockert.se Mon Jul 15 21:27:45 2013 From: jens at nockert.se (Jens Nockert) Date: Tue, 16 Jul 2013 06:27:45 +0200 Subject: [rust-dev] OpenCL-style accessors, casts. Message-ID: Hello rust-dev! I implemented OpenCL-style[0] accessors for SIMD types in Rust[1], the code quality isn't near /merge-worthy yet, but I wanted some input. For some code-examples, go to https://github.com/jensnockert/rust/tree/simd/src/test/run-pass/simd-test and check it out, you should be able to get the idea of how they work. Note that I didn't add any actual syntax for vector types yet (since it would be highly controversial and I don't know what would be the best option), so I just added a simd!(name: T * n) syntax extension that declares a new type that maps down to a LLVM . My preference for syntax right now would be simd!(n x T) if I can get that to parse, or simd!(T, ..n). And then you would declare a type with type f32x4 = simd(4 x f32); and it would magically work. Another option would be some variant of the [T, ..n] syntax used for fixed-length vectors. Introducing a new t, ty_simd_vec(t, uint), instead of using the current #[simd] struct { ? }, is yet another thing that is controversial about the patch and this needs a bit of explanation of the problem with #[simd] struct { ? }. To be able to make these accessors work, you unfortunately need to be able to generate anonymous types in the compiler, x.even for example (take the even-indexed elements of a vector) may be a type that is undeclared. And if you want to be able to pretty-print that, you need to be able to generate a type without a name, which makes #[simd] struct { ? } impossible. You could just pre-declare all possible options up to 256-bit long, which probably would only be a hundred types or so, but would feel a bit silly. There are also other operations that could generate (possibly) unnamed types, like a == b, which should generate a i1-vector, or a shufflevector intrinsic that could generate vectors of any length. Ps. I didn't think of #[simd] (T, T, T, T) &c. before implementing (sanxiyn gave me that idea), but I still think that is probably a worse idea than adding SIMD as an additional type with actual syntax. [0]: http://www.khronos.org/files/opencl-quick-reference-card.pdf, page 2, "Vector Component Addressing" [1]: https://github.com/jensnockert/rust/tree/simd From jeaye at arrownext.com Tue Jul 16 00:03:14 2013 From: jeaye at arrownext.com (Jeaye) Date: Tue, 16 Jul 2013 00:03:14 -0700 Subject: [rust-dev] OpenCL-style accessors, casts. In-Reply-To: References: Message-ID: <51E4F032.4030000@arrownext.com> This supports swizzling? If so, *very* cool (I've wanted swizzling in Rust for some time). J On 07/15/2013 09:27 PM, Jens Nockert wrote: > Hello rust-dev! > > I implemented OpenCL-style[0] accessors for SIMD types in Rust[1], the code quality isn't near /merge-worthy yet, but I wanted some input. > > For some code-examples, go to https://github.com/jensnockert/rust/tree/simd/src/test/run-pass/simd-test and check it out, you should be able to get the idea of how they work. > > Note that I didn't add any actual syntax for vector types yet (since it would be highly controversial and I don't know what would be the best option), so I just added a simd!(name: T * n) syntax extension that declares a new type that maps down to a LLVM . > > My preference for syntax right now would be simd!(n x T) if I can get that to parse, or simd!(T, ..n). And then you would declare a type with type f32x4 = simd(4 x f32); and it would magically work. Another option would be some variant of the [T, ..n] syntax used for fixed-length vectors. > > Introducing a new t, ty_simd_vec(t, uint), instead of using the current #[simd] struct { ? }, is yet another thing that is controversial about the patch and this needs a bit of explanation of the problem with #[simd] struct { ? }. > > To be able to make these accessors work, you unfortunately need to be able to generate anonymous types in the compiler, x.even for example (take the even-indexed elements of a vector) may be a type that is undeclared. And if you want to be able to pretty-print that, you need to be able to generate a type without a name, which makes #[simd] struct { ? } impossible. > > You could just pre-declare all possible options up to 256-bit long, which probably would only be a hundred types or so, but would feel a bit silly. > > There are also other operations that could generate (possibly) unnamed types, like a == b, which should generate a i1-vector, or a shufflevector intrinsic that could generate vectors of any length. > > Ps. I didn't think of #[simd] (T, T, T, T) &c. before implementing (sanxiyn gave me that idea), but I still think that is probably a worse idea than adding SIMD as an additional type with actual syntax. > > [0]: http://www.khronos.org/files/opencl-quick-reference-card.pdf, page 2, "Vector Component Addressing" > [1]: https://github.com/jensnockert/rust/tree/simd > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From bjzaba at yahoo.com.au Tue Jul 16 03:13:14 2013 From: bjzaba at yahoo.com.au (Brendan Zabarauskas) Date: Tue, 16 Jul 2013 20:13:14 +1000 Subject: [rust-dev] OpenCL-style accessors, casts. In-Reply-To: <7FAF959C-7564-4691-A16D-98C90B238AB2@nockert.se> References: <7FAF959C-7564-4691-A16D-98C90B238AB2@nockert.se> Message-ID: > Introducing a new t, ty_simd_vec(t, uint), instead of using the current #[simd] struct { ? }, is yet another thing that is controversial about the patch This is indeed a shame because named fields are very nice for clean, self-documenting apis. Perhaps properties solve this, but I don't think there would be much will to add more features considering all the work that still has to be done (I could be wrong though). ~Brendan On 16/07/2013, at 2:27 PM, Jens Nockert wrote: > Hello rust-dev! > > I implemented OpenCL-style[0] accessors for SIMD types in Rust[1], the code quality isn't near /merge-worthy yet, but I wanted some input. > > For some code-examples, go to https://github.com/jensnockert/rust/tree/simd/src/test/run-pass/simd-test and check it out, you should be able to get the idea of how they work. > > Note that I didn't add any actual syntax for vector types yet (since it would be highly controversial and I don't know what would be the best option), so I just added a simd!(name: T * n) syntax extension that declares a new type that maps down to a LLVM . > > My preference for syntax right now would be simd!(n x T) if I can get that to parse, or simd!(T, ..n). And then you would declare a type with type f32x4 = simd(4 x f32); and it would magically work. Another option would be some variant of the [T, ..n] syntax used for fixed-length vectors. > > Introducing a new t, ty_simd_vec(t, uint), instead of using the current #[simd] struct { ? }, is yet another thing that is controversial about the patch and this needs a bit of explanation of the problem with #[simd] struct { ? }. > > To be able to make these accessors work, you unfortunately need to be able to generate anonymous types in the compiler, x.even for example (take the even-indexed elements of a vector) may be a type that is undeclared. And if you want to be able to pretty-print that, you need to be able to generate a type without a name, which makes #[simd] struct { ? } impossible. > > You could just pre-declare all possible options up to 256-bit long, which probably would only be a hundred types or so, but would feel a bit silly. > > There are also other operations that could generate (possibly) unnamed types, like a == b, which should generate a i1-vector, or a shufflevector intrinsic that could generate vectors of any length. > > Ps. I didn't think of #[simd] (T, T, T, T) &c. before implementing (sanxiyn gave me that idea), but I still think that is probably a worse idea than adding SIMD as an additional type with actual syntax. > > [0]: http://www.khronos.org/files/opencl-quick-reference-card.pdf, page 2, "Vector Component Addressing" > [1]: https://github.com/jensnockert/rust/tree/simd > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From bjzaba at yahoo.com.au Tue Jul 16 05:07:38 2013 From: bjzaba at yahoo.com.au (Brendan Zabarauskas) Date: Tue, 16 Jul 2013 22:07:38 +1000 Subject: [rust-dev] OpenCL-style accessors, casts. In-Reply-To: References: <7FAF959C-7564-4691-A16D-98C90B238AB2@nockert.se> Message-ID: <369D3947-64BE-447B-A20B-C443B6E513AD@yahoo.com.au> I'm not saying that the shuffles would have to be generated using the field names - that would be near impossible. For example: ~~~ #[simd] struct RGB { r: T, g: T, b: T, a: T } ~~~ Shuffling would still use the CL syntax: ~~~ let v2 = v.s3201 ~~~ I would be really interested to hear what sanxiyn had in mind for #[simd] when he added it. Relevant PRs with discussions: https://github.com/mozilla/rust/pull/5841 https://github.com/mozilla/rust/pull/6214 https://github.com/mozilla/rust/pull/7705 ~Brendan On 16/07/2013, at 9:06 PM, Jens Nockert wrote: > On H.25/07/16, at 12:13, Brendan Zabarauskas wrote: > >>> Introducing a new t, ty_simd_vec(t, uint), instead of using the current #[simd] struct { ? }, is yet another thing that is controversial about the patch >> >> This is indeed a shame because named fields are very nice for clean, self-documenting apis. Perhaps properties solve this, but I don't think there would be much will to add more features considering all the work that still has to be done (I could be wrong though). > > While nice, I don't think this is a good idea. > > It leads to very complex shuffle-syntax, and makes intrinsics and anything else with a T1 (x T1) -> T2 type signature (comparisons, non-bitwise casts) much harder to call and implement. > > It would also mean that all intrinsics would have to be generic. And that you need to pattern-match match in trans to generate shufflevector operations. > > Examples, > > ~~~ OpenCL shuffle > let v2 = v.abgr; > ~~~ Named property shuffle > let v2 = match v1 { rgba { r:r, b:b, g:g, a:a } => rgba { r:a, g:b, b:g, a:r } }; > ~~~ > > And that isn't even the degenerate case of wanting to replace the order of a subset of the elements of a u8x16-like type which succintly can be described in OpenCl-like syntax. > > ~~~ > v1.s89 = v1.s98; // or for complex arithmetic > let i0 = a * b; > r.even = i0.even - i0.odd; > r.odd = a.odd * b.even + a.even * b.odd; > ~~~ > > And these I cannot write the named-property variants of on my phone, so you will have to imagine what they would look like. > From svetoslav at neykov.name Tue Jul 16 10:52:37 2013 From: svetoslav at neykov.name (Svetoslav Neykov) Date: Tue, 16 Jul 2013 20:52:37 +0300 Subject: [rust-dev] Rust on bare metal ARM - sample project Message-ID: <031401ce824d$434410f0$c9cc32d0$@neykov.name> On 15.07. 13 23:37, Patrick Walton wrote: >On 7/14/13 1:04 PM, Svetoslav Neykov wrote: >> ."unsafe" is not a normal block and doesn't return a value, can't be >> used as an expression. This made it impossible to wrap the unsafe casts >> from fixed memory locations to borrowed pointers in macros. Instead I >> had to use inline functions and assign the resulting value to a local >> function variable. > >This should not be the case. There may be a bug in the way macros >interact with unsafe checking. Do you have a test case by any chance? Yes, my bad. I double checked, there is no problem using "unsafe" as an expression or wrapping it inside of a macro. The real problem, turns out, is that the macro can't be used as an expression unless wrapped inside parentheses. GPIOD!().MODER //doesn't compile (error: unexpected token: `.`) (GPIOD!()).MODER //OK Svetoslav. -------------- next part -------------- An HTML attachment was scrubbed... URL: From pnkfelix at mozilla.com Tue Jul 16 11:03:50 2013 From: pnkfelix at mozilla.com (Felix S. Klock II) Date: Tue, 16 Jul 2013 20:03:50 +0200 Subject: [rust-dev] Rust on bare metal ARM - sample project In-Reply-To: <031401ce824d$434410f0$c9cc32d0$@neykov.name> References: <031401ce824d$434410f0$c9cc32d0$@neykov.name> Message-ID: <51E58B06.9040003@mozilla.com> On 16/07/2013 19:52, Svetoslav Neykov wrote: > > On 15.07.13 23:37, Patrick Walton wrote: > > >On 7/14/13 1:04 PM, Svetoslav Neykov wrote: > > >> ?"unsafe" is not a normal block and doesn't return a value, can't be > > >> used as an expression. This made it impossible to wrap the unsafe casts > > >> from fixed memory locations to borrowed pointers in macros. Instead I > > >> had to use inline functions and assign the resulting value to a local > > >> function variable. > > > > > >This should not be the case. There may be a bug in the way macros > > >interact with unsafe checking. Do you have a test case by any chance? > > Yes, my bad. I double checked, there is no problem using "unsafe" as > an expression or wrapping it inside of a macro. > > The real problem, turns out, is that the macro can't be used as an > expression unless wrapped inside parentheses. > > GPIOD!().MODER //doesn't compile (error: unexpected token: `.`) > > (GPIOD!()).MODER //OK > > Svetoslav. > > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev Yes I believe this is filed under the following ticket: " Syntax extensions (and macros) that start a line want to be a whole statement" https://github.com/mozilla/rust/issues/5941 (I noted on that bug that we could probably provide a better error message here.) Cheers, -Felix -- irc: pnkfelix on irc.mozilla.org email: {fklock, pnkfelix}@mozilla.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From daede003 at umn.edu Tue Jul 16 11:08:24 2013 From: daede003 at umn.edu (Thomas Daede) Date: Tue, 16 Jul 2013 13:08:24 -0500 Subject: [rust-dev] Rust on bare metal ARM - sample project In-Reply-To: <000101ce80cd$60dbc670$22935350$@neykov.name> References: <000101ce80cd$60dbc670$22935350$@neykov.name> Message-ID: On Sun, Jul 14, 2013 at 3:04 PM, Svetoslav Neykov wrote: > Hello, > > My interest in Rust is from the point of view of an embedded > microcontrollers running bare metal programs with no underlying OS. I > decided to explore what the language offers in that space by creating an > actual running program. For the target I used STM32F4Discovery board since > it has an ARM CPU which is already supported by the compiler. What is > special about this board with comparison to the Android port is that it has > only 192K internal memory (no SDRAM) and no MMU. > > > > You can find the project at https://github.com/neykov/armboot. > > > > For the first step I chose the fastest approach possible ? to generate an > intermediate .ll, convert it to assembler and compile it with the gcc > cross-compiler for the target (arm-none-eabi). One change was required to > the compiler to skip the generation of function prologue for split stacks > (see https://raw.github.com/neykov/armboot/master/rustc.patch). This version > supports only static memory allocation, though heap access (owned pointers) > is easily implemented (i.e. use malloc/free linked to newlib). Zero.rs is > used so no managed pointers and garbage collection. > > The generation of the executable file is automated. After generation the .ll > file is corrected so it works with unpatched llvm 3.4 and the .note.rustc > section is removed so it doesn?t take space on the target device. > > > > Major points from the effort: > > ? I ported a basic C program to equivalent safe Rust program (see > main.rs vs blinky.c). It is interesting because it uses an interrupt > callback for the actual blinking logic. > > ? The platform definitions were needed ? like IO register locations > and memory layout. I created a subset of them, mostly by hand, taking the > output from rust-bindgen for the structures. All the #defines and enums had > to be created as macros so as not to allocate actual memory on the device if > declared as static (which I tried and ran out of memory J ). This is > somewhat cumbersome since it requires adding ?!()? but not a huge problem. > > ? ?unsafe? is not a normal block and doesn?t return a value, can?t > be used as an expression. This made it impossible to wrap the unsafe casts > from fixed memory locations to borrowed pointers in macros. Instead I had to > use inline functions and assign the resulting value to a local function > variable. > > ? No ?volatile? equivalent in Rust ? currently all code is compiled > with disabled optimizations so IO code is not optimized away. Another > possible workaround is to use extern ?C? functions to do the actual hardware > communication. > > ? I couldn?t move the platform code to a separate library since > macros can?t be exported (I saw that this is still a work in progress > according to #3114 so not a long term problem). > > ? There were problems with the code comments in the original source > files (i.e. see > https://github.com/neykov/armboot/blob/master/sys/inc/stm32f4xx.h). I got > compile-time errors because of the special symbol combinations in them which > are reserved in Rust. > > ? No core/std since I used zero.rs. > > > > As a future development I will look into adding support for the > arm-none-eabi target by the Rust compiler and getting at least part of > ?core? working on the target device in memory constrained environment. > > > > Svetoslav > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > This is really exciting! I'm actually working on something very similar, but didn't get nearly as far as you - I made a post about it on the mailing list a month back: https://mail.mozilla.org/pipermail/rust-dev/2013-June/004538.html I started with the same approach as you, generating the LLVM bytecode intermediate, pushing it through the LLVM compiler externally, then using gcc-arm-embedded's linker combined with libopencm3. However, I also quickly ran into the issue of the runtime, and decided to start instead with slowly porting the standard library away from OS dependencies (made harder due to in being in flux at the moment). I have the exact same hardware as you do, so when I have more time next week I'll see if I can run your script. - Thomas From graydon at mozilla.com Tue Jul 16 17:33:45 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 16 Jul 2013 17:33:45 -0700 Subject: [rust-dev] perf metrics and ratchets Message-ID: <51E5E669.7000500@mozilla.com> Hi, I've added some new machinery to the testing systems in rust and wanted to draw a little attention to them. At least this will all be true shortly when https://github.com/mozilla/rust/pull/7829 lands. They're (lightly) documented at the bottom of: https://github.com/mozilla/rust/wiki/Doc-unit-testing and https://github.com/mozilla/rust/wiki/Note-testsuite The point-form version is: - #[bench] tests can now save their results as json. run the testrunner with --save-metrics=foo.json - If you want to avoid regressing on something, use --ratchet-metrics=foo.json instead; it will save and reload with each run, and consider any regression beyond a given noise threshold to be a test-fail. (Removing, renaming, omitting or adding metrics does not cause failure. it emits a warning and assumes you meant to do it.) - If you configure with --ratchet-bench then all the crate #[bench] benchmarks will be ratcheted in your workspace. We will turn this on on the buildbot soon-ish. At that point, adding a #[bench] function will make it impervious to perf regressions, so add them regularly but also with some care and thought. - If you're on a particularly noisy machine, you can override the inferred noise thresholds with --ratchet-noise-percent=N - There are new compiletests in src/test/codegen. These consist of pairs of files, foo.rs and foo.cc, each containing a non-mangled extern C function 'test'. The runner will compile the rust one with rustc and the C++ one with clang, extract their LLVM bitcode, disassemble it and compare the sizes. The result is recorded in a metrics file and _ratcheted by default_. - The codegen tests also leave behind foo-extract.ll and foo-clang-extract.ll files, which are helpful for eyeballing problems in our codegen. Please populate the codegen directory liberally. All you need to do is write a function in rust and a function that "does the same thing" in C++. If you have any questions, or find none of it works for you and want help making it work, please let me know. I'll hopefully turn on --ratchet-bench and export the metrics files from the buildbot soon. -Graydon From jens at nockert.se Tue Jul 16 19:50:11 2013 From: jens at nockert.se (Jens Nockert) Date: Wed, 17 Jul 2013 04:50:11 +0200 Subject: [rust-dev] Fwd: OpenCL-style accessors, casts. References: <4B95985E-8AE1-4419-811E-422697F9F7FC@nockert.se> Message-ID: Begin forwarded message: > From: Jens Nockert > Subject: Re: [rust-dev] OpenCL-style accessors, casts. > Date: 16 July 2013 14:36:34 CEST > To: Brendan Zabarauskas > > > On 16 Jul 2013, at 14:07, Brendan Zabarauskas wrote: > >> I'm not saying that the shuffles would have to be generated using the field names - that would be near impossible. >> >> For example: >> >> ~~~ >> #[simd] struct RGB { r: T, g: T, b: T, a: T } >> ~~~ >> >> Shuffling would still use the CL syntax: >> >> ~~~ >> let v2 = v.s3201 >> ~~~ > > > But then they would not behave like structs at all anymore, and you would see someone do something silly like define Vertex { w:f32, x:f32, y:f32, z:f32 } and try to access .w and get the value for z. > > And it only solves a small part of the problem, what is the type of a componentwise (v1 == v2), where v1, v2 are RGB ? Ps. Sorry bjz that you get duplicate messages, it was early and I replied only to you. -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Tue Jul 16 23:52:08 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Tue, 16 Jul 2013 23:52:08 -0700 Subject: [rust-dev] "copy" is going away Message-ID: <51E63F18.1090905@mozilla.com> Just a quick note that I have a pull request in the queue to remove the "copy" expression in favor of the "clone" method. Please try to avoid using "copy" in your pull requests, or you will cause mine to bounce. (It has already bounced somewhere between 5 and 8 times, I lost count.) Thanks, Patrick From niko at alum.mit.edu Wed Jul 17 03:50:24 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 17 Jul 2013 06:50:24 -0400 Subject: [rust-dev] "copy" is going away In-Reply-To: <51E63F18.1090905@mozilla.com> References: <51E63F18.1090905@mozilla.com> Message-ID: <20130717105024.GH22848@Mr-Bennet> On Tue, Jul 16, 2013 at 11:52:08PM -0700, Patrick Walton wrote: > Just a quick note that I have a pull request in the queue to remove > the "copy" expression in favor of the "clone" method. Please try to > avoid using "copy" in your pull requests, or you will cause mine to > bounce. (It has already bounced somewhere between 5 and 8 times, I > lost count.) Can we just close the tree? This seems like one of those causes that merits it. Niko From ben.striegel at gmail.com Wed Jul 17 09:07:08 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Wed, 17 Jul 2013 12:07:08 -0400 Subject: [rust-dev] perf metrics and ratchets In-Reply-To: <51E5E669.7000500@mozilla.com> References: <51E5E669.7000500@mozilla.com> Message-ID: This is all fantastic, especially the codegen tests. Does buildbot record the codegen tests in a way such that they're potentially trackable on isrustfastyet? On Tue, Jul 16, 2013 at 8:33 PM, Graydon Hoare wrote: > Hi, > > I've added some new machinery to the testing systems in rust and wanted > to draw a little attention to them. At least this will all be true > shortly when https://github.com/mozilla/rust/pull/7829 lands. > > They're (lightly) documented at the bottom of: > > https://github.com/mozilla/rust/wiki/Doc-unit-testing > > and > > https://github.com/mozilla/rust/wiki/Note-testsuite > > The point-form version is: > > - #[bench] tests can now save their results as json. > run the testrunner with --save-metrics=foo.json > > - If you want to avoid regressing on something, use > --ratchet-metrics=foo.json instead; it will save and > reload with each run, and consider any regression beyond > a given noise threshold to be a test-fail. > > (Removing, renaming, omitting or adding metrics does not cause > failure. it emits a warning and assumes you meant to do it.) > > - If you configure with --ratchet-bench then all the crate #[bench] > benchmarks will be ratcheted in your workspace. We will turn this > on on the buildbot soon-ish. At that point, adding a #[bench] > function will make it impervious to perf regressions, so add them > regularly but also with some care and thought. > > - If you're on a particularly noisy machine, you can override the > inferred noise thresholds with --ratchet-noise-percent=N > > - There are new compiletests in src/test/codegen. These consist > of pairs of files, foo.rs and foo.cc, each containing a non-mangled > extern C function 'test'. The runner will compile the rust one with > rustc and the C++ one with clang, extract their LLVM bitcode, > disassemble it and compare the sizes. The result is recorded in > a metrics file and _ratcheted by default_. > > - The codegen tests also leave behind foo-extract.ll and > foo-clang-extract.ll files, which are helpful for eyeballing > problems in our codegen. Please populate the codegen directory > liberally. All you need to do is write a function in rust and > a function that "does the same thing" in C++. > > If you have any questions, or find none of it works for you and want > help making it work, please let me know. I'll hopefully turn on > --ratchet-bench and export the metrics files from the buildbot soon. > > -Graydon > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Wed Jul 17 09:25:14 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 17 Jul 2013 09:25:14 -0700 Subject: [rust-dev] perf metrics and ratchets In-Reply-To: References: <51E5E669.7000500@mozilla.com> Message-ID: <51E6C56A.4050108@mozilla.com> On 13-07-17 09:07 AM, Benjamin Striegel wrote: > This is all fantastic, especially the codegen tests. Does buildbot > record the codegen tests in a way such that they're potentially > trackable on isrustfastyet? Not quite yet, but (when I make time to finish this part) buildbot will grab all the metrics of all the tests and make them public someplace for further analysis. That's definitely part of the plot here, yes. -Graydon From graydon at mozilla.com Wed Jul 17 10:22:22 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 17 Jul 2013 10:22:22 -0700 Subject: [rust-dev] "copy" is going away In-Reply-To: <20130717105024.GH22848@Mr-Bennet> References: <51E63F18.1090905@mozilla.com> <20130717105024.GH22848@Mr-Bennet> Message-ID: <51E6D2CE.50005@mozilla.com> On 13-07-17 03:50 AM, Niko Matsakis wrote: > On Tue, Jul 16, 2013 at 11:52:08PM -0700, Patrick Walton wrote: >> Just a quick note that I have a pull request in the queue to remove >> the "copy" expression in favor of the "clone" method. Please try to >> avoid using "copy" in your pull requests, or you will cause mine to >> bounce. (It has already bounced somewhere between 5 and 8 times, I >> lost count.) > > Can we just close the tree? This seems like one of those causes that > merits it. I'd be fine with that. Catch me on IRC to co-ordinate, I'll suspend bors while you line it up. -Graydon From banderson at mozilla.com Wed Jul 17 10:35:58 2013 From: banderson at mozilla.com (Brian Anderson) Date: Wed, 17 Jul 2013 10:35:58 -0700 Subject: [rust-dev] Test suite uses too many open fds In-Reply-To: References: Message-ID: <51E6D5FE.1080101@mozilla.com> On 07/13/2013 01:19 PM, Kevin Ballard wrote: > Last night I tracked down why `make check-stage2-std` no longer works > on my computer. This is documented in issue > https://github.com/mozilla/rust/issues/7772. In summary, the test > runner now uses num_cpus*2 threads instead of 4 threads, which ends up > being 16 on my machine, and this causes the process to run out of fds. > > Why is the test suite using so many fds? lsof says most of them are > PIPEs. What are those being used for? > > -Kevin > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev I replied in the issue tracker, but the new scheduler is based on libuv, which works by waiting on fds, and the test suite does aggressive testing of the scheduler, which eats up a lot of fds. I had to raise the ulimit on the mac bots to land it. There are two overcommits involved in the test suite now that could be contributing to this problem: first, as you pointed out, the multithreaded scheduler tests create num_cpus * 2 scheduler threads each; second, the normal test runner creates num_cpus * 4 test tasks. Each scheduler I believe needs a minimum of 2 fds, one for the kqueue (I think), and a second for an async handle. So at any time while running stdtest you may need at least num_cpus * 2 * 4 * 2 = 64 fds, and undoubtedly there are even more that I'm not aware of. There may also be some inefficiencies here too, e.g. we create too many idle handles (though I don't think those require an fd). From banderson at mozilla.com Wed Jul 17 10:37:48 2013 From: banderson at mozilla.com (Brian Anderson) Date: Wed, 17 Jul 2013 10:37:48 -0700 Subject: [rust-dev] Test suite uses too many open fds In-Reply-To: <51E6D5FE.1080101@mozilla.com> References: <51E6D5FE.1080101@mozilla.com> Message-ID: <51E6D66C.3010305@mozilla.com> On 07/17/2013 10:35 AM, Brian Anderson wrote: > On 07/13/2013 01:19 PM, Kevin Ballard wrote: >> Last night I tracked down why `make check-stage2-std` no longer works >> on my computer. This is documented in issue >> https://github.com/mozilla/rust/issues/7772. In summary, the test >> runner now uses num_cpus*2 threads instead of 4 threads, which ends up >> being 16 on my machine, and this causes the process to run out of fds. >> >> Why is the test suite using so many fds? lsof says most of them are >> PIPEs. What are those being used for? >> >> -Kevin >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev > > I replied in the issue tracker, but the new scheduler is based on > libuv, which works by waiting on fds, and the test suite does > aggressive testing of the scheduler, which eats up a lot of fds. I had > to raise the ulimit on the mac bots to land it. > > There are two overcommits involved in the test suite now that could be > contributing to this problem: first, as you pointed out, the > multithreaded scheduler tests create num_cpus * 2 scheduler threads > each; second, the normal test runner creates num_cpus * 4 test tasks. > > Each scheduler I believe needs a minimum of 2 fds, one for the kqueue > (I think), and a second for an async handle. So at any time while > running stdtest you may need at least num_cpus * 2 * 4 * 2 = 64 fds, > and undoubtedly there are even more that I'm not aware of. > > There may also be some inefficiencies here too, e.g. we create too > many idle handles (though I don't think those require an fd). > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev Uh, that math was wrong. num_cpus * 2 * num_cpus * 4 * 2 = 256 :) From graydon at mozilla.com Wed Jul 17 11:34:12 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 17 Jul 2013 11:34:12 -0700 Subject: [rust-dev] Test suite uses too many open fds In-Reply-To: <51E6D66C.3010305@mozilla.com> References: <51E6D5FE.1080101@mozilla.com> <51E6D66C.3010305@mozilla.com> Message-ID: <51E6E3A4.1020200@mozilla.com> On 13-07-17 10:37 AM, Brian Anderson wrote: > Uh, that math was wrong. num_cpus * 2 * num_cpus * 4 * 2 = 256 :) I'm a bit confused here. Is the arithmetic based on the notion of "num_cpus * 4" test-tasks running at once (let's say 32 tasks, on an 8-way machine) all doing MT-scheduler testing at the same time, thus making "num_cpus * 2 * 2" (i.e. 32) fds? I would also point out that the testsuite runs subprocesses on pipes and thus chews up 3 more fds per subprocess. They get recycled but only when the subprocess is dropped. -Graydon From banderson at mozilla.com Wed Jul 17 11:37:24 2013 From: banderson at mozilla.com (Brian Anderson) Date: Wed, 17 Jul 2013 11:37:24 -0700 Subject: [rust-dev] Test suite uses too many open fds In-Reply-To: <51E6E3A4.1020200@mozilla.com> References: <51E6D5FE.1080101@mozilla.com> <51E6D66C.3010305@mozilla.com> <51E6E3A4.1020200@mozilla.com> Message-ID: <51E6E464.3060906@mozilla.com> On 07/17/2013 11:34 AM, Graydon Hoare wrote: > On 13-07-17 10:37 AM, Brian Anderson wrote: > >> Uh, that math was wrong. num_cpus * 2 * num_cpus * 4 * 2 = 256 :) > > I'm a bit confused here. Is the arithmetic based on the notion of > "num_cpus * 4" test-tasks running at once (let's say 32 tasks, on an > 8-way machine) all doing MT-scheduler testing at the same time, thus > making "num_cpus * 2 * 2" (i.e. 32) fds? There are num_cpus * 4 test tasks created by extra::test. Then each of the scheduler tests in stdtest creates num_cpus * 2 scheduler threads. Resulting in possibly (num_cpus * 4) * (num_cpus * 2) threads, times 2 fds per thread. > > I would also point out that the testsuite runs subprocesses on pipes > and thus chews up 3 more fds per subprocess. They get recycled but > only when the subprocess is dropped. That does not apply to stdtest, where the scheduler tests are located, but only to the tests run by the compiletest driver. From tohava at gmail.com Wed Jul 17 11:42:39 2013 From: tohava at gmail.com (ori bar) Date: Wed, 17 Jul 2013 21:42:39 +0300 Subject: [rust-dev] Warning about gmail inbox tabs Message-ID: gmail has recently added a tabs interface in its inbox. For some reason, this interface filters out many rust-dev messages as 'promotions'. Please recommend people in this list to disable/reconfigure it. -- 1110101111111110 - it's a way of life -------------- next part -------------- An HTML attachment was scrubbed... URL: From ben.striegel at gmail.com Wed Jul 17 13:46:01 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Wed, 17 Jul 2013 16:46:01 -0400 Subject: [rust-dev] Warning about gmail inbox tabs In-Reply-To: References: Message-ID: AFAICT it should be possible to bypass this auto-filtering by setting up a filter of your own for messages from rust-dev at mozilla.org. On Wed, Jul 17, 2013 at 2:42 PM, ori bar wrote: > gmail has recently added a tabs interface in its inbox. For some reason, > this interface filters out many rust-dev messages as 'promotions'. Please > recommend people in this list to disable/reconfigure it. > > -- > 1110101111111110 - it's a way of life > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From svetoslav at neykov.name Wed Jul 17 14:03:14 2013 From: svetoslav at neykov.name (Svetoslav Neykov) Date: Thu, 18 Jul 2013 00:03:14 +0300 Subject: [rust-dev] Rust on bare metal ARM - sample project In-Reply-To: References: <000101ce80cd$60dbc670$22935350$@neykov.name> Message-ID: <05ad01ce8331$0e643f10$2b2cbd30$@neykov.name> On Tue, 16 Jul 2013 13:08:24 -0500 Thomas Daede wrote: >This is really exciting! I'm actually working on something very >similar, but didn't get nearly as far as you - I made a post about it >on the mailing list a month back: >https://mail.mozilla.org/pipermail/rust-dev/2013-June/004538.html > >I started with the same approach as you, generating the LLVM bytecode >intermediate, pushing it through the LLVM compiler externally, then >using gcc-arm-embedded's linker combined with libopencm3. However, I >also quickly ran into the issue of the runtime, and decided to start >instead with slowly porting the standard library away from OS >dependencies (made harder due to in being in flux at the moment). > >I have the exact same hardware as you do, so when I have more time >next week I'll see if I can run your script. It's reassuring to see I am not the only one working on this platform. We can work together to add support for it. By standard library do you mean std or extra? Is there something specific you needed the standard library for? Why did you decide to start working on it initially? Svetoslav. From graydon at mozilla.com Wed Jul 17 14:35:09 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 17 Jul 2013 14:35:09 -0700 Subject: [rust-dev] Test suite uses too many open fds In-Reply-To: <51E6E464.3060906@mozilla.com> References: <51E6D5FE.1080101@mozilla.com> <51E6D66C.3010305@mozilla.com> <51E6E3A4.1020200@mozilla.com> <51E6E464.3060906@mozilla.com> Message-ID: <51E70E0D.60306@mozilla.com> On 13-07-17 11:37 AM, Brian Anderson wrote: > That does not apply to stdtest, where the scheduler tests are located, > but only to the tests run by the compiletest driver. Oh yeah, failing in stdtest, sorry. Misread. -Graydon From bjzaba at yahoo.com.au Wed Jul 17 15:56:27 2013 From: bjzaba at yahoo.com.au (Brendan Zabarauskas) Date: Thu, 18 Jul 2013 08:56:27 +1000 Subject: [rust-dev] OpenCL-style accessors, casts. In-Reply-To: <7FAF959C-7564-4691-A16D-98C90B238AB2@nockert.se> References: <7FAF959C-7564-4691-A16D-98C90B238AB2@nockert.se> Message-ID: Just so folks have the heads up, here is the discussion of the blog post on reddit: http://www.reddit.com/r/rust/comments/1igvye/vision_for_rust_simd/ ~Brendan On 16/07/2013, at 2:27 PM, Jens Nockert wrote: > Hello rust-dev! > > I implemented OpenCL-style[0] accessors for SIMD types in Rust[1], the code quality isn't near /merge-worthy yet, but I wanted some input. > > For some code-examples, go to https://github.com/jensnockert/rust/tree/simd/src/test/run-pass/simd-test and check it out, you should be able to get the idea of how they work. > > Note that I didn't add any actual syntax for vector types yet (since it would be highly controversial and I don't know what would be the best option), so I just added a simd!(name: T * n) syntax extension that declares a new type that maps down to a LLVM . > > My preference for syntax right now would be simd!(n x T) if I can get that to parse, or simd!(T, ..n). And then you would declare a type with type f32x4 = simd(4 x f32); and it would magically work. Another option would be some variant of the [T, ..n] syntax used for fixed-length vectors. > > Introducing a new t, ty_simd_vec(t, uint), instead of using the current #[simd] struct { ? }, is yet another thing that is controversial about the patch and this needs a bit of explanation of the problem with #[simd] struct { ? }. > > To be able to make these accessors work, you unfortunately need to be able to generate anonymous types in the compiler, x.even for example (take the even-indexed elements of a vector) may be a type that is undeclared. And if you want to be able to pretty-print that, you need to be able to generate a type without a name, which makes #[simd] struct { ? } impossible. > > You could just pre-declare all possible options up to 256-bit long, which probably would only be a hundred types or so, but would feel a bit silly. > > There are also other operations that could generate (possibly) unnamed types, like a == b, which should generate a i1-vector, or a shufflevector intrinsic that could generate vectors of any length. > > Ps. I didn't think of #[simd] (T, T, T, T) &c. before implementing (sanxiyn gave me that idea), but I still think that is probably a worse idea than adding SIMD as an additional type with actual syntax. > > [0]: http://www.khronos.org/files/opencl-quick-reference-card.pdf, page 2, "Vector Component Addressing" > [1]: https://github.com/jensnockert/rust/tree/simd > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From corey at octayn.net Wed Jul 17 16:06:58 2013 From: corey at octayn.net (Corey Richardson) Date: Wed, 17 Jul 2013 19:06:58 -0400 Subject: [rust-dev] PSA: E-needstest Message-ID: Hello all, If you're very attentive, you'll have noticed that there's a new label starting to pop up: E-needstest. This label indicates that an issue needs a testcase in the testsuite before it can be closed. This can be joined with B-clarifying if it needs to be determined what exactly the bug was, and/or E-easy if it's trivial (for example, a testcase is already in the issue, just needs to be added to the suite). This is a good way for new contributors to get their feet wet. Triagers: please don't close an issue that doesn't reproduce that doesn't have a testcase, mark it E-needstest! From bklooste at gmail.com Thu Jul 18 04:09:34 2013 From: bklooste at gmail.com (Bennie Kloosteman) Date: Thu, 18 Jul 2013 19:09:34 +0800 Subject: [rust-dev] traits Message-ID: Can somebody either explain the following questions about Rust, or point me to a description, or (ideally) both? 1. I'm compiling the source code for some crate, and I need a trait implementation. Over what scope is the instance resolution search performed? [Following assume that the answer is "over the crate being compiled"] 2. I'm compiling a library crate. A parameter of type T crosses the interface boundary of this library, and the library does something that requires an implementation of MyTrait. How is the implementation of MyTrait obtained? Ben -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Thu Jul 18 04:24:07 2013 From: corey at octayn.net (Corey Richardson) Date: Thu, 18 Jul 2013 07:24:07 -0400 Subject: [rust-dev] Automatic Clone Derivation Proposal Message-ID: So with decopy landed we now have no way to copy things that does not require author intervention. And I am ok with this! Clone is much more flexible, less magic, etc. I see one problem with this though: we have no way to copy things that does not require author intervention. For example, I ran into this with rustdoc_ng: there is no Clone implementation for syntax::ast::struct_def. There's no reason it couldn't have one, it's just that it wasn't needed to be cloned, so an implementation wasn't added (via #[deriving(Clone)]). This is a problem. If a library author overlooks something that could/should have Clone, users of that library are now with no way to copy. I propose the following: If a given struct/enum has no Clone implementation, it fulfills the requirements of the now-gone Copy kind, and the #[no_clone] attribute is not present, #[deriving(Clone)] is automatically applied to it. I'm not that fond of this sort of magic but it seems to be necessary: library authors aren't perfect, and a simple oversight can harmfully limiting what can be done with its types. From ben.striegel at gmail.com Thu Jul 18 06:36:22 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Thu, 18 Jul 2013 09:36:22 -0400 Subject: [rust-dev] Automatic Clone Derivation Proposal In-Reply-To: References: Message-ID: I agree that this is a huge headache waiting to happen. It's our own version of the const-correctness problem. We do already have a notion of "opt-out" kinds via #[no_freeze] and #[no_send], so this isn't entirely unprecedented. It would also be good to know how often one needs custom copy behavior. >From just looking at rustc: git grep "impl.*Clone for" | wc -l # 62 manual implementations (though 11 are just from clone.rs) git grep "#\[deriving.*Clone" | wc -l # 290 derived implementations On Thu, Jul 18, 2013 at 7:24 AM, Corey Richardson wrote: > So with decopy landed we now have no way to copy things that does not > require author intervention. And I am ok with this! Clone is much more > flexible, less magic, etc. I see one problem with this though: we have > no way to copy things that does not require author intervention. > > For example, I ran into this with rustdoc_ng: there is no Clone > implementation for syntax::ast::struct_def. There's no reason it > couldn't have one, it's just that it wasn't needed to be cloned, so an > implementation wasn't added (via #[deriving(Clone)]). > > This is a problem. If a library author overlooks something that > could/should have Clone, users of that library are now with no way to > copy. > > I propose the following: > > If a given struct/enum has no Clone implementation, it fulfills the > requirements of the now-gone Copy kind, and the #[no_clone] attribute > is not present, #[deriving(Clone)] is automatically applied to it. > > I'm not that fond of this sort of magic but it seems to be necessary: > library authors aren't perfect, and a simple oversight can harmfully > limiting what can be done with its types. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Thu Jul 18 09:18:20 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 18 Jul 2013 09:18:20 -0700 Subject: [rust-dev] Automatic Clone Derivation Proposal In-Reply-To: References: Message-ID: <51E8154C.8000206@mozilla.com> On 13-07-18 06:36 AM, Benjamin Striegel wrote: > I agree that this is a huge headache waiting to happen. It's our own > version of the const-correctness problem. It also occurs with other "obvious utility impls" like totalord and iterbytes, when someone decides to use a struct as a key in a hash or tree map without the person who made that struct picturing that use case. You can kinda work around these by doing a newtype struct, but it's clunky. And you can only do so if the struct you're wrapping has all-public fields. I'm hitting this in workcache and json now. Stuff that the author didn't think to make cloneable or comparable impls for. Since I'm in the same source tree now I can fix it, but if it was in a different crate I didn't control, I'd be out of luck. -Graydon From jack at metajack.im Thu Jul 18 09:55:34 2013 From: jack at metajack.im (Jack Moffitt) Date: Thu, 18 Jul 2013 10:55:34 -0600 Subject: [rust-dev] Automatic Clone Derivation Proposal In-Reply-To: <51E8154C.8000206@mozilla.com> References: <51E8154C.8000206@mozilla.com> Message-ID: > I'm hitting this in workcache and json now. Stuff that the author didn't > think to make cloneable or comparable impls for. Since I'm in the same > source tree now I can fix it, but if it was in a different crate I didn't > control, I'd be out of luck. After converting Servo to Rust 0.6, I had to go an add a few Clones in libstd. If we decide not to automatically derive Clone then some kind of systematic pass on libstd and libextra will be necessary to make sure none are missing. Missing Clones in libstd and libextra are the worst offenders because not only do you have to add them, but every downstream consumer must upgrade Rust to get the change too. jack. From sadams58 at woh.rr.com Wed Jul 17 12:11:17 2013 From: sadams58 at woh.rr.com (Steve Adams) Date: Wed, 17 Jul 2013 15:11:17 -0400 Subject: [rust-dev] does not build on build on VectorLinux 7 on ThinkPad T23 Message-ID: <51E6EC55.1050801@woh.rr.com> I have build the 0.5 and up releases on ThinkPad T23 systems running Anti-X, CrunchBang and Lubuntu with no problems. However, it always fails with a compiler error when trying to build on VectorLinux 7. Also, regardless of which system I use to build, it takes many hours to do a build. Will this be changing in future releases? From loebel.marvin at gmail.com Thu Jul 18 06:51:52 2013 From: loebel.marvin at gmail.com (=?ISO-8859-1?Q?Marvin_L=F6bel?=) Date: Thu, 18 Jul 2013 15:51:52 +0200 Subject: [rust-dev] Automatic Clone Derivation Proposal In-Reply-To: References: Message-ID: Right, we already have opt-out, and having elementary functions like Clone predefined also has precedence in other languages. See java and the overwritable clone() method on Object for example. Am 18.07.2013 15:36 schrieb "Benjamin Striegel" : > I agree that this is a huge headache waiting to happen. It's our own > version of the const-correctness problem. > > We do already have a notion of "opt-out" kinds via #[no_freeze] and > #[no_send], so this isn't entirely unprecedented. > > It would also be good to know how often one needs custom copy behavior. > From just looking at rustc: > > git grep "impl.*Clone for" | wc -l # 62 manual implementations > (though 11 are just from clone.rs) > git grep "#\[deriving.*Clone" | wc -l # 290 derived implementations > > > On Thu, Jul 18, 2013 at 7:24 AM, Corey Richardson wrote: > >> So with decopy landed we now have no way to copy things that does not >> require author intervention. And I am ok with this! Clone is much more >> flexible, less magic, etc. I see one problem with this though: we have >> no way to copy things that does not require author intervention. >> >> For example, I ran into this with rustdoc_ng: there is no Clone >> implementation for syntax::ast::struct_def. There's no reason it >> couldn't have one, it's just that it wasn't needed to be cloned, so an >> implementation wasn't added (via #[deriving(Clone)]). >> >> This is a problem. If a library author overlooks something that >> could/should have Clone, users of that library are now with no way to >> copy. >> >> I propose the following: >> >> If a given struct/enum has no Clone implementation, it fulfills the >> requirements of the now-gone Copy kind, and the #[no_clone] attribute >> is not present, #[deriving(Clone)] is automatically applied to it. >> >> I'm not that fond of this sort of magic but it seems to be necessary: >> library authors aren't perfect, and a simple oversight can harmfully >> limiting what can be done with its types. >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Thu Jul 18 11:12:04 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Thu, 18 Jul 2013 14:12:04 -0400 Subject: [rust-dev] Automatic Clone Derivation Proposal In-Reply-To: References: Message-ID: On Thu, Jul 18, 2013 at 7:24 AM, Corey Richardson wrote: > So with decopy landed we now have no way to copy things that does not > require author intervention. And I am ok with this! Clone is much more > flexible, less magic, etc. I see one problem with this though: we have > no way to copy things that does not require author intervention. > > For example, I ran into this with rustdoc_ng: there is no Clone > implementation for syntax::ast::struct_def. There's no reason it > couldn't have one, it's just that it wasn't needed to be cloned, so an > implementation wasn't added (via #[deriving(Clone)]). > > This is a problem. If a library author overlooks something that > could/should have Clone, users of that library are now with no way to > copy. > > I propose the following: > > If a given struct/enum has no Clone implementation, it fulfills the > requirements of the now-gone Copy kind, and the #[no_clone] attribute > is not present, #[deriving(Clone)] is automatically applied to it. > > I'm not that fond of this sort of magic but it seems to be necessary: > library authors aren't perfect, and a simple oversight can harmfully > limiting what can be done with its types. I find that this applies equally to other traits like `DeepClone` and `Eq` so solving it for one more commonly used trait won't fix the issue. Almost every type should also have a `DeepClone` implementation and most should also have `Eq` *and* `TotalEq`. From danielmicay at gmail.com Thu Jul 18 11:13:44 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Thu, 18 Jul 2013 14:13:44 -0400 Subject: [rust-dev] does not build on build on VectorLinux 7 on ThinkPad T23 In-Reply-To: <51E6EC55.1050801@woh.rr.com> References: <51E6EC55.1050801@woh.rr.com> Message-ID: On Wed, Jul 17, 2013 at 3:11 PM, Steve Adams wrote: > Also, regardless of which system I use to build, it takes many hours to do a > build. Will this be changing in future releases? If it takes many hours to build, you're probably running out of memory. After LLVM is built, it takes me 12-15 minutes to compile the 3 stages of the Rust compiler. From banderson at mozilla.com Thu Jul 18 11:15:36 2013 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 18 Jul 2013 11:15:36 -0700 Subject: [rust-dev] Automatic Clone Derivation Proposal In-Reply-To: References: Message-ID: <51E830C8.5020202@mozilla.com> On 07/18/2013 04:24 AM, Corey Richardson wrote: > So with decopy landed we now have no way to copy things that does not > require author intervention. And I am ok with this! Clone is much more > flexible, less magic, etc. I see one problem with this though: we have > no way to copy things that does not require author intervention. > > For example, I ran into this with rustdoc_ng: there is no Clone > implementation for syntax::ast::struct_def. There's no reason it > couldn't have one, it's just that it wasn't needed to be cloned, so an > implementation wasn't added (via #[deriving(Clone)]). > > This is a problem. If a library author overlooks something that > could/should have Clone, users of that library are now with no way to > copy. > > I propose the following: > > If a given struct/enum has no Clone implementation, it fulfills the > requirements of the now-gone Copy kind, and the #[no_clone] attribute > is not present, #[deriving(Clone)] is automatically applied to it. > > I'm not that fond of this sort of magic but it seems to be necessary: > library authors aren't perfect, and a simple oversight can harmfully > limiting what can be done with its types. I disagree with the premise. There are any number of valid traits that library authors can forget to implement. Clone isn't special here. From sadams58 at woh.rr.com Thu Jul 18 12:05:55 2013 From: sadams58 at woh.rr.com (Steve Adams) Date: Thu, 18 Jul 2013 15:05:55 -0400 Subject: [rust-dev] does not build on build on VectorLinux 7 on ThinkPad T23 In-Reply-To: References: <51E6EC55.1050801@woh.rr.com> Message-ID: <51E83C93.20802@woh.rr.com> Quite possible. The machine in question has just 1Gb. It's booted up to just a text shell to keep as much memory open as possible. Although I built it on a CruchBang system on the same class machine (same memory, disk and CPU) and it works fine -- but it takes hours there as well (could still be a memory issue). On 07/18/2013 02:13 PM, Daniel Micay wrote: > On Wed, Jul 17, 2013 at 3:11 PM, Steve Adams wrote: >> Also, regardless of which system I use to build, it takes many hours to do a >> build. Will this be changing in future releases? > If it takes many hours to build, you're probably running out of > memory. After LLVM is built, it takes me 12-15 minutes to compile the > 3 stages of the Rust compiler. > From corey at octayn.net Thu Jul 18 12:06:25 2013 From: corey at octayn.net (Corey Richardson) Date: Thu, 18 Jul 2013 15:06:25 -0400 Subject: [rust-dev] Automatic Clone Derivation Proposal In-Reply-To: <51E830C8.5020202@mozilla.com> References: <51E830C8.5020202@mozilla.com> Message-ID: On Thu, Jul 18, 2013 at 2:15 PM, Brian Anderson wrote: > > I disagree with the premise. There are any number of valid traits that > library authors can forget to implement. Clone isn't special here. > Thinking about it more over lunch I came to the same conclusion: we need a generic way to automatically derive trait implementations for types which are eligible. #[deriving(Eq, Ord, TotalOrd, TotalEq, IterBytes, Clone)] should be the default. Almost every type wants them, and your type can be crippled without them. Of course, this comes with the peril that someone will not override the derived implementation and their code will be incorrect as a result. From corey at octayn.net Thu Jul 18 12:08:16 2013 From: corey at octayn.net (Corey Richardson) Date: Thu, 18 Jul 2013 15:08:16 -0400 Subject: [rust-dev] does not build on build on VectorLinux 7 on ThinkPad T23 In-Reply-To: <51E83C93.20802@woh.rr.com> References: <51E6EC55.1050801@woh.rr.com> <51E83C93.20802@woh.rr.com> Message-ID: On Thu, Jul 18, 2013 at 3:05 PM, Steve Adams wrote: > Quite possible. The machine in question has just 1Gb. It's booted up to > just a text shell to keep as much memory open as possible. > > Although I built it on a CruchBang system on the same class machine (same > memory, disk and CPU) and it works fine -- but it takes hours there as well > (could still be a memory issue). > The build needs 1.6GiB all to itself. Swapping is going to be reallllly slow (as you've experienced). From pwalton at mozilla.com Thu Jul 18 12:11:50 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Thu, 18 Jul 2013 12:11:50 -0700 Subject: [rust-dev] Automatic Clone Derivation Proposal In-Reply-To: References: <51E830C8.5020202@mozilla.com> Message-ID: <51E83DF6.1030405@mozilla.com> On 7/18/13 12:06 PM, Corey Richardson wrote: > Thinking about it more over lunch I came to the same conclusion: we > need a generic way to automatically derive trait implementations for > types which are eligible. #[deriving(Eq, Ord, TotalOrd, TotalEq, > IterBytes, Clone)] should be the default. Almost every type wants > them, and your type can be crippled without them. Automatically generating, typechecking, code generating, and then probably throwing away 6 implementations for every type has the potential for effects on compile time... Patrick From lindsey at composition.al Thu Jul 18 12:16:45 2013 From: lindsey at composition.al (Lindsey Kuper) Date: Thu, 18 Jul 2013 12:16:45 -0700 Subject: [rust-dev] does not build on build on VectorLinux 7 on ThinkPad T23 In-Reply-To: References: <51E6EC55.1050801@woh.rr.com> <51E83C93.20802@woh.rr.com> Message-ID: On Thu, Jul 18, 2013 at 12:08 PM, Corey Richardson wrote: > On Thu, Jul 18, 2013 at 3:05 PM, Steve Adams wrote: >> Quite possible. The machine in question has just 1Gb. It's booted up to >> just a text shell to keep as much memory open as possible. >> >> Although I built it on a CruchBang system on the same class machine (same >> memory, disk and CPU) and it works fine -- but it takes hours there as well >> (could still be a memory issue). >> > > The build needs 1.6GiB all to itself. Swapping is going to be > reallllly slow (as you've experienced). Yep, that's going to take hours and hours. The recommendation these days is to have 2.5 GiB RAM available for the build process alone. https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust#memory-usage Lindsey From danielmicay at gmail.com Thu Jul 18 12:17:46 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Thu, 18 Jul 2013 15:17:46 -0400 Subject: [rust-dev] Automatic Clone Derivation Proposal In-Reply-To: References: <51E830C8.5020202@mozilla.com> Message-ID: On Thu, Jul 18, 2013 at 3:06 PM, Corey Richardson wrote: > On Thu, Jul 18, 2013 at 2:15 PM, Brian Anderson wrote: >> >> I disagree with the premise. There are any number of valid traits that >> library authors can forget to implement. Clone isn't special here. >> > > Thinking about it more over lunch I came to the same conclusion: we > need a generic way to automatically derive trait implementations for > types which are eligible. #[deriving(Eq, Ord, TotalOrd, TotalEq, > IterBytes, Clone)] should be the default. Almost every type wants > them, and your type can be crippled without them. > > Of course, this comes with the peril that someone will not override > the derived implementation and their code will be incorrect as a > result. You don't want it on every type though. Most types are going to be private to a module, and should only have the minimal implementations required for their usage. As always, a public API takes careful thought and deriving the appropriate traits should be part of that, as it is in Haskell. From graydon at mozilla.com Thu Jul 18 12:26:35 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 18 Jul 2013 12:26:35 -0700 Subject: [rust-dev] does not build on build on VectorLinux 7 on ThinkPad T23 In-Reply-To: References: <51E6EC55.1050801@woh.rr.com> <51E83C93.20802@woh.rr.com> Message-ID: <51E8416B.4090805@mozilla.com> On 13-07-18 12:16 PM, Lindsey Kuper wrote: > On Thu, Jul 18, 2013 at 12:08 PM, Corey Richardson wrote: >> On Thu, Jul 18, 2013 at 3:05 PM, Steve Adams wrote: >>> Quite possible. The machine in question has just 1Gb. It's booted up to >>> just a text shell to keep as much memory open as possible. >>> >>> Although I built it on a CruchBang system on the same class machine (same >>> memory, disk and CPU) and it works fine -- but it takes hours there as well >>> (could still be a memory issue). >>> >> >> The build needs 1.6GiB all to itself. Swapping is going to be >> reallllly slow (as you've experienced). > > Yep, that's going to take hours and hours. The recommendation these > days is to have 2.5 GiB RAM available for the build process alone. > > https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust#memory-usage Yeah. This is not a forever thing, but at this point we tend to use too much memory (and generate too much code). -Graydon From danielmicay at gmail.com Thu Jul 18 12:26:33 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Thu, 18 Jul 2013 15:26:33 -0400 Subject: [rust-dev] does not build on build on VectorLinux 7 on ThinkPad T23 In-Reply-To: References: <51E6EC55.1050801@woh.rr.com> <51E83C93.20802@woh.rr.com> Message-ID: On Thu, Jul 18, 2013 at 3:16 PM, Lindsey Kuper wrote: > On Thu, Jul 18, 2013 at 12:08 PM, Corey Richardson wrote: >> On Thu, Jul 18, 2013 at 3:05 PM, Steve Adams wrote: >>> Quite possible. The machine in question has just 1Gb. It's booted up to >>> just a text shell to keep as much memory open as possible. >>> >>> Although I built it on a CruchBang system on the same class machine (same >>> memory, disk and CPU) and it works fine -- but it takes hours there as well >>> (could still be a memory issue). >>> >> >> The build needs 1.6GiB all to itself. Swapping is going to be >> reallllly slow (as you've experienced). > > Yep, that's going to take hours and hours. The recommendation these > days is to have 2.5 GiB RAM available for the build process alone. > > https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust#memory-usage > > Lindsey It actually got much better since that was written, but there was a recent 300MiB regression. http://huonw.github.io/isrustfastyet/mem/ From ben.striegel at gmail.com Thu Jul 18 12:28:02 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Thu, 18 Jul 2013 15:28:02 -0400 Subject: [rust-dev] Automatic Clone Derivation Proposal In-Reply-To: References: <51E830C8.5020202@mozilla.com> Message-ID: I think at the least we should offer a #[deriving(Basics)] for use on public types so that people aren't forced to memorize "Eq Ord TotalOrd TotalEq IterBytes Clone" (unless we can find a silly SFINAE-esque acronym... http://www.wordsmith.org/anagram/anagram.cgi?anagram=eottic ). On Thu, Jul 18, 2013 at 3:17 PM, Daniel Micay wrote: > On Thu, Jul 18, 2013 at 3:06 PM, Corey Richardson > wrote: > > On Thu, Jul 18, 2013 at 2:15 PM, Brian Anderson > wrote: > >> > >> I disagree with the premise. There are any number of valid traits that > >> library authors can forget to implement. Clone isn't special here. > >> > > > > Thinking about it more over lunch I came to the same conclusion: we > > need a generic way to automatically derive trait implementations for > > types which are eligible. #[deriving(Eq, Ord, TotalOrd, TotalEq, > > IterBytes, Clone)] should be the default. Almost every type wants > > them, and your type can be crippled without them. > > > > Of course, this comes with the peril that someone will not override > > the derived implementation and their code will be incorrect as a > > result. > > You don't want it on every type though. Most types are going to be > private to a module, and should only have the minimal implementations > required for their usage. As always, a public API takes careful > thought and deriving the appropriate traits should be part of that, as > it is in Haskell. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Thu Jul 18 12:33:57 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Thu, 18 Jul 2013 15:33:57 -0400 Subject: [rust-dev] Automatic Clone Derivation Proposal In-Reply-To: References: <51E830C8.5020202@mozilla.com> Message-ID: On Thu, Jul 18, 2013 at 3:28 PM, Benjamin Striegel wrote: > I think at the least we should offer a #[deriving(Basics)] for use on public > types so that people aren't forced to memorize "Eq Ord TotalOrd TotalEq > IterBytes Clone" (unless we can find a silly SFINAE-esque acronym... > http://www.wordsmith.org/anagram/anagram.cgi?anagram=eottic ). Plenty of types can't actually be ordered, and in *many* cases not all fields should be considered for equality/ordering and they may or may not be listed in the order the comparison should try. The only two that rarely require any extra consideration are `Clone`/`DeepClone`, since they should be on almost every type without a destructor. From corey at octayn.net Thu Jul 18 12:39:38 2013 From: corey at octayn.net (Corey Richardson) Date: Thu, 18 Jul 2013 15:39:38 -0400 Subject: [rust-dev] Automatic Clone Derivation Proposal In-Reply-To: References: <51E830C8.5020202@mozilla.com> Message-ID: On Thu, Jul 18, 2013 at 3:33 PM, Daniel Micay wrote: > Plenty of types can't actually be ordered, and in *many* cases not all > fields should be considered for equality/ordering and they may or may > not be listed in the order the comparison should try. > I've wanted like #[deriving(Ord(a, b), Eq(b, c))] which would define not only which fields are used for comparison but also the order of the fields for... ordering. From graydon at mozilla.com Thu Jul 18 12:45:47 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 18 Jul 2013 12:45:47 -0700 Subject: [rust-dev] does not build on build on VectorLinux 7 on ThinkPad T23 In-Reply-To: References: <51E6EC55.1050801@woh.rr.com> <51E83C93.20802@woh.rr.com> Message-ID: <51E845EB.3060600@mozilla.com> On 13-07-18 12:26 PM, Daniel Micay wrote: > It actually got much better since that was written, but there was a > recent 300MiB regression. > > http://huonw.github.io/isrustfastyet/mem/ I believe https://github.com/mozilla/rust/pull/7644 is the fix for that. It has bitrotted recently but only slightly. Anyone with some spare cycles is welcome to try to land it; it should recover that 300mb at least. (There is a lot of shaving to do here) -Graydon From danielmicay at gmail.com Thu Jul 18 12:46:11 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Thu, 18 Jul 2013 15:46:11 -0400 Subject: [rust-dev] Automatic Clone Derivation Proposal In-Reply-To: References: <51E830C8.5020202@mozilla.com> Message-ID: On Thu, Jul 18, 2013 at 3:39 PM, Corey Richardson wrote: > On Thu, Jul 18, 2013 at 3:33 PM, Daniel Micay wrote: >> Plenty of types can't actually be ordered, and in *many* cases not all >> fields should be considered for equality/ordering and they may or may >> not be listed in the order the comparison should try. >> > > I've wanted like #[deriving(Ord(a, b), Eq(b, c))] which would define > not only which fields are used for comparison but also the order of > the fields for... ordering. That can work if it's explicit, but if it's implicitly defined it will often be wrong (in the case of Ord) or slow (for Eq). From corey at octayn.net Thu Jul 18 12:50:06 2013 From: corey at octayn.net (Corey Richardson) Date: Thu, 18 Jul 2013 15:50:06 -0400 Subject: [rust-dev] does not build on build on VectorLinux 7 on ThinkPad T23 In-Reply-To: <51E845EB.3060600@mozilla.com> References: <51E6EC55.1050801@woh.rr.com> <51E83C93.20802@woh.rr.com> <51E845EB.3060600@mozilla.com> Message-ID: On Thu, Jul 18, 2013 at 3:45 PM, Graydon Hoare wrote: > On 13-07-18 12:26 PM, Daniel Micay wrote: > >> It actually got much better since that was written, but there was a >> recent 300MiB regression. >> >> http://huonw.github.io/isrustfastyet/mem/ > > > I believe https://github.com/mozilla/rust/pull/7644 is the fix for that. It > has bitrotted recently but only slightly. Anyone with some spare cycles is > welcome to try to land it; it should recover that 300mb at least. > > (There is a lot of shaving to do here) > aatch said it is broken on Windows with no obvious fix besides de-sharing the rest of the AST From hansjorg at gmail.com Thu Jul 18 13:47:54 2013 From: hansjorg at gmail.com (=?ISO-8859-1?Q?Hans_J=F8rgen_Hoel?=) Date: Thu, 18 Jul 2013 22:47:54 +0200 Subject: [rust-dev] New Ubuntu PPA Message-ID: Hi, I've set up a new PPA with nightly builds: https://launchpad.net/~hansjorg/+archive/rust There's also a 0.7 version (as well as 0.5 and 0.6, but only for quantal). The packages use the alternatives system, so you can have multiple versions installed at once. To switch rustc & co: $ sudo update-alternatives --config rustc Cheers, - Hans J?rgen -------------- next part -------------- An HTML attachment was scrubbed... URL: From jeaye at arrownext.com Thu Jul 18 13:50:48 2013 From: jeaye at arrownext.com (jeaye at arrownext.com) Date: Thu, 18 Jul 2013 14:50:48 -0600 Subject: [rust-dev] New Ubuntu PPA In-Reply-To: References: Message-ID: On 2013-07-18 14:47, Hans J?rgen Hoel wrote: > Hi, > > I've set up a new PPA with nightly builds: > > https://launchpad.net/~hansjorg/+archive/rust [1] > > There's also a 0.7 version (as well as 0.5 and 0.6, but only for > quantal). > > The packages use the alternatives system, so you can have multiple > versions installed at once. To switch rustc & co: > > $ sudo update-alternatives --config rustc > > Cheers, > > - Hans J?rgen > > > Links: > ------ > [1] https://launchpad.net/~hansjorg/+archive/rust > Arch Linux: Check Ubuntu: Check Thanks for the work, Hans; I'm sure this will come in handy for our Ubuntu users! J From banderson at mozilla.com Thu Jul 18 14:53:30 2013 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 18 Jul 2013 14:53:30 -0700 Subject: [rust-dev] New Ubuntu PPA In-Reply-To: References: Message-ID: <51E863DA.1060104@mozilla.com> On 07/18/2013 01:47 PM, Hans J?rgen Hoel wrote: > Hi, > > I've set up a new PPA with nightly builds: > > https://launchpad.net/~hansjorg/+archive/rust > > > There's also a 0.7 version (as well as 0.5 and 0.6, but only for quantal). > > The packages use the alternatives system, so you can have multiple > versions installed at once. To switch rustc & co: > > $ sudo update-alternatives --config rustc Added this to https://github.com/mozilla/rust/wiki/Doc-packages,-editors,-and-other-tools From dbau.pp at gmail.com Thu Jul 18 17:26:44 2013 From: dbau.pp at gmail.com (Huon Wilson) Date: Fri, 19 Jul 2013 10:26:44 +1000 Subject: [rust-dev] Automatic Clone Derivation Proposal In-Reply-To: References: <51E830C8.5020202@mozilla.com> Message-ID: <51E887C4.8060606@gmail.com> On 19/07/13 05:39, Corey Richardson wrote: > On Thu, Jul 18, 2013 at 3:33 PM, Daniel Micay wrote: >> Plenty of types can't actually be ordered, and in *many* cases not all >> fields should be considered for equality/ordering and they may or may >> not be listed in the order the comparison should try. >> > I've wanted like #[deriving(Ord(a, b), Eq(b, c))] which would define > not only which fields are used for comparison but also the order of > the fields for... ordering. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev I'm working on this; at the moment the plan is to look something like: #[deriving(Ord(test_order(z,y), reverse(y), ignore(w)))] struct A { x: int, y: int, z: int, w: int, t: int } // is the same as impl Ord for A { fn lt(&self, other: &A) -> bool { self.z < other.z && other.y < self.y && self.x < other.x && self.t < other.t } // etc. } The reason `test_order` and `ignore` are separated is because I imagine the most common cases are ignoring one field, and moving one field to be tested first, and so these would be #[deriving(Ord(ignore(field)))] and #[deriving(Ord(test_order(field)))] respectively, rather than having to list all the fields explicitly. (I'm willing to be convinced otherwise.) It will work with `Eq`, `TotalEq` and `TotalOrd` too; and for each trait the appropriate options (i.e. `ignore` for the Total traits, and `reverse` for the Eq ones) will be disabled with an error. Huon From qwertie256 at gmail.com Thu Jul 18 18:06:31 2013 From: qwertie256 at gmail.com (David Piepgrass) Date: Thu, 18 Jul 2013 19:06:31 -0600 Subject: [rust-dev] Can Rust allow a bitwise equality test? Message-ID: > > I think at the least we should offer a #[deriving(Basics)] for use on > public > > types so that people aren't forced to memorize "Eq Ord TotalOrd TotalEq > > IterBytes Clone" (unless we can find a silly SFINAE-esque acronym... > > http://www.wordsmith.org/anagram/anagram.cgi?anagram=eottic ). > > Plenty of types can't actually be ordered, and in *many* cases not all > fields should be considered for equality/ordering and they may or may > not be listed in the order the comparison should try. > > The only two that rarely require any extra consideration are > `Clone`/`DeepClone`, since they should be on almost every type without > a destructor. > > I just had a random thought. I once implemented a data structure for .NET called a VList ( http://www.codeproject.com/Articles/26171/VList-data-structures-in-C) which provided a "SmartSelect" pseudo-LINQ method. If you had a list of numbers, you could ensure they are all positive like this: list.SmartSelect(x => Math.Max(x, 1)) The reason it's called SmartSelect is that it returns a changed list only if the select operation *changes* any of the values (and even then it may still be able to re-use the tail of the list). The tricky part is detecting when there has been any changes. Ideally I would have liked to simply do a bitwise equality test because it would be very fast and requires no special support from the data type, but .NET doesn't have a bitwise equality test. So I ended up having to use a test that always requires dynamic method invocation, which I have heard is fantastically slow in the general case of structs that don't implement IEquatable. I wonder if Rust could, in the general case, allow my bitwise equality test. I realize that bitwise equality isn't "real" equality, but in this case it's good enough. For instance if the selector changes -0.0 to +0.0, which is value-equal but bitwise-different, the effect is fairly harmless--a partially new list is allocated instead of re-using the old list. Of course, if the list contains references (~T, @T), the bitwise test should compare the references themselves, without dereferencing. -------------- next part -------------- An HTML attachment was scrubbed... URL: From thiezz at gmail.com Fri Jul 19 02:17:52 2013 From: thiezz at gmail.com (Thiez) Date: Fri, 19 Jul 2013 11:17:52 +0200 Subject: [rust-dev] Can Rust allow a bitwise equality test? In-Reply-To: References: Message-ID: I think something along these lines should do: fn bitwise_compare(a: &T, b: &T) -> bool { use std::{ptr,sys,cast,uint}; let size = sys::size_of::(); unsafe { let a: &u8 = cast::transmute(a); let b: &u8 = cast::transmute(b); for uint::range(0,size) |n| { if *ptr::offset(a,n) != *ptr::offset(b,n){ return false } } } true } Note that it won't work for strings and vectors. It could be slightly more efficient by comparing in larger chunks than u8, but LLVM will probably figure that out. On Fri, Jul 19, 2013 at 3:06 AM, David Piepgrass wrote: > > > I think at the least we should offer a #[deriving(Basics)] for use on >> public >> > types so that people aren't forced to memorize "Eq Ord TotalOrd TotalEq >> > IterBytes Clone" (unless we can find a silly SFINAE-esque acronym... >> > http://www.wordsmith.org/anagram/anagram.cgi?anagram=eottic ). >> >> Plenty of types can't actually be ordered, and in *many* cases not all >> fields should be considered for equality/ordering and they may or may >> not be listed in the order the comparison should try. >> >> The only two that rarely require any extra consideration are >> `Clone`/`DeepClone`, since they should be on almost every type without >> a destructor. >> >> > I just had a random thought. > > I once implemented a data structure for .NET called a VList ( > http://www.codeproject.com/Articles/26171/VList-data-structures-in-C) > which provided a "SmartSelect" pseudo-LINQ method. If you had a list of > numbers, you could ensure they are all positive like this: > > list.SmartSelect(x => Math.Max(x, 1)) > > The reason it's called SmartSelect is that it returns a changed list only > if the select operation *changes* any of the values (and even then it may > still be able to re-use the tail of the list). The tricky part is detecting > when there has been any changes. Ideally I would have liked to simply do a > bitwise equality test because it would be very fast and requires no special > support from the data type, but .NET doesn't have a bitwise equality test. > So I ended up having to use a test that always requires dynamic method > invocation, which I have heard is fantastically slow in the general case of > structs that don't implement IEquatable. > > I wonder if Rust could, in the general case, allow my bitwise equality > test. I realize that bitwise equality isn't "real" equality, but in this > case it's good enough. For instance if the selector changes -0.0 to +0.0, > which is value-equal but bitwise-different, the effect is fairly > harmless--a partially new list is allocated instead of re-using the old > list. > > Of course, if the list contains references (~T, @T), the bitwise test > should compare the references themselves, without dereferencing. > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From simon.sapin at exyr.org Fri Jul 19 03:24:18 2013 From: simon.sapin at exyr.org (Simon Sapin) Date: Fri, 19 Jul 2013 11:24:18 +0100 Subject: [rust-dev] Can Rust allow a bitwise equality test? In-Reply-To: References: Message-ID: <51E913D2.8010403@exyr.org> Le 19/07/2013 10:17, Thiez a ?crit : > I think something along these lines should do: > > fn bitwise_compare(a: &T, b: &T) -> bool { > use std::{ptr,sys,cast,uint}; > let size = sys::size_of::(); > unsafe { > let a: &u8 = cast::transmute(a); > let b: &u8 = cast::transmute(b); > for uint::range(0,size) |n| { > if *ptr::offset(a,n) != *ptr::offset(b,n){ > return false > } > } > } > true > } > > Note that it won't work for strings and vectors. It could be slightly > more efficient by comparing in larger chunks than u8, but LLVM will > probably figure that out. There?s code in libstd that uses libc::memcpm instead of an explicit loop: https://github.com/mozilla/rust/blob/06fec5243b/src/libstd/vec.rs#L2091 Cheers, -- Simon Sapin From niko at alum.mit.edu Fri Jul 19 13:28:23 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Fri, 19 Jul 2013 16:28:23 -0400 Subject: [rust-dev] Automatic Clone Derivation Proposal In-Reply-To: References: <51E830C8.5020202@mozilla.com> Message-ID: <20130719202823.GF11294@Mr-Bennet> On Thu, Jul 18, 2013 at 03:28:02PM -0400, Benjamin Striegel wrote: > I think at the least we should offer a #[deriving(Basics)] for use on > public types so that people aren't forced to memorize "Eq Ord TotalOrd > TotalEq IterBytes Clone" (unless we can find a silly SFINAE-esque > acronym... http://www.wordsmith.org/anagram/anagram.cgi?anagram=eottic ). +1 This is more-or-less what I was going to propose. Don't care too much what we call it. Niko From corey at octayn.net Sat Jul 20 19:57:10 2013 From: corey at octayn.net (Corey Richardson) Date: Sat, 20 Jul 2013 22:57:10 -0400 Subject: [rust-dev] Automatic Clone Derivation Proposal In-Reply-To: <20130719202823.GF11294@Mr-Bennet> References: <51E830C8.5020202@mozilla.com> <20130719202823.GF11294@Mr-Bennet> Message-ID: I agree, this is the best solution to the problem I think. On Fri, Jul 19, 2013 at 4:28 PM, Niko Matsakis wrote: > On Thu, Jul 18, 2013 at 03:28:02PM -0400, Benjamin Striegel wrote: >> I think at the least we should offer a #[deriving(Basics)] for use on >> public types so that people aren't forced to memorize "Eq Ord TotalOrd >> TotalEq IterBytes Clone" (unless we can find a silly SFINAE-esque >> acronym... http://www.wordsmith.org/anagram/anagram.cgi?anagram=eottic ). > > +1 This is more-or-less what I was going to propose. Don't care too > much what we call it. > > > Niko > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From dbau.pp at gmail.com Sun Jul 21 03:44:22 2013 From: dbau.pp at gmail.com (Huon Wilson) Date: Sun, 21 Jul 2013 20:44:22 +1000 Subject: [rust-dev] Recent batch of spurious test failures. Message-ID: <51EBBB86.5010409@gmail.com> Hi all, The buildbot seems to have corrupted a few of its build directories, and this has lead to every single r+'d pull request failing, completely unrelated to their actual content. There is little point in r+/retrying until [7939] gets resolved. Huon Wilson [7939]: https://github.com/mozilla/rust/issues/7939 From dwrenshaw at gmail.com Sun Jul 21 09:44:24 2013 From: dwrenshaw at gmail.com (David Renshaw) Date: Sun, 21 Jul 2013 12:44:24 -0400 Subject: [rust-dev] Cap'n Proto and region variables Message-ID: Hello everyone, I'm playing around with a Rust implementation for Cap'n Proto. Check it out: http://github.com/dwrensha/capnproto-rust . I welcome any comments or contributions. The reason I'm sharing this project with you now is I'd like to ask about a language feature missing from Rust that I feel may be hindering my progress. To the point, I want to be able define a trait like this: trait Constructable<'self> { fn construct<'a>(StructReader<'a>) -> Self<'a>; } The important detail here is that the lifetime 'a of the constructed object is the same as the lifetime of the constructor's input. Why do I want this? When we are reading a Cap'n Proto message, the message's data is just an immutable byte vector owned by some enclosing scope. To traverse the message, we use auxiliary data structures such as `StructReader<'a>` and `ListReader<'a>` that hold slices of the message and various indices into them. These auxiliary structures are internal to the library and should not be exposed to the user. They are in turn wrapped by specialized user-facing structs. For example, if AddressBook is a user-defined message, then capnproto-rust generates an `AddressBook::Reader<'a>` struct, with message-specific accessor methods, which can be constructed from a generic `StructReader<'a>`. Here we hit a problem. We want the user to be able to do something like this: let addressBookReader = message.readRoot::(); If we had the `Constructable` trait above, we could achieve that like this: impl <'self> MessageReader <'self> { // ... fn readRoot (&self) -> T<'a> { Constructable::construct(self.readRootStructReader()) } } but otherwise the user is forced to do something like: let addressBookReader = AddressBook::Reader::new(message.readRootStructReader()); or maybe, if we want to hide the `StructReader` as much a possible: let addressBookReader = AddressBook::Reader::constructFromMessageRoot(message); Note that the latter workaround requires that capnproto-rust generate a `constructFromMessageRoot` method for each type of message. We run into more problems when we start considering lists. Cap'n Proto messages may contain arbitrarily nested lists. So, for example, we may encounter a list of lists of AddressBooks. Under the hood, these will be generic ListReaders, but we would like to provide users an appropriate specialized interface to them. For instance, if a user gets an element from a list of structs, it should not be a generic StructReader---it should be a reader of the appropriate specialized type. As a simple example, we want allow uses like this: let people = addressBookReader.getPeople(); for std::uint::range(0, people.size()) |i| { let person = people.get(i); printfln!("person: %s, email: %s", person.getName(), person.getEmail()); } Generalizing such usage to the general case of arbitrarily nested lists seems to require a trait like `Constructable`. Otherwise I can't see a way around writing a tangled mess of `constructFrom...` methods. Just ask yourself: what type does `people` need to be so that it can implement the `get` method? It seems to me that the natural answer is something like "the instantiation of some struct with a type parameter ". I'll note that my implementation strategy has been to follow the C++ Cap'n Proto implementation, which uses templates to solve all of these problems. My big questions are: Is there a way to do what I want in Rust? If not, why not?---and will there be in the future? Thanks, David From graydon at mozilla.com Sun Jul 21 10:54:14 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Sun, 21 Jul 2013 10:54:14 -0700 Subject: [rust-dev] Recent batch of spurious test failures. In-Reply-To: <51EBBB86.5010409@gmail.com> References: <51EBBB86.5010409@gmail.com> Message-ID: <51EC2046.1030302@mozilla.com> On 13-07-21 03:44 AM, Huon Wilson wrote: > Hi all, > > The buildbot seems to have corrupted a few of its build directories, and > this has lead to every single r+'d pull request failing, completely > unrelated to their actual content. There is little point in r+/retrying > until [7939] gets resolved. Fixing presently. Sorry, not sure what happened. Maybe a git failure? -Graydon From bsteinbr at gmail.com Sun Jul 21 10:58:40 2013 From: bsteinbr at gmail.com (=?iso-8859-1?Q?Bj=F6rn?= Steinbrink) Date: Sun, 21 Jul 2013 19:58:40 +0200 Subject: [rust-dev] Recent batch of spurious test failures. In-Reply-To: <51EC2046.1030302@mozilla.com> References: <51EBBB86.5010409@gmail.com> <51EC2046.1030302@mozilla.com> Message-ID: <20130721175840.GA22972@atjola.homenet> Hi, On 2013.07.21 10:54:14 -0700, Graydon Hoare wrote: > On 13-07-21 03:44 AM, Huon Wilson wrote: > >The buildbot seems to have corrupted a few of its build directories, and > >this has lead to every single r+'d pull request failing, completely > >unrelated to their actual content. There is little point in r+/retrying > >until [7939] gets resolved. > > Fixing presently. Sorry, not sure what happened. Maybe a git failure? Bad timing with the interruption. That seems to use SIGKILL and killed a git process that still had the lockfile in place. Bj?rn From corey at octayn.net Sun Jul 21 14:25:01 2013 From: corey at octayn.net (Corey Richardson) Date: Sun, 21 Jul 2013 17:25:01 -0400 Subject: [rust-dev] This Week in Rust Message-ID: Content copied from http://cmr.github.io/blog/2013/07/21/this-week-in-rust/ -- Hello and welcome to the seventh issue of *This Week in Rust*, a weekly overview of Rust and its community. Things are calming down quite a bit, in that nothing extraordinarily exciting is happening. Lots of great work is being done everywhere, and good progress is being made in both bugfixes and cleanup. It has been a good week! # What's cooking on master? Issue churn this week was -15. A total of 59 PRs were merged. ## Breaking changes - **[The semantics of `range_rev` have changed](https://github.com/mozilla/rust/pull/7684). This will break your code without warning.** It is now, to use [interval notation](https://en.wikipedia.org/wiki/Interval_%28mathematics%29#Notations_for_intervals), `(hi, lo]` rather than `[hi, lo)`. - `pub extern` and `priv extern` [have been removed](https://github.com/mozilla/rust/pull/7896) from the language. This matches the previous similar change to `impl`. Place the visibility qualifier (`pub`/`priv`) on each item in the `extern` block instead. - `&T` (besides `&'static T`) is [no longer allowed in `@T`](https://github.com/mozilla/rust/pull/7894). - The `ThreadPerCore` spawn mode [has been removed](https://github.com/mozilla/rust/pull/7856), as it doesn't make sense with the new scheduler. - The `consume` methods of the hash containers [has been replaced with an external iterator](https://github.com/mozilla/rust/pull/7833). The method name is the same, though. - Moved values can [no longer be captured twice](https://github.com/mozilla/rust/pull/7849). This was a blatant soundness issue. - The `swap_unwrap` method of Option has been [renamed to `take_unwrap`](https://github.com/mozilla/rust/pull/7831). - `debug!` statements [generate no code](https://github.com/mozilla/rust/pull/7822) unless you pass `--cfg debug` to `rustc`. This should help keep code size down and make your programs a (tiny bit) faster. Now you don't have to feel bad about having `debug!` in hot code. - The `mutate_values` method of HashMap [has been removed](https://github.com/mozilla/rust/pull/7815). ## Notable library additions, bugfixes, and cleanup - An iterator adaptor was added that [endlessly repeats the iterator it is called on](https://github.com/mozilla/rust/pull/7882). - Generated test runners [now have a `-h`/`--help`](https://github.com/mozilla/rust/pull/7840) option. - Metric capturing + racheting [has been added](https://github.com/mozilla/rust/pull/7829) for benchmarks. - `local_data` [now has a `get_mut`](https://github.com/mozilla/rust/pull/7841) function. - `extra::semver` [has been updated to SemVer 2.0.0](https://github.com/mozilla/rust/pull/7726). - Consuming iterators [have been added](https://github.com/mozilla/rust/pull/7806) for the hash structures. - `extra::ringbuf` [now implements DoubleEndedIterator](https://github.com/mozilla/rust/pull/7808). - `Eq` [now has a default implementation of `ne`](https://github.com/mozilla/rust/pull/7799). - `extra::term` [now knows how to handle more attributes](https://github.com/mozilla/rust/pull/7716). - More containers [implement FromIter](https://github.com/mozilla/rust/pull/7788). This means you can use `.collect()` to gather the elements from an iterator into those containers. - [Task killing, failure, and exit code propagation](https://github.com/mozilla/rust/pull/7858) in the new runtime has been implemented. ## Notable compiler additions, bugfixes, and cleanup - `syntax::attr` [has been modernized](https://github.com/mozilla/rust/pull/7902). - [Tons of debuginfo work](https://github.com/mozilla/rust/pull/7710) from mw this week! - Trait data structures [have been cleaned up](https://github.com/mozilla/rust/pull/7886), as well as a default method fix. - Intrinsics [now have much better codegen](https://github.com/mozilla/rust/pull/7851). - A `no_implicit_prelude` attribute [has been added](https://github.com/mozilla/rust/pull/7844), which prevents prelude injection in the module heirarchy starting at the item which that attribute is added to. - C-style enum variants are [now allowed](https://github.com/mozilla/rust/pull/7827) in `[T, ..n]` expressions. - All language items are [now optional](https://github.com/mozilla/rust/pull/7828). The compiler emits an error if a language item is used but not provided. - The removal of `spanned` [has begun](https://github.com/mozilla/rust/pull/7826). - Headers [have been removed](https://github.com/mozilla/rust/pull/7816) for `~str` and `~[T]` where `T` is unmanaged. ## Documentation, tools, and other stuff - rustpkg [now works when you don't give it a package ID](https://github.com/mozilla/rust/pull/7419). It builds/installs/cleans the package in the current directory, *iff* the current directory is in a rustpkg workspace. - `--quiet` is [no longer passed](https://github.com/mozilla/rust/pull/7847) to git during submodule operations, so you can see the progress of the huge LLVM download. - Documentation of the [lint-controlling attributes](https://github.com/mozilla/rust/pull/7823) was added. - rustpkg [now handles cloning from local git repos](https://github.com/mozilla/rust/pull/7681). - The GtkSourceView highlighting file [was improved](https://github.com/mozilla/rust/pull/7795). # Meetings The [Tuesday meeting](https://github.com/mozilla/rust/wiki/Meeting-weekly-2013-07-16) discussed nothing at all of importance. # Discussion + Blog posts - [Discussion and slides from Niko's presentation at the Northeastern University Programming Language Seminar](http://www.reddit.com/r/rust/comments/1imeac/guaranteeing_memory_safety_in_rust_niko_matsakis/) - [A nightly Ubuntu PPA](http://thread.gmane.org/gmane.comp.lang.rust.devel/4829) - [SIMD discussion](http://www.reddit.com/r/rust/comments/1igvye/vision_for_rust_simd/) - [Rust on bare metal ARM](https://mail.mozilla.org/pipermail/rust-dev/2013-July/004841.html) - [dherman's OSCON presentation](http://www.oscon.com/oscon2013/public/schedule/detail/28741) From niko at alum.mit.edu Wed Jul 24 06:09:33 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 24 Jul 2013 09:09:33 -0400 Subject: [rust-dev] Cap'n Proto and region variables In-Reply-To: References: Message-ID: <20130724130933.GF2179@Mr-Bennet> On Sun, Jul 21, 2013 at 12:44:24PM -0400, David Renshaw wrote: > Hello everyone, > > I'm playing around with a Rust implementation for Cap'n Proto. Check > it out: http://github.com/dwrensha/capnproto-rust . I welcome any > comments or contributions. > > The reason I'm sharing this project with you now is I'd like to ask > about a language feature missing from Rust that I feel may be > hindering my progress. > > To the point, I want to be able define a trait like this: > > trait Constructable<'self> { > fn construct<'a>(StructReader<'a>) -> Self<'a>; > } I believe it would it be possible to define the trait like so: trait Constructable<'self> { fn construct(StructReader<'self>) -> Self; } regards, Niko From martine at danga.com Wed Jul 24 09:15:17 2013 From: martine at danga.com (Evan Martin) Date: Wed, 24 Jul 2013 09:15:17 -0700 Subject: [rust-dev] read_byte and sentinel values Message-ID: Hello, Sorry for the bikesheddy question, but coming from a Haskell perspective it's strange that io::Reader::read_byte returns (1) an int, when the value you're reading is a byte, and (2) "a negative value" on error/EOF. The unspecified sentinel value means the pattern match needs to look like: match r.read_byte() { i if i < 0 => ... i => { let b = i as u8; ... } It would seem more natural to me for it to return an Option, but that leads to two questions: 1) Is it more Rusty to use types like this instead of sentinels? My aesthetics aren't adapted to Rust yet. 2) Is an Option implemented as a pair of (type, value) or is it packed into a single word? (In the former case, maybe efficiency is the reason for the original "int" return value.) And is this sort of thing even specified by Rust or is it up to the compiler to optimize or not? Looking at the tracker I found https://github.com/mozilla/rust/issues/5977 , which seems like basically the same thing. -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Wed Jul 24 09:19:51 2013 From: corey at octayn.net (Corey Richardson) Date: Wed, 24 Jul 2013 12:19:51 -0400 Subject: [rust-dev] read_byte and sentinel values In-Reply-To: References: Message-ID: On Wed, Jul 24, 2013 at 12:15 PM, Evan Martin wrote: > It would seem more natural to me for it to return an Option, but that > leads to two questions: > > 1) Is it more Rusty to use types like this instead of sentinels? My > aesthetics aren't adapted to Rust yet. > Yes. Option is the correct choice here. The old IO code (all of the stuff in std::io) is crufty and needing to be replaced (work on the new rt is progressing quite well). From bjzaba at yahoo.com.au Wed Jul 24 09:33:47 2013 From: bjzaba at yahoo.com.au (Brendan Zabarauskas) Date: Thu, 25 Jul 2013 02:33:47 +1000 Subject: [rust-dev] read_byte and sentinel values In-Reply-To: References: Message-ID: <62838D38-4371-4C73-A314-C56E4E3FC778@yahoo.com.au> On 25/07/2013, at 2:15 AM, Evan Martin wrote: > Is an Option implemented as a pair of (type, value) or is it packed into a single word? A quick test shows: rusti> std::sys::size_of::>() 16 ~Brendan -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthieu.monrocq at gmail.com Wed Jul 24 09:42:36 2013 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Wed, 24 Jul 2013 18:42:36 +0200 Subject: [rust-dev] read_byte and sentinel values In-Reply-To: <62838D38-4371-4C73-A314-C56E4E3FC778@yahoo.com.au> References: <62838D38-4371-4C73-A314-C56E4E3FC778@yahoo.com.au> Message-ID: Given that all values of u8 are meanginful, there is no space for an extra bit, so it is no surprise that it cannot be packed. For pointers, for example, it is typical to exploit the fact that the null pointer is a meaningless value and thus rely on this sentinel value to encode the absence of value, but in general this is only possible if such a sentinel value is possible to begin with. -- Matthieu On Wed, Jul 24, 2013 at 6:33 PM, Brendan Zabarauskas wrote: > On 25/07/2013, at 2:15 AM, Evan Martin wrote: > > Is an Option implemented as a pair of (type, value) or is it packed > into a single word? > > > A quick test shows: > > rusti> std::sys::size_of::>() > 16 > > ~Brendan > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Wed Jul 24 09:46:20 2013 From: corey at octayn.net (Corey Richardson) Date: Wed, 24 Jul 2013 12:46:20 -0400 Subject: [rust-dev] read_byte and sentinel values In-Reply-To: References: <62838D38-4371-4C73-A314-C56E4E3FC778@yahoo.com.au> Message-ID: On Wed, Jul 24, 2013 at 12:42 PM, Matthieu Monrocq wrote: > Given that all values of u8 are meanginful, there is no space for an extra > bit, so it is no surprise that it cannot be packed. > > For pointers, for example, it is typical to exploit the fact that the null > pointer is a meaningless value and thus rely on this sentinel value to > encode the absence of value, but in general this is only possible if such a > sentinel value is possible to begin with. > I would expect it to be backed into a u16. From matthieu.monrocq at gmail.com Wed Jul 24 09:51:03 2013 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Wed, 24 Jul 2013 18:51:03 +0200 Subject: [rust-dev] read_byte and sentinel values In-Reply-To: References: <62838D38-4371-4C73-A314-C56E4E3FC778@yahoo.com.au> Message-ID: It could be. If it is not, it may be that Option needs some love at the CodeGen level to make it so :) -- Matthieu. On Wed, Jul 24, 2013 at 6:46 PM, Corey Richardson wrote: > On Wed, Jul 24, 2013 at 12:42 PM, Matthieu Monrocq > wrote: > > Given that all values of u8 are meanginful, there is no space for an > extra > > bit, so it is no surprise that it cannot be packed. > > > > For pointers, for example, it is typical to exploit the fact that the > null > > pointer is a meaningless value and thus rely on this sentinel value to > > encode the absence of value, but in general this is only possible if > such a > > sentinel value is possible to begin with. > > > > I would expect it to be backed into a u16. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Wed Jul 24 09:50:36 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Wed, 24 Jul 2013 12:50:36 -0400 Subject: [rust-dev] read_byte and sentinel values In-Reply-To: <62838D38-4371-4C73-A314-C56E4E3FC778@yahoo.com.au> References: <62838D38-4371-4C73-A314-C56E4E3FC778@yahoo.com.au> Message-ID: On Wed, Jul 24, 2013 at 12:33 PM, Brendan Zabarauskas wrote: > On 25/07/2013, at 2:15 AM, Evan Martin wrote: > > Is an Option implemented as a pair of (type, value) or is it packed into > a single word? > > > A quick test shows: > > rusti> std::sys::size_of::>() > 16 > > ~Brendan It will be 2 bytes, it's just that enum discriminants aren't made as small as possible yet. From danielmicay at gmail.com Wed Jul 24 10:05:07 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Wed, 24 Jul 2013 13:05:07 -0400 Subject: [rust-dev] read_byte and sentinel values In-Reply-To: References: <62838D38-4371-4C73-A314-C56E4E3FC778@yahoo.com.au> Message-ID: On Wed, Jul 24, 2013 at 12:51 PM, Matthieu Monrocq wrote: > It could be. > > If it is not, it may be that Option needs some love at the CodeGen level to > make it so :) > > -- Matthieu. It's a known issue for enums in general. The `Option` type is entirely a library feature, and isn't special-cased by the compiler. https://github.com/mozilla/rust/issues/1647 From graydon at mozilla.com Wed Jul 24 10:08:27 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 24 Jul 2013 10:08:27 -0700 Subject: [rust-dev] read_byte and sentinel values In-Reply-To: <62838D38-4371-4C73-A314-C56E4E3FC778@yahoo.com.au> References: <62838D38-4371-4C73-A314-C56E4E3FC778@yahoo.com.au> Message-ID: <51F00A0B.7080508@mozilla.com> On 13-07-24 09:33 AM, Brendan Zabarauskas wrote: > On 25/07/2013, at 2:15 AM, Evan Martin > wrote: > >> Is an Option implemented as a pair of (type, value) or is it >> packed into a single word? > > A quick test shows: > > rusti> std::sys::size_of::>() > 16 We represent enums as (tag-word, union-of-data-fields) pairs, except in the optimized representation case of option<~T> where we use compress the nullary None tag into a sentinel pointer (null) and drop to 1 word. I expect we'll eventually do one other obvious optimization here, to define tags as the smallest datum width that can accommodate all the tag values and maintan the alignment "requirement" (or absence of speed penalty) of the data fields, not just "1 word". That sort of definition would mean option drops to 2 bytes (not 16) and on targets with cheap unaligned access (ivy bridge etc) most tags (with <256 variants) drop from 8 bytes to 1 (if you pass the appropriate --target-feature flag). To get much more clever than that involves hunting in the union-of-data-fields for overlapping fields into which you can either scrounge bits or use sentinel values. This is not totally implausible: the low 3 bits are available in most pointers from a malloc, and the entire zero page on almost all platforms is unmapped for picking sentinels. On x64 there are tons of spare bits in every pointer, and virtually unlimited sentinel values due to the noncanonical address range. Plus there are NaN bits and the unused >21st bits in char and whatnot. But ... I think it'll be a while before we bother with that sort of thing, if ever. -Graydon From niko at alum.mit.edu Wed Jul 24 12:12:00 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 24 Jul 2013 15:12:00 -0400 Subject: [rust-dev] read_byte and sentinel values In-Reply-To: <51F00A0B.7080508@mozilla.com> References: <62838D38-4371-4C73-A314-C56E4E3FC778@yahoo.com.au> <51F00A0B.7080508@mozilla.com> Message-ID: <20130724191200.GL2179@Mr-Bennet> The existence of ref patterns somewhat limits what one can do here as well, since you must be able to create a pointer to the value being matched, which implies that it can't be too "disguised". For example, this prevents us from optimizing something like `Either<~A,~B>` to use a 0 or 1 in the low bit. One thought that was recently mentioned to me is that it would be useful to define a few types like u31/u63 or u28/u60, which would allow us to siphon off the high bits for sentinel values. Niko On Wed, Jul 24, 2013 at 10:08:27AM -0700, Graydon Hoare wrote: > On 13-07-24 09:33 AM, Brendan Zabarauskas wrote: > >On 25/07/2013, at 2:15 AM, Evan Martin >> wrote: > > > >>Is an Option implemented as a pair of (type, value) or is it > >>packed into a single word? > > > >A quick test shows: > > > > rusti> std::sys::size_of::>() > > 16 > > We represent enums as (tag-word, union-of-data-fields) pairs, except > in the optimized representation case of option<~T> where we use > compress the nullary None tag into a sentinel pointer (null) and drop > to 1 word. > > I expect we'll eventually do one other obvious optimization here, to > define tags as the smallest datum width that can accommodate all the > tag values and maintan the alignment "requirement" (or absence of > speed penalty) of the data fields, not just "1 word". That sort of > definition would mean option drops to 2 bytes (not 16) and on > targets with cheap unaligned access (ivy bridge etc) most tags (with > <256 variants) drop from 8 bytes to 1 (if you pass the appropriate > --target-feature flag). > > To get much more clever than that involves hunting in the > union-of-data-fields for overlapping fields into which you can either > scrounge bits or use sentinel values. This is not totally > implausible: the low 3 bits are available in most pointers from a > malloc, and the entire zero page on almost all platforms is unmapped > for picking sentinels. On x64 there are tons of spare bits in every > pointer, and virtually unlimited sentinel values due to the > noncanonical address range. Plus there are NaN bits and the unused > >21st bits in char and whatnot. But ... I think it'll be a while > before we bother with that sort of thing, if ever. > > -Graydon > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From jld at panix.com Wed Jul 24 12:18:37 2013 From: jld at panix.com (Jed Davis) Date: Wed, 24 Jul 2013 12:18:37 -0700 Subject: [rust-dev] read_byte and sentinel values In-Reply-To: <51F00A0B.7080508@mozilla.com> References: <62838D38-4371-4C73-A314-C56E4E3FC778@yahoo.com.au> <51F00A0B.7080508@mozilla.com> Message-ID: <20130724191837.GA8512@panix.com> On Wed, Jul 24, 2013 at 10:08:27AM -0700, Graydon Hoare wrote: > I expect we'll eventually do one other obvious optimization here, to > define tags as the smallest datum width that can accommodate all the > tag values and maintan the alignment "requirement" (or absence of > speed penalty) of the data fields, not just "1 word". I had this working at one point, but it wasn't completely finished, and then the type_ and external interator changes conflicted with it, and I haven't had time recently to fix it. It's not quite as simple as it sounds, because there's unsafe code that's transmuting ints to C-like enums, and passing C-like enums to C functions that expect an actual C enum (or some other integral type). So this more or less forces part of the problem of specifying a representation. The work in progress, unmergeable in its current form (and in need of some squashing): https://github.com/jld/rust/compare/enum-discrim-size > That sort of definition would mean option drops to 2 bytes (not > 16) and on targets with cheap unaligned access (ivy bridge etc) most > tags (with <256 variants) drop from 8 bytes to 1 (if you pass the > appropriate --target-feature flag). Is that safe? I know at least some architectures don't like atomic operations that can cross cache lines. The other thing that sort of goes here is that, if the struct-of-fields needs alignment padding anyway, the discriminant can go there. This is essentially a special case of reordering fields to reduce padding. (But if this makes the offset to the discriminant unrepresentable in (for example) an ARM load/store instruction, so that it has to be synthesized, then that's less good.) > To get much more clever than that involves hunting in the > union-of-data-fields for overlapping fields into which you can > either scrounge bits or use sentinel values. Or creating useful overlapping fields by choosing appropriate offsets. > This is not totally implausible: the low 3 bits are available in > most pointers from a malloc, and the entire zero page on almost all > platforms is unmapped for picking sentinels. The value might also have unused bits due to alignment padding, although I'm wary of what happens to them (either intentionally in rustc or due to LLVM's assumptions) when the value containing them is copied/moved. But also, an enum that doesn't use the entire range of its discriminant has sentinel values that another enum containing it can use. And then there's the possibility of handling nested enums like this: enum E { A, B } enum F { C, D } enum G { X(E), Y(F) } by assigning A=0, B=1, C=2, D=3. Which may or may not be helpful enough for any real use cases (e.g., ast) to be worth thinking about. --Jed From corey at octayn.net Wed Jul 24 12:31:53 2013 From: corey at octayn.net (Corey Richardson) Date: Wed, 24 Jul 2013 15:31:53 -0400 Subject: [rust-dev] read_byte and sentinel values In-Reply-To: <20130724191837.GA8512@panix.com> References: <62838D38-4371-4C73-A314-C56E4E3FC778@yahoo.com.au> <51F00A0B.7080508@mozilla.com> <20130724191837.GA8512@panix.com> Message-ID: On Wed, Jul 24, 2013 at 3:18 PM, Jed Davis wrote: > It's not quite as simple as it sounds, because there's unsafe code > that's transmuting ints to C-like enums, and passing C-like enums to C > functions that expect an actual C enum (or some other integral type). > So this more or less forces part of the problem of specifying a > representation. > Something that came up in IRC when discussing why 'struct' exists as a special case of 1-ary sums is the idea of a #[layout="C"] attribute. Perhaps something similar could be adapted here; if you don't have a specific layout specified, it's undefined. This seems like a very hard problem overall, though. From dwrenshaw at gmail.com Wed Jul 24 16:26:21 2013 From: dwrenshaw at gmail.com (David Renshaw) Date: Wed, 24 Jul 2013 19:26:21 -0400 Subject: [rust-dev] Cap'n Proto and region variables In-Reply-To: <20130724130933.GF2179@Mr-Bennet> References: <20130724130933.GF2179@Mr-Bennet> Message-ID: Looks like it's broken at the moment. If I try to compile this program: trait Constructable<'self> { fn construct(v : &'self[u8]) -> Self; } fn main() { } I get this error: error: internal compiler error: ty::Region#subst(): Reference to self region when given substs with no self region: substs(self_r=None, self_ty=Some(BUG[0]), tps=[]) On Wed, Jul 24, 2013 at 9:09 AM, Niko Matsakis wrote: > On Sun, Jul 21, 2013 at 12:44:24PM -0400, David Renshaw wrote: >> Hello everyone, >> >> I'm playing around with a Rust implementation for Cap'n Proto. Check >> it out: http://github.com/dwrensha/capnproto-rust . I welcome any >> comments or contributions. >> >> The reason I'm sharing this project with you now is I'd like to ask >> about a language feature missing from Rust that I feel may be >> hindering my progress. >> >> To the point, I want to be able define a trait like this: >> >> trait Constructable<'self> { >> fn construct<'a>(StructReader<'a>) -> Self<'a>; >> } > > I believe it would it be possible to define the trait like so: > > trait Constructable<'self> { > fn construct(StructReader<'self>) -> Self; > } > > > > regards, > > Niko From graydon at mozilla.com Wed Jul 24 17:56:30 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 24 Jul 2013 17:56:30 -0700 Subject: [rust-dev] 'in' for for loops and alloc exprs Message-ID: <51F077BE.9090601@mozilla.com> Hi, We had some discussion recently about reforming the for-loop syntax since we'll be switching it to external iterators and it's a bit deceptive to the user to be writing a lambda-pattern there. Many people have suggested we use a simple and familiar: for in { ... } form. I am inclined to agree with this though I should point out a few minor concerns: - It's a new keyword. We've been really, really trying not to do that. - No-pattern form now requires a dummy pattern. That is, we can't do: for 10.times { ... } anymore, rather we have to write: for _ in 10.times() { ... } which is possibly unsightly. We can't disambiguate patterns from exprs just by peeking at them. I don't know. The 10.times thing always seemed a little clever to me anyways. - The 'do' form starts to look a little lonely / incongruous. We use it presently for passing-in-a-closure when a function takes an optional value, such as: do hashmap.find_or_insert_with(k) { def() } Given we're discussing macro-izing the other main use of 'do' to generate an owning thunk Trait object, It's not entirely clear to me that this pattern alone warrants keeping 'do'. Anyway, neither of these seem like showstoppers to me, I just thought I'd mention them in passing in case anyone wanted to chew on possible solutions (or point out other issues with for .. in that I didn't picture yet). I found it more interesting to note that, should we take 'in' as a new keyword, it's a perfectly reasonable keyword to reuse for the putative "allocation expressions" we've been talking about needing for supporting C++-like placement-new. That is, evaluating an expression "into" a bit of memory provided by one of the operands. This is useful for arenas, GCs, custom smart pointers and memory pools, etc. We've been somewhat concerned that we're sealing up the language without the ability to implement evaluate-into-place forms; evaluating into a local and then moving into a place doesn't actually work either, due to unknown-sized types (vectors and such). I think it kinda has to be a built-in expression. So I'm wondering how this looks for people: in as a new bottom-precedence binop. The RHS is evaluated first, to a *mut u8 or perhaps some lang-item trait we define for "the interface to a memory allocator", then the LHS is "evaluated into it". I do not _think_ it would collide with "for in ", unless my eyes confuse me. It might need to be an unsafe expr; not clear. Any thoughts? Ghastly? Convenient? I don't much like evaluating RHS before LHS but in this case it seems like it'd be necessary. And lest you complain that reusing 'in' this way is a comprehension menace, I'd point out that we reuse several other keywords in differing contexts ('for', 'mod', 'self', 'super') without too much confusion. -Graydon From jeaye at arrownext.com Wed Jul 24 19:59:13 2013 From: jeaye at arrownext.com (Jeaye) Date: Wed, 24 Jul 2013 19:59:13 -0700 Subject: [rust-dev] 'in' for for loops and alloc exprs In-Reply-To: <51F077BE.9090601@mozilla.com> References: <51F077BE.9090601@mozilla.com> Message-ID: <51F09481.20006@arrownext.com> > We had some discussion recently about reforming the for-loop syntax > since we'll be switching it to external iterators and it's a bit > deceptive to the user to be writing a lambda-pattern there. Have we yet considered C++11's approach to this? for : { ... } This seems pretty consistent to me at first glance, considering how we use a similar syntax to declare and initialize fields. Consider being initialized by for each value in . > - No-pattern form now requires a dummy pattern. That is, we can't do: > > for 10.times { ... } > > anymore, rather we have to write: > > for _ in 10.times() { ... } If we do go this route, I think this new idiom is actually a good thing. `for 10.times { }` seems a bit too clever, whereas the latter is entirely predictable, albeit slightly more verbose.; it's also entirely consistent with our usage of _ elsewhere. What would be the trait tied to 'in' that allowed any user-created container to be iterated in this manner? > I found it more interesting to note that, should we take 'in' as a new > keyword, it's a perfectly reasonable keyword to reuse for the putative > "allocation expressions" we've been talking about needing for > supporting C++-like placement-new. That's a really good idea and seems entirely logical, coming from C++. J From corey at octayn.net Wed Jul 24 20:05:56 2013 From: corey at octayn.net (Corey Richardson) Date: Wed, 24 Jul 2013 23:05:56 -0400 Subject: [rust-dev] 'in' for for loops and alloc exprs In-Reply-To: <51F09481.20006@arrownext.com> References: <51F077BE.9090601@mozilla.com> <51F09481.20006@arrownext.com> Message-ID: On Wed, Jul 24, 2013 at 10:59 PM, Jeaye wrote: >> We had some discussion recently about reforming the for-loop syntax since >> we'll be switching it to external iterators and it's a bit deceptive to the >> user to be writing a lambda-pattern there. > > Have we yet considered C++11's approach to this? > > for : { ... } > I personally dislike this syntax for iteration, but it would be consistent with current Rust (just change to ). >> - No-pattern form now requires a dummy pattern. That is, we can't do: >> >> for 10.times { ... } >> >> anymore, rather we have to write: >> >> for _ in 10.times() { ... } > > If we do go this route, I think this new idiom is actually a good thing. > `for 10.times { }` seems a bit too clever, whereas the latter is entirely > predictable, albeit slightly more verbose.; it's also entirely consistent > with our usage of _ elsewhere. Do any other languages with similar syntax let you omit the "x in" part of the "for x in y" when there is no x? Also, of course it's consistent, it's just a pattern :) > What would be the trait tied to 'in' that > allowed any user-created container to be iterated in this manner? > `std::iterator::Iterator`. Probably needs to be a lang item with this change. From jack at metajack.im Wed Jul 24 22:54:10 2013 From: jack at metajack.im (Jack Moffitt) Date: Wed, 24 Jul 2013 23:54:10 -0600 Subject: [rust-dev] 'in' for for loops and alloc exprs In-Reply-To: <51F077BE.9090601@mozilla.com> References: <51F077BE.9090601@mozilla.com> Message-ID: > - No-pattern form now requires a dummy pattern. That is, we can't do: > > for 10.times { ... } > > anymore, rather we have to write: > > for _ in 10.times() { ... } I will not cry much if this happens; it is a bit clever, but maybe we could save it by using loop: loop 10.times { ... } and loop { ... } could coexist perhaps? > Given we're discussing macro-izing the other main use of 'do' to > generate an owning thunk Trait object, It's not entirely clear to > me that this pattern alone warrants keeping 'do'. I'm not sure what you mean here. Can you provide an example? > I found it more interesting to note that, should we take 'in' as a new > keyword, it's a perfectly reasonable keyword to reuse for the putative > "allocation expressions" we've been talking about needing for supporting > C++-like placement-new. It seems reasonable to use for the partial binding in patterns as well, although that might not work with for: Instead of `foo @ Something(bar)` you'd write `Something(bar) in foo`. Seems pretty nice. jack. From rust-dev at tomlee.co Wed Jul 24 23:05:59 2013 From: rust-dev at tomlee.co (Tom Lee) Date: Wed, 24 Jul 2013 23:05:59 -0700 Subject: [rust-dev] Portland, OR Friday 6:30pm: Patrick Walton & Jack Moffitt talk sprocketnes & Servo Message-ID: Hey all, If you're in Portland, OR this week -- as many are for OSCON -- Patrick Walton & Jack Moffitt are taking some time out of their schedules to talk Rust this Friday evening, 26th of July @ 6:30pm: http://calagator.org/events/1250464569 All welcome, feel free to pop in & say hi -- elevators should be open from around 6:15pm. We'll be supplying beer & pizza. There's also plenty of soda if you're not alcohol-ly inclined. Any other questions, feel free to ping me at this address. Otherwise, see you there! Cheers, Tom -- Tom Lee / http://tomlee.co / @tglee From info at bnoordhuis.nl Thu Jul 25 03:02:03 2013 From: info at bnoordhuis.nl (Ben Noordhuis) Date: Thu, 25 Jul 2013 12:02:03 +0200 Subject: [rust-dev] Incremental and generational GC In-Reply-To: <51DDA8A8.9060707@mozilla.com> References: <51DDA8A8.9060707@mozilla.com> Message-ID: Sorry about reviving an oldish thread, I hadn't seen it before. On Wed, Jul 10, 2013 at 8:32 PM, Patrick Walton wrote: > For generational GC, we must ensure that objects in the nursery pointed to > by the tenured generation are either added to a remembered set or tenured. > This is harder in Rust because we have to know both the generation of the > referrer and the referent simultaneously. I believe that conservatively > tenuring all objects that are mutated would be overconservative and defeat > much of the purpose of GGC. > > The only thing that I can think of that would work is to use the MMU and do > the generational GC barriers on a per-page basis. I believe that this is > what Boehm does in its GGC mode. This to me seems the most risky part of > this; I'm not sure what the performance implications of this are. One issue I see with relying on memory protection to fix up write barriers is that you are effectively tying yourself to 4 kB pages. You won't be able to use huge pages (2 or 4 MB) because those are simply too large to scan in a reasonable amount of time. From ben.striegel at gmail.com Thu Jul 25 05:42:57 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Thu, 25 Jul 2013 08:42:57 -0400 Subject: [rust-dev] 'in' for for loops and alloc exprs In-Reply-To: References: <51F077BE.9090601@mozilla.com> Message-ID: > for in { ... } I really like this notation. And there's actually a better reason for switching to a new syntax other than "it's a bit deceptive to the user to be writing a lambda-pattern there". Namely, given strcat's plan to allow iteration automatically on anything that implements Iterator or Iterable, the following is actually ambiguous: for foo.bar |i| { ... } In our current `for` notation, we allow one to omit parentheses for empty argument lists. Thus, in the above loop, we have no idea if `bar` is a member of `foo` that implements Iterable or if `bar` is a method that evaluates to an Iterable! To disambiguate we would have to require parentheses, and this would create an inconsistency with `do` notation. > it's a perfectly reasonable keyword to reuse for the putative "allocation expressions" I'm all for reusing `in` in other contexts. Placement new is one that I hadn't thought of. I was actually thinking of something along the lines of overriding shadowing in match statements: let x = 2; let y = match (4, 3) { (x, 3) => x, _ = 0 }; The above code will assign 4 to y, because the pattern `(x, 3)` shadows the outer declaration of `x`. Now imagine we had something like the following: let x = 2; let y = match x in (4, 3) { (x, 3) => x, _ = 0 }; Rather than shadowing `x`, the above could allow us to use the existing definition in the pattern.I don't know if anyone else thinks this would be useful, I'm just pointing out possibilities. > It's not entirely clear to me that this pattern alone warrants keeping 'do'. As a professional Javascripter, I implore you keep `do` as it is. It really and truly is a world of difference between: do foo { ... } and: foo(|| { ... }); It's one of my favorite features of Rust, and it makes higher-order functions feel like first-class citizens. > for _ in 10.times() { ... } As the original creator of `10.times`, I was under the impression that we'd be moving from `for` to `do` once this change is complete. As in: do 10.times { ... } I'm baffled as to why people think something so simple and intuitive is "clever". :P > for : { ... } -1. The `:` symbol is already hugely overloaded, and it's less readable to boot. -------------- next part -------------- An HTML attachment was scrubbed... URL: From michaelwoerister at gmail.com Thu Jul 25 06:26:07 2013 From: michaelwoerister at gmail.com (Michael Woerister) Date: Thu, 25 Jul 2013 15:26:07 +0200 Subject: [rust-dev] 'in' for for loops and alloc exprs In-Reply-To: References: <51F077BE.9090601@mozilla.com> Message-ID: <51F1276F.2000204@gmail.com> > > for : { ... } > > -1. The `:` symbol is already hugely overloaded, and it's less > readable to boot. > I think `for : { ... }` reads a lot like `for *of type* { ... }`, which doesn't make much sense. `for in { ... }`, on the other hand, looks very nice. From bklooste at gmail.com Thu Jul 25 07:30:39 2013 From: bklooste at gmail.com (Bennie Kloosteman) Date: Thu, 25 Jul 2013 22:30:39 +0800 Subject: [rust-dev] Incremental and generational GC In-Reply-To: References: <51DDA8A8.9060707@mozilla.com> Message-ID: Even 4K is probably too large most card tables are 128 or 256 bytes . Im pretty sure memory protection has been tried but i cant recall the paper. I do know Azul pauseless/concurrent collector uses the MMU but this is more for cocurrent mark/sweep reasons. They had an issue because which pages to be protected change and the kernel could not handle all the system calls so they have a long running request ( so far denied) to change the syscall ( or add one) to specify a collection of pages. Ben >One issue I see with relying on memory protection to fix up write >barriers is that you are effectively tying yourself to 4 kB pages. >You won't be able to use huge pages (2 or 4 MB) because those are >simply too large to scan in a reasonable amount of time. On Thu, Jul 25, 2013 at 6:02 PM, Ben Noordhuis wrote: > Sorry about reviving an oldish thread, I hadn't seen it before. > > On Wed, Jul 10, 2013 at 8:32 PM, Patrick Walton > wrote: > > For generational GC, we must ensure that objects in the nursery pointed > to > > by the tenured generation are either added to a remembered set or > tenured. > > This is harder in Rust because we have to know both the generation of the > > referrer and the referent simultaneously. I believe that conservatively > > tenuring all objects that are mutated would be overconservative and > defeat > > much of the purpose of GGC. > > > > The only thing that I can think of that would work is to use the MMU and > do > > the generational GC barriers on a per-page basis. I believe that this is > > what Boehm does in its GGC mode. This to me seems the most risky part of > > this; I'm not sure what the performance implications of this are. > > One issue I see with relying on memory protection to fix up write > barriers is that you are effectively tying yourself to 4 kB pages. > You won't be able to use huge pages (2 or 4 MB) because those are > simply too large to scan in a reasonable amount of time. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jaoke.chinlee at 10gen.com Thu Jul 25 07:44:39 2013 From: jaoke.chinlee at 10gen.com (Jao-ke Chin-Lee) Date: Thu, 25 Jul 2013 10:44:39 -0400 Subject: [rust-dev] Rust driver for mongoDB In-Reply-To: References: Message-ID: * Jed and I are excited to announce the alpha versionof the Rust driver for mongoDB! Thank you all for your help on the #rust IRC channel towards this project. We?ve published a postabout the driver, and the source and documentation are available. Feel free to send along any questions, comments, bug reports, and pull requests! Thanks again,* * * *~~Jao-ke* On Fri, Jun 7, 2013 at 1:56 PM, Jao-ke Chin-Le wrote: > * > > Greetings all, > > Jed Estep and I are interns at 10gen (the mongoDB company), and we?re > excited to announce that we?ll be working on the Rust driver for mongo! > Please feel free to contact us with any questions/comments; likewise, we?ll > be in your care for Rust questions. > > Thank you! > > Jao-ke Chin-Lee* > -------------- next part -------------- An HTML attachment was scrubbed... URL: From simon.sapin at exyr.org Thu Jul 25 08:34:13 2013 From: simon.sapin at exyr.org (Simon Sapin) Date: Thu, 25 Jul 2013 16:34:13 +0100 Subject: [rust-dev] 'in' for for loops and alloc exprs In-Reply-To: <51F077BE.9090601@mozilla.com> References: <51F077BE.9090601@mozilla.com> Message-ID: <51F14575.6050509@exyr.org> Le 25/07/2013 01:56, Graydon Hoare a ?crit : > for in { ... } Yes please. > - The 'do' form starts to look a little lonely / incongruous. We use > it presently for passing-in-a-closure when a function takes an > optional value, such as: > > do hashmap.find_or_insert_with(k) { > def() > } > > Given we're discussing macro-izing the other main use of 'do' to > generate an owning thunk Trait object, It's not entirely clear to > me that this pattern alone warrants keeping 'do'. Aren?t there other uses of 'do'? do std::task::spawn { // ... } -- Simon Sapin From pwalton at mozilla.com Thu Jul 25 08:41:49 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Thu, 25 Jul 2013 08:41:49 -0700 Subject: [rust-dev] 'in' for for loops and alloc exprs In-Reply-To: <51F09481.20006@arrownext.com> References: <51F077BE.9090601@mozilla.com> <51F09481.20006@arrownext.com> Message-ID: <51F1473D.3000204@mozilla.com> On 7/24/13 7:59 PM, Jeaye wrote: >> We had some discussion recently about reforming the for-loop syntax >> since we'll be switching it to external iterators and it's a bit >> deceptive to the user to be writing a lambda-pattern there. > Have we yet considered C++11's approach to this? > > for : { ... } > > This seems pretty consistent to me at first glance, considering how we > use a similar syntax to declare and initialize fields. Consider > being initialized by for each value in . I'd like to reserve `:` as the type ascription operator (thanks to Michael Artzenius for the name): i.e. assertion that some pattern or expression has a given type. This would eliminate a bunch of `let` bindings that are currently sometimes used when the type inference fails. For example, you could write: debug!("%?", from_json("{ \"foobie\": \"bletch\" }") : MyObject) Instead of: let my_object: MyObject = from_json("{ \"foobie\": \"bletch\" }"); debug!("%?", my_object); Anyway, that would conflict with this. Patrick From pwalton at mozilla.com Thu Jul 25 08:46:27 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Thu, 25 Jul 2013 08:46:27 -0700 Subject: [rust-dev] 'in' for for loops and alloc exprs In-Reply-To: <51F077BE.9090601@mozilla.com> References: <51F077BE.9090601@mozilla.com> Message-ID: <51F14853.60100@mozilla.com> On 7/24/13 5:56 PM, Graydon Hoare wrote: > Hi, > > We had some discussion recently about reforming the for-loop syntax > since we'll be switching it to external iterators and it's a bit > deceptive to the user to be writing a lambda-pattern there. Many people > have suggested we use a simple and familiar: > > for in { ... } +1 > So I'm wondering how this looks for people: > > in The more I think about this, the more I like it. "new" is not great as we're already using it everywhere for constructors. And it's all about *placement*, as you said: you're placing the value *in* another location. let expr = Expr::new(foo, bar, baz) in Gc; let my_dom_node = Element::new() in JsHeap; let my_flow_node = BlockFlow::new() in FlowArena; The only thing I might worry about is that it conflicts with Python's and JS's use of "in", but that isn't a showstopper to me. Patrick From banderson at mozilla.com Thu Jul 25 09:52:13 2013 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 25 Jul 2013 09:52:13 -0700 Subject: [rust-dev] Rust driver for mongoDB In-Reply-To: References: Message-ID: <51F157BD.20209@mozilla.com> On 07/25/2013 07:44 AM, Jao-ke Chin-Lee wrote: > * > > *Jed and I are excited to announce the alpha version > of > the Rust driver for mongoDB! Thank you all for your help on the #rust > IRC channel towards this project.* > > > > We've published a post > about > the driver, and the source > and > documentation > are > available. Feel free to send along any questions, comments, bug > reports, and pull requests! > > > * This looks really amazing! I love that you've included a comprehensive readme file. Having a high-quality database driver is going to enable some interesting Rust projects. Thanks, and nice work. -Brian -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Thu Jul 25 10:32:17 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 25 Jul 2013 10:32:17 -0700 Subject: [rust-dev] 'in' for for loops and alloc exprs In-Reply-To: References: <51F077BE.9090601@mozilla.com> Message-ID: <51F16121.7050807@mozilla.com> On 13-07-25 05:42 AM, Benjamin Striegel wrote: > As a professional Javascripter, I implore you keep `do` as it is. It > really and truly is a world of difference between: > > do foo { > ... > } > > and: > > foo(|| { > ... > }); > > It's one of my favorite features of Rust, and it makes higher-order > functions feel like first-class citizens. Ok. Nice feedback :) >> for _ in 10.times() { ... } > > As the original creator of `10.times`, I was under the impression that > we'd be moving from `for` to `do` once this change is complete. As in: > > do 10.times { ... } > > I'm baffled as to why people think something so simple and intuitive is > "clever". :P If we did that, we'd lose the ability to break or return, since 'do' doesn't follow the for-style loop protocol. Maybe not that important. -Graydon From graydon at mozilla.com Thu Jul 25 11:31:18 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 25 Jul 2013 11:31:18 -0700 Subject: [rust-dev] 'in' for for loops and alloc exprs In-Reply-To: <51F14575.6050509@exyr.org> References: <51F077BE.9090601@mozilla.com> <51F14575.6050509@exyr.org> Message-ID: <51F16EF6.2080603@mozilla.com> On 13-07-25 08:34 AM, Simon Sapin wrote: > Le 25/07/2013 01:56, Graydon Hoare a ?crit : >> for in { ... } > > Yes please. > > >> - The 'do' form starts to look a little lonely / incongruous. We use >> it presently for passing-in-a-closure when a function takes an >> optional value, such as: >> >> do hashmap.find_or_insert_with(k) { >> def() >> } >> >> Given we're discussing macro-izing the other main use of 'do' to >> generate an owning thunk Trait object, It's not entirely clear to >> me that this pattern alone warrants keeping 'do'. > > Aren?t there other uses of 'do'? > > do std::task::spawn { > // ... > } That's what I alluded to above, where we're likely to switch that to a macro call that passes explicitly-captured arguments into a thunk struct that owns the explicit captures. This has been in meeting minutes for a while but I guess it wasn't clear. Lambdas that capture-by-copy (=move) are slated for removal. Or at least ... we've agreed to _experiment_ with replacing them with thunk-generating macros. There are a few reasons for this: - Capture-by-copy-or-move is ... counterintuitive for at least several users. It's especially counterintuitive given that it's _inferred_ presently. But even without, users seem to have magical beliefs about closures that seldom agree from user to user. We've got a lot of "that didn't do what I expected" feedback about any closure form other than simple by-ref, can-mutate-the-environment &fns. - Structs already own their fields and have an extremely rich language for describing the relationship between self and fields. Notably: - Trait bounds for things like Freeze, Clone, Send - Region parameters on captured pointers - Once-ness (by-val self) - Freezing and thawing the owner We've attempted to add all these things on to function types in the past and wound up with function types like once ~fn:Clone+'static<'a,T,U>(&'a T) -> U which, while plausibly readable to someone very familiar with rust code, feels to me a bit like "past the reasonable cognitive budget". The syntax(es) for declaring these things on structs and traits is similar, but a little more spacious, a little easier to digest: the onceness, arg and return parts are moved to a method, making it a bit easier to read uses of the thunk-type itself. - Spawned tasks should get names and source coordinates for the sake of backtraces and error reporting, so we want to macro-ize spawning anyways. - Spawned tasks may wind up needing dtors anyways, in which case they would need to be named types, not an anonymous fn type. So I think we'll try it, anyways. It naturally makes the delightful looking 'do spawn { ... }' expression a little grottier, but that might be the price we pay for eliminating confusion elsewhere. -Graydon From ben.striegel at gmail.com Thu Jul 25 13:46:31 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Thu, 25 Jul 2013 16:46:31 -0400 Subject: [rust-dev] 'in' for for loops and alloc exprs In-Reply-To: <51F16EF6.2080603@mozilla.com> References: <51F077BE.9090601@mozilla.com> <51F14575.6050509@exyr.org> <51F16EF6.2080603@mozilla.com> Message-ID: > If we did that, we'd lose the ability to break or return, since 'do' doesn't follow the for-style loop protocol. I'm perfectly happy with that; the `times` method was never about complex control flow, just simple repetition. `do 10.times {` is a delightfully self-explanatory contract. And just as evidence that `do` notation is useful beyond `spawn`: $ git grep "do .*{" -- "*.rs" | wc -l 2019 $ git grep "do .*spawn" -- "*.rs" | wc -l 274 > we're likely to switch that to a macro call that passes explicitly-captured arguments into a thunk struct that owns the explicit captures I don't remember seeing much of this idea in the meeting notes, but I do remember seeing it mentioned in these blog posts (for those who want more context): http://smallcultfollowing.com/babysteps/blog/2013/05/30/removing-procs/ http://smallcultfollowing.com/babysteps/blog/2013/06/03/more-on-fns/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Thu Jul 25 14:01:10 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 25 Jul 2013 14:01:10 -0700 Subject: [rust-dev] buildbot upgrade Message-ID: <51F19216.1020002@mozilla.com> As it's a little quiet this week (many people away at OSCON) I'm going to take the opportunity to upgrade buildbot (we're running a version from 2010). Hopefully it shouldn't be offline for long, assuming I get a new instance running reasonably well; but there might be some disruption to landings while I debug any incompatibilities between the versions. -Graydon From thadguidry at gmail.com Thu Jul 25 14:28:22 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Thu, 25 Jul 2013 16:28:22 -0500 Subject: [rust-dev] 'in' for for loops and alloc exprs In-Reply-To: References: <51F077BE.9090601@mozilla.com> <51F14575.6050509@exyr.org> <51F16EF6.2080603@mozilla.com> Message-ID: I also like 'do 10,times {' , since I likely would also use it to create multiple copies (one after the other). A lazy sequence for my purposes dealing with data generation. Just to clarify, 'do 10.times {' would NOT allow launching multiple copies in parallel, correct ? (that's reserved for Actor styles, etc, etc.) Just simple repetition, as you say ? On Thu, Jul 25, 2013 at 3:46 PM, Benjamin Striegel wrote: > > If we did that, we'd lose the ability to break or return, since 'do' > doesn't follow the for-style loop protocol. > > I'm perfectly happy with that; the `times` method was never about complex > control flow, just simple repetition. `do 10.times {` is a delightfully > self-explanatory contract. > > And just as evidence that `do` notation is useful beyond `spawn`: > > $ git grep "do .*{" -- "*.rs" | wc -l > 2019 > $ git grep "do .*spawn" -- "*.rs" | wc -l > 274 > > > we're likely to switch that to a macro call that passes > explicitly-captured arguments into a thunk struct that owns the explicit > captures > > I don't remember seeing much of this idea in the meeting notes, but I do > remember seeing it mentioned in these blog posts (for those who want more > context): > > http://smallcultfollowing.com/babysteps/blog/2013/05/30/removing-procs/ > http://smallcultfollowing.com/babysteps/blog/2013/06/03/more-on-fns/ > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -- -Thad Thad on Freebase.com Thad on LinkedIn -------------- next part -------------- An HTML attachment was scrubbed... URL: From ben.striegel at gmail.com Thu Jul 25 15:31:44 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Thu, 25 Jul 2013 18:31:44 -0400 Subject: [rust-dev] 'in' for for loops and alloc exprs In-Reply-To: References: <51F077BE.9090601@mozilla.com> <51F14575.6050509@exyr.org> <51F16EF6.2080603@mozilla.com> Message-ID: Nowadays you can do: for 10.times { do spawn { ... } } to launch 10 asynchronous things. In the future there might be a `par` library to make doing things in parallel more uniform. -------------- next part -------------- An HTML attachment was scrubbed... URL: From loebel.marvin at gmail.com Thu Jul 25 06:45:32 2013 From: loebel.marvin at gmail.com (=?ISO-8859-1?Q?Marvin_L=F6bel?=) Date: Thu, 25 Jul 2013 15:45:32 +0200 Subject: [rust-dev] 'in' for for loops and alloc exprs In-Reply-To: <51F077BE.9090601@mozilla.com> References: <51F077BE.9090601@mozilla.com> Message-ID: <51F12BFC.7080806@googlemail.com> I'm all for using `in` in the `for` syntax, and then using the `in` keyword as part of the allocation interface sounds like a good idea. But isn't that interface as presentatd a bit limited? At least, if it uses *mut u8 and is unsafe then `foo() in bar()` would be the same as `*bar() = foo()`, right? Don't we need something like `alloc ` for evaluating an expression into a new allocation, and `alloc in ` for evaluating an expression into an new allocation inside of ``? > [...] > So I'm wondering how this looks for people: > > in > > as a new bottom-precedence binop. The RHS is evaluated first, to a > *mut u8 or perhaps some lang-item trait we define for "the interface > to a memory allocator", then the LHS is "evaluated into it". I do not > _think_ it would collide with "for in ", unless my eyes > confuse me. It might need to be an unsafe expr; not clear. > > Any thoughts? Ghastly? Convenient? I don't much like evaluating RHS > before LHS but in this case it seems like it'd be necessary. And lest > you complain that reusing 'in' this way is a comprehension menace, I'd > point out that we reuse several other keywords in differing contexts > ('for', 'mod', 'self', 'super') without too much confusion. > > -Graydon > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From danielmicay at gmail.com Fri Jul 26 07:31:41 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Fri, 26 Jul 2013 10:31:41 -0400 Subject: [rust-dev] 'in' for for loops and alloc exprs In-Reply-To: <51F12BFC.7080806@googlemail.com> References: <51F077BE.9090601@mozilla.com> <51F12BFC.7080806@googlemail.com> Message-ID: On Thu, Jul 25, 2013 at 9:45 AM, Marvin L?bel wrote: > I'm all for using `in` in the `for` syntax, and then using the `in` keyword > as part of the allocation interface sounds like a good idea. > But isn't that interface as presentatd a bit limited? At least, if it uses > *mut u8 and is unsafe then `foo() in bar()` would be the same as `*bar() = > foo()`, right? > > Don't we need something like `alloc ` for evaluating an expression > into a new allocation, > and `alloc in ` for evaluating an expression into an new > allocation inside of ``? `*bar = foo` with `*mut u8` will actually still run the destructor on `*bar` before moving `foo` into it From michaelwoerister at gmail.com Fri Jul 26 08:54:41 2013 From: michaelwoerister at gmail.com (Michael Woerister) Date: Fri, 26 Jul 2013 17:54:41 +0200 Subject: [rust-dev] Removing codemap::spanned In-Reply-To: <51E45A6D.5030407@mozilla.com> References: <51E163E2.70507@gmail.com> <51E17F81.1040502@mozilla.com> <51E3A746.9050608@gmail.com> <51E432A8.7010204@mozilla.com> <51E434DB.2070005@gmail.com> <51E45A6D.5030407@mozilla.com> Message-ID: <51F29BC1.8010508@gmail.com> Reviving an old thread here because I'm still working on this. > I suspect you'll want to make a trait `Spanned` that the various > spanned-types implement, such that code that generically acts on "Some > spanned thing" can continue to work. Not sure, just a hunch. I thought so too, but after removing spanned from a few types I have not encountered the need to do so so far. The reason is probably that without traits a common abstraction over 'everthing having a span' couldn't be expressed, so no code was written that would rely upon such an abstraction. > (spanned predates having traits at all, so if there's a better way to > approach this in current idioms, go right ahead) It turns out that my initial reasoning for getting rid of spanned didn't take enums properly into account. For these, having a wrapper containing data common to all variants makes more sense than for structs. Because otherwise the common fields have to be put in every variants: struct spanned { span: span, node: T } // This might be more convenient to use... pub type decl = spanned; pub enum decl_ { decl_local(@Local), decl_item(@item), } // .. than this: pub enum decl { decl_local(@Local, span), decl_item(@item, span), } Especially when the enum an has many variants (such as `ast::expr_` with 33 variants) adding a `span` field to all of them is kind of annoying. Apart from spanned there are quite a few such wrapper structs containing common fields: ast::expr, ast::pat, ast::foreign_item, ast::item, ast::view_item, and ast::Ty to name only those in libsyntax/ast.rs To me this seems very much like a slightly clunky way of emulating inheritance (with a lot more typing involved at definition and usage sites). Field accessor functions or traits can alleviate some of this clunkyness at the usage site; however, at the cost of even more boilerplate needed at the definition site: pub enum decl { decl_local(@Local, span), decl_item(@item, span), } impl decl { fn get_span(&self) { // this match statement also introduces some unnecessary runtime overhead... match *self { decl_local(_, span) => span, decl_item(_, span) => span } } } This situation is not very satisfactory but I don't know an easy solution to the problem. I certainly don't suggest adding such a heavy tool as inheritance to Rust just for this use case. So for now I'll keep adapting things to the new naming convention but I'll leave wrapped enums as they are. I'm very much interested in any comments regarding this problem of types with some common fields and some specialized fields. Type specialization is something popping up all the time and Rust seems to have some weak spots there. Some concrete style questions: - Do enum variants follow the guideline for variable_naming or TypeNaming. (Although, imo enum variants should be *subtypes* of their defining enum anyway ;) - What is the preferred naming convention for getter functions such as `get_span()` above? get_span()? just span()? something else? Thanks for reading! From pwalton at mozilla.com Fri Jul 26 09:18:24 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Fri, 26 Jul 2013 09:18:24 -0700 Subject: [rust-dev] Removing codemap::spanned In-Reply-To: <51F29BC1.8010508@gmail.com> References: <51E163E2.70507@gmail.com> <51E17F81.1040502@mozilla.com> <51E3A746.9050608@gmail.com> <51E432A8.7010204@mozilla.com> <51E434DB.2070005@gmail.com> <51E45A6D.5030407@mozilla.com> <51F29BC1.8010508@gmail.com> Message-ID: <51F2A150.4040305@mozilla.com> On 7/26/13 8:54 AM, Michael Woerister wrote: > To me this seems very much like a slightly clunky way of emulating > inheritance (with a lot more typing involved at definition and usage > sites). Field accessor functions or traits can alleviate some of this > clunkyness at the usage site; however, at the cost of even more > boilerplate needed at the definition site: > > pub enum decl { > decl_local(@Local, span), > decl_item(@item, span), > } > > impl decl { > fn get_span(&self) { > // this match statement also introduces some unnecessary > runtime overhead... > match *self { > decl_local(_, span) => span, > decl_item(_, span) => span > } > } > } > > This situation is not very satisfactory but I don't know an easy > solution to the problem. I certainly don't suggest adding such a heavy > tool as inheritance to Rust just for this use case. This is the preferred method of emulating common fields. We use this in Servo. I would like to add an optimization to remove the unnecessary runtime overhead in this case. In theory this should be amenable to compiler optimizations. > So for now I'll keep adapting things to the new naming convention but > I'll leave wrapped enums as they are. I'm very much interested in any > comments regarding this problem of types with some common fields and > some specialized fields. Type specialization is something popping up all > the time and Rust seems to have some weak spots there. > > Some concrete style questions: > - Do enum variants follow the guideline for variable_naming or > TypeNaming. (Although, imo enum variants should be *subtypes* of their > defining enum anyway ;) TypeNaming, i.e. CamelCase. > - What is the preferred naming convention for getter functions such as > `get_span()` above? get_span()? just span()? something else? Just `span()`. There's no need to use a `get` prefix in Rust because method calls and field projections are syntactically distinguished. Patrick From erick.tryzelaar at gmail.com Fri Jul 26 09:30:38 2013 From: erick.tryzelaar at gmail.com (Erick Tryzelaar) Date: Fri, 26 Jul 2013 09:30:38 -0700 Subject: [rust-dev] Cap'n Proto and region variables In-Reply-To: References: <20130724130933.GF2179@Mr-Bennet> Message-ID: David: That error seems pretty similar to this one ( https://github.com/mozilla/rust/issues/7331), so I added your code as another example. On Wed, Jul 24, 2013 at 4:26 PM, David Renshaw wrote: > Looks like it's broken at the moment. If I try to compile this program: > > trait Constructable<'self> { fn construct(v : &'self[u8]) -> Self; } > fn main() { } > > I get this error: > > error: internal compiler error: ty::Region#subst(): Reference to self > region when given substs with no self region: substs(self_r=None, > self_ty=Some(BUG[0]), tps=[]) > > On Wed, Jul 24, 2013 at 9:09 AM, Niko Matsakis wrote: > > On Sun, Jul 21, 2013 at 12:44:24PM -0400, David Renshaw wrote: > >> Hello everyone, > >> > >> I'm playing around with a Rust implementation for Cap'n Proto. Check > >> it out: http://github.com/dwrensha/capnproto-rust . I welcome any > >> comments or contributions. > >> > >> The reason I'm sharing this project with you now is I'd like to ask > >> about a language feature missing from Rust that I feel may be > >> hindering my progress. > >> > >> To the point, I want to be able define a trait like this: > >> > >> trait Constructable<'self> { > >> fn construct<'a>(StructReader<'a>) -> Self<'a>; > >> } > > > > I believe it would it be possible to define the trait like so: > > > > trait Constructable<'self> { > > fn construct(StructReader<'self>) -> Self; > > } > > > > > > > > regards, > > > > Niko > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From erick.tryzelaar at gmail.com Fri Jul 26 09:32:20 2013 From: erick.tryzelaar at gmail.com (Erick Tryzelaar) Date: Fri, 26 Jul 2013 09:32:20 -0700 Subject: [rust-dev] Cap'n Proto and region variables In-Reply-To: References: <20130724130933.GF2179@Mr-Bennet> Message-ID: ... and I just found a workaround for you: trait Constructable { fn construct<'a>(v : &'a [u8]) -> Self; } fn main() { } Compiles fine for me. On Fri, Jul 26, 2013 at 9:30 AM, Erick Tryzelaar wrote: > David: That error seems pretty similar to this one ( > https://github.com/mozilla/rust/issues/7331), so I added your code as > another example. > > > On Wed, Jul 24, 2013 at 4:26 PM, David Renshaw wrote: > >> Looks like it's broken at the moment. If I try to compile this program: >> >> trait Constructable<'self> { fn construct(v : &'self[u8]) -> Self; } >> fn main() { } >> >> I get this error: >> >> error: internal compiler error: ty::Region#subst(): Reference to self >> region when given substs with no self region: substs(self_r=None, >> self_ty=Some(BUG[0]), tps=[]) >> >> On Wed, Jul 24, 2013 at 9:09 AM, Niko Matsakis wrote: >> > On Sun, Jul 21, 2013 at 12:44:24PM -0400, David Renshaw wrote: >> >> Hello everyone, >> >> >> >> I'm playing around with a Rust implementation for Cap'n Proto. Check >> >> it out: http://github.com/dwrensha/capnproto-rust . I welcome any >> >> comments or contributions. >> >> >> >> The reason I'm sharing this project with you now is I'd like to ask >> >> about a language feature missing from Rust that I feel may be >> >> hindering my progress. >> >> >> >> To the point, I want to be able define a trait like this: >> >> >> >> trait Constructable<'self> { >> >> fn construct<'a>(StructReader<'a>) -> Self<'a>; >> >> } >> > >> > I believe it would it be possible to define the trait like so: >> > >> > trait Constructable<'self> { >> > fn construct(StructReader<'self>) -> Self; >> > } >> > >> > >> > >> > regards, >> > >> > Niko >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From michaelwoerister at gmail.com Fri Jul 26 09:35:54 2013 From: michaelwoerister at gmail.com (Michael Woerister) Date: Fri, 26 Jul 2013 18:35:54 +0200 Subject: [rust-dev] Removing codemap::spanned In-Reply-To: <51F2A150.4040305@mozilla.com> References: <51E163E2.70507@gmail.com> <51E17F81.1040502@mozilla.com> <51E3A746.9050608@gmail.com> <51E432A8.7010204@mozilla.com> <51E434DB.2070005@gmail.com> <51E45A6D.5030407@mozilla.com> <51F29BC1.8010508@gmail.com> <51F2A150.4040305@mozilla.com> Message-ID: <51F2A56A.5030709@gmail.com> On 07/26/2013 06:18 PM, Patrick Walton wrote: > On 7/26/13 8:54 AM, Michael Woerister wrote: >> To me this seems very much like a slightly clunky way of emulating >> inheritance (with a lot more typing involved at definition and usage >> sites). Field accessor functions or traits can alleviate some of this >> clunkyness at the usage site; however, at the cost of even more >> boilerplate needed at the definition site: >> >> pub enum decl { >> decl_local(@Local, span), >> decl_item(@item, span), >> } >> >> impl decl { >> fn get_span(&self) { >> // this match statement also introduces some unnecessary >> runtime overhead... >> match *self { >> decl_local(_, span) => span, >> decl_item(_, span) => span >> } >> } >> } >> >> This situation is not very satisfactory but I don't know an easy >> solution to the problem. I certainly don't suggest adding such a heavy >> tool as inheritance to Rust just for this use case. > > This is the preferred method of emulating common fields. We use this > in Servo. > > I would like to add an optimization to remove the unnecessary runtime > overhead in this case. In theory this should be amenable to compiler > optimizations. Yes, if all common fields are placed in the same order at the beginning of every variant, all arms of the match should result in the same LLVM code generated. Maybe LLVM can optimize this already? Thanks for your answer! -Michael From graydon at mozilla.com Fri Jul 26 09:36:50 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 26 Jul 2013 09:36:50 -0700 Subject: [rust-dev] Buildbot upgraded, bors reminder Message-ID: <51F2A5A2.7020607@mozilla.com> Hi, The buildbot upgrade is more-or-less done (I need to do some no-op upgrades on the slaves today but this carries no risk); we're now on buildbot 0.8.8rc1. If you see any behavior that worries you or appears to be a new error, please let me know. For the most part it should behave as before, but a little more robustly. Meanwhile: the bors queue has 44 entries in it. This is not, as it might appear, strictly a matter of cycle time: only 3 of those entries are approved; 7 are stale, 12 failed integration and are pending fixes, and the remainder are at some point in the review cycle. If you have a PR in a state where it can be moved forward some, please take a moment to do so. The longer a PR sits idle in the queue, the greater the odds of entropy killing it. -Graydon From corey at octayn.net Fri Jul 26 09:47:53 2013 From: corey at octayn.net (Corey Richardson) Date: Fri, 26 Jul 2013 12:47:53 -0400 Subject: [rust-dev] rustdoc_ng update Message-ID: Hi all, Just a quick update on the status of rustdoc_ng. The core of it is progressing nicely. Starting to nail down a workable JSON schema and getting the difficult moving parts solid. Hammering out some of the finer details like "how can you cross-link to a different crate" and "should we impose a formatting language in doc comments". Meanwhile a bunch of my time has been redirected towards non-Rust things. If you want to help out, there is an issue tracker at https://github.com/cmr/rustdoc_ng/issues. We track current master right now (or should) so it's easy to get going. In particular, https://github.com/cmr/rustdoc_ng/issues/3 is mostly just tedious work of "add struct, extract from AST, write Clean and ToJson impls", and is very easy. We have a channel, #rustdoc-wg, on irc.mozilla.net. Join if you have questions, want to help out, or have idea to contribute! (The ML works too, though). Thanks From dwrenshaw at gmail.com Fri Jul 26 10:28:43 2013 From: dwrenshaw at gmail.com (David Renshaw) Date: Fri, 26 Jul 2013 13:28:43 -0400 Subject: [rust-dev] Cap'n Proto and region variables In-Reply-To: References: <20130724130933.GF2179@Mr-Bennet> Message-ID: I don't think that workaround helps in my case. The next thing I want is a struct: struct SegmentReader<'self> { data : &'self [u8] } which implements `Constructable`. None of the following compile successfully: impl <'self> Constructable for SegmentReader<'self> { fn construct(v : &'self [u8]) -> SegmentReader<'self> { SegmentReader { data : v } } } impl <'self> Constructable for SegmentReader<'self> { fn construct<'self>(v : &'self [u8]) -> SegmentReader<'self> { SegmentReader { data : v } } } impl <'self> Constructable for SegmentReader<'self> { fn construct<'a>(v : &'a [u8]) -> SegmentReader<'a> { SegmentReader { data : v } } } On Fri, Jul 26, 2013 at 12:32 PM, Erick Tryzelaar wrote: > ... and I just found a workaround for you: > > trait Constructable { fn construct<'a>(v : &'a [u8]) -> Self; } > fn main() { } > > Compiles fine for me. > > > > On Fri, Jul 26, 2013 at 9:30 AM, Erick Tryzelaar > wrote: >> >> David: That error seems pretty similar to this one >> (https://github.com/mozilla/rust/issues/7331), so I added your code as >> another example. >> >> >> On Wed, Jul 24, 2013 at 4:26 PM, David Renshaw >> wrote: >>> >>> Looks like it's broken at the moment. If I try to compile this program: >>> >>> trait Constructable<'self> { fn construct(v : &'self[u8]) -> Self; } >>> fn main() { } >>> >>> I get this error: >>> >>> error: internal compiler error: ty::Region#subst(): Reference to self >>> region when given substs with no self region: substs(self_r=None, >>> self_ty=Some(BUG[0]), tps=[]) >>> >>> On Wed, Jul 24, 2013 at 9:09 AM, Niko Matsakis wrote: >>> > On Sun, Jul 21, 2013 at 12:44:24PM -0400, David Renshaw wrote: >>> >> Hello everyone, >>> >> >>> >> I'm playing around with a Rust implementation for Cap'n Proto. Check >>> >> it out: http://github.com/dwrensha/capnproto-rust . I welcome any >>> >> comments or contributions. >>> >> >>> >> The reason I'm sharing this project with you now is I'd like to ask >>> >> about a language feature missing from Rust that I feel may be >>> >> hindering my progress. >>> >> >>> >> To the point, I want to be able define a trait like this: >>> >> >>> >> trait Constructable<'self> { >>> >> fn construct<'a>(StructReader<'a>) -> Self<'a>; >>> >> } >>> > >>> > I believe it would it be possible to define the trait like so: >>> > >>> > trait Constructable<'self> { >>> > fn construct(StructReader<'self>) -> Self; >>> > } >>> > >>> > >>> > >>> > regards, >>> > >>> > Niko >>> _______________________________________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/listinfo/rust-dev >> >> > From erick.tryzelaar at gmail.com Fri Jul 26 10:49:13 2013 From: erick.tryzelaar at gmail.com (Erick Tryzelaar) Date: Fri, 26 Jul 2013 10:49:13 -0700 Subject: [rust-dev] Cap'n Proto and region variables In-Reply-To: References: <20130724130933.GF2179@Mr-Bennet> Message-ID: Yep, you are right. I think this is going to need #7331 fixed to work for you. On Fri, Jul 26, 2013 at 10:28 AM, David Renshaw wrote: > I don't think that workaround helps in my case. The next thing I want > is a struct: > > struct SegmentReader<'self> { data : &'self [u8] } > > which implements `Constructable`. None of the following compile > successfully: > > > impl <'self> Constructable for SegmentReader<'self> { > fn construct(v : &'self [u8]) -> SegmentReader<'self> { > SegmentReader { data : v } > } > } > > > impl <'self> Constructable for SegmentReader<'self> { > fn construct<'self>(v : &'self [u8]) -> SegmentReader<'self> { > SegmentReader { data : v } > } > } > > > impl <'self> Constructable for SegmentReader<'self> { > fn construct<'a>(v : &'a [u8]) -> SegmentReader<'a> { > SegmentReader { data : v } > } > } > > > > On Fri, Jul 26, 2013 at 12:32 PM, Erick Tryzelaar > wrote: > > ... and I just found a workaround for you: > > > > trait Constructable { fn construct<'a>(v : &'a [u8]) -> Self; } > > fn main() { } > > > > Compiles fine for me. > > > > > > > > On Fri, Jul 26, 2013 at 9:30 AM, Erick Tryzelaar < > erick.tryzelaar at gmail.com> > > wrote: > >> > >> David: That error seems pretty similar to this one > >> (https://github.com/mozilla/rust/issues/7331), so I added your code as > >> another example. > >> > >> > >> On Wed, Jul 24, 2013 at 4:26 PM, David Renshaw > >> wrote: > >>> > >>> Looks like it's broken at the moment. If I try to compile this program: > >>> > >>> trait Constructable<'self> { fn construct(v : &'self[u8]) -> Self; } > >>> fn main() { } > >>> > >>> I get this error: > >>> > >>> error: internal compiler error: ty::Region#subst(): Reference to self > >>> region when given substs with no self region: substs(self_r=None, > >>> self_ty=Some(BUG[0]), tps=[]) > >>> > >>> On Wed, Jul 24, 2013 at 9:09 AM, Niko Matsakis > wrote: > >>> > On Sun, Jul 21, 2013 at 12:44:24PM -0400, David Renshaw wrote: > >>> >> Hello everyone, > >>> >> > >>> >> I'm playing around with a Rust implementation for Cap'n Proto. Check > >>> >> it out: http://github.com/dwrensha/capnproto-rust . I welcome any > >>> >> comments or contributions. > >>> >> > >>> >> The reason I'm sharing this project with you now is I'd like to ask > >>> >> about a language feature missing from Rust that I feel may be > >>> >> hindering my progress. > >>> >> > >>> >> To the point, I want to be able define a trait like this: > >>> >> > >>> >> trait Constructable<'self> { > >>> >> fn construct<'a>(StructReader<'a>) -> Self<'a>; > >>> >> } > >>> > > >>> > I believe it would it be possible to define the trait like so: > >>> > > >>> > trait Constructable<'self> { > >>> > fn construct(StructReader<'self>) -> Self; > >>> > } > >>> > > >>> > > >>> > > >>> > regards, > >>> > > >>> > Niko > >>> _______________________________________________ > >>> Rust-dev mailing list > >>> Rust-dev at mozilla.org > >>> https://mail.mozilla.org/listinfo/rust-dev > >> > >> > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From illissius at gmail.com Fri Jul 26 11:08:08 2013 From: illissius at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Fri, 26 Jul 2013 20:08:08 +0200 Subject: [rust-dev] 'in' for for loops and alloc exprs In-Reply-To: References: <51F077BE.9090601@mozilla.com> <51F14575.6050509@exyr.org> <51F16EF6.2080603@mozilla.com> Message-ID: +1 for `for x in xs { }` +1 for `in` as placement new, as far as I understand it +1 for keeping `do` and `do 666.times { }` +1 for `:` as type ascription (yay!) On Thu, Jul 25, 2013 at 11:28 PM, Thad Guidry wrote: > I also like 'do 10,times {' , since I likely would also use it to create > multiple copies (one after the other). A lazy sequence for my purposes > dealing with data generation. > > Just to clarify, 'do 10.times {' would NOT allow launching multiple copies > in parallel, correct ? (that's reserved for Actor styles, etc, etc.) Just > simple repetition, as you say ? > > > On Thu, Jul 25, 2013 at 3:46 PM, Benjamin Striegel > wrote: > >> > If we did that, we'd lose the ability to break or return, since 'do' >> doesn't follow the for-style loop protocol. >> >> I'm perfectly happy with that; the `times` method was never about complex >> control flow, just simple repetition. `do 10.times {` is a delightfully >> self-explanatory contract. >> >> And just as evidence that `do` notation is useful beyond `spawn`: >> >> $ git grep "do .*{" -- "*.rs" | wc -l >> 2019 >> $ git grep "do .*spawn" -- "*.rs" | wc -l >> 274 >> >> > we're likely to switch that to a macro call that passes >> explicitly-captured arguments into a thunk struct that owns the explicit >> captures >> >> I don't remember seeing much of this idea in the meeting notes, but I do >> remember seeing it mentioned in these blog posts (for those who want more >> context): >> >> http://smallcultfollowing.com/babysteps/blog/2013/05/30/removing-procs/ >> http://smallcultfollowing.com/babysteps/blog/2013/06/03/more-on-fns/ >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> > > > -- > -Thad > Thad on Freebase.com > Thad on LinkedIn > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -- Your ship was destroyed in a monadic eruption. -------------- next part -------------- An HTML attachment was scrubbed... URL: From me at kevincantu.org Fri Jul 26 22:40:43 2013 From: me at kevincantu.org (Kevin Cantu) Date: Fri, 26 Jul 2013 22:40:43 -0700 Subject: [rust-dev] New Ubuntu PPA In-Reply-To: <51E863DA.1060104@mozilla.com> References: <51E863DA.1060104@mozilla.com> Message-ID: This is really awesome. I've been meaning to ask somebody to take this up for a while now! Thanks! Kevin -- Kevin Cantu On Thu, Jul 18, 2013 at 2:53 PM, Brian Anderson wrote: > On 07/18/2013 01:47 PM, Hans J?rgen Hoel wrote: > >> Hi, >> >> I've set up a new PPA with nightly builds: >> >> https://launchpad.net/~**hansjorg/+archive/rust< >> https://launchpad.net/%**7Ehansjorg/+archive/rust >> > >> >> >> There's also a 0.7 version (as well as 0.5 and 0.6, but only for quantal). >> >> The packages use the alternatives system, so you can have multiple >> versions installed at once. To switch rustc & co: >> >> $ sudo update-alternatives --config rustc >> > > Added this to https://github.com/mozilla/**rust/wiki/Doc-packages,-** > editors,-and-other-tools > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alex at crichton.co Fri Jul 26 23:37:22 2013 From: alex at crichton.co (Alex Crichton) Date: Fri, 26 Jul 2013 23:37:22 -0700 Subject: [rust-dev] Redesigning fmt! Message-ID: I recently looked into redesigning fmt!, and I wanted to post my ideas before going all the way to ensure that I'm not missing out on anything. == Today's state == As of today, fmt! works pretty well. It's a very useful function and will likely be a very common thing in all rust code using libstd. It does have a few drawbacks though: 1. It always returns ~str. This should not be the case, rather it should always write into some form of stream (io::Writer/io::rt::Writer). This avoids any unnecessary allocations. 2. If you're formatting via %X, then the value must have one, and only one type (you can't implement %s for your own types). 3. Format specifiers are a predefined compiler constant. It would be pretty awesome if libraries/programs could specify their own fmt! specifiers via something like a #[fmt="name"] attribute 4. Currently fmt! results in a lot of code at the callsite. This is because the string allocation and building the string are all implemented inline. Only the actual conversions to strings are performed in function calls. 5. It's generally slow right now due to performing large numbers of intermediate allocations. A printing function should perform 0 allocations. There are probably other limitations, but those are the big ones I can think of. == What I'd like to see == I'm envisioning a rustc that predefines two macros, fmt! and fprintf! (maybe ffmt!). The former would be as it is today, returning ~str, and the latter would take a stream instance to write information to. Then fmt! would be implemented with a memory buffer to fprintf!. This would solve problem 1 (kinda, more down below). Furthermore, the codegen would be different. Format strings would still be parsed at compile time, but the format string would be passed through instead of passing around these Conv structures at runtime. This means that the actual function will then take a string and a slice of values to print (the types of the values are verified at compile-time still). This would solve problem 2. All printing will be done through traits. For example: #[fmt="d"] trait Signed { // Emit to Formatter's stream using its parameters for width/precision/etc. fn fmt(&Self, &mut std::fmt::Formatter); } Anything which implements this trait can then be used with the '%d' format specifier. Furthermore this means that you can create user-defined format specifiers (via the fmt attribute). I would imaging that multi-char format specifiers could be something like: "%(mytype)". This solves problems 3 and 4. I'd also do my best at the same time to remove any and all allocations, but it's not guaranteed that the system today can do that. Right now I think that there's limitations blocking this. == Is this possible? == In my opinion, the way to go about this is not to use trait parameterization, but rather trait objects. In order to avoid allocations, the functions should also take &Trait. From what I can tell, however, this is fairly broken and most operations don't work at all. Plus I don't think there's any coercion from ~Trait and @Trait to &Trait yet. Regardless, for now I don't think that fprintf! can exist, but I do believe that I can rewrite fmt! to use this new system of defining formats. I can also try to open up specific bugs about &Traits to get them to a working conditions. === Does this sound like a sane replacement for fmt? All code today would work the same as it used to, but in theory it would be a bit faster and hopefully more powerful as well. From thadguidry at gmail.com Sat Jul 27 07:47:05 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Sat, 27 Jul 2013 09:47:05 -0500 Subject: [rust-dev] Great summary of Windows Compiler Toolchain Options Message-ID: I recently found the QT project has a great summary of the state of things for Windows users concerning Toolchains and Compiler choices supporting Exception Handling and their differences. http://qt-project.org/wiki/MinGW-64-bit -- -Thad Thad on Freebase.com Thad on LinkedIn -------------- next part -------------- An HTML attachment was scrubbed... URL: From illissius at gmail.com Sat Jul 27 07:51:38 2013 From: illissius at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Sat, 27 Jul 2013 16:51:38 +0200 Subject: [rust-dev] RFC: Removing *T Message-ID: Spurred by https://github.com/mozilla/rust/issues/7694 I was thinking about the differences between `*` and `&` and the reason both need to exist. As far as I can tell the differences boil down to: - The compiler makes no attempt to enforce any invariants for `*T` Meaning that, in an interesting duality-ish: - Creating `*T` out of `&T` (or anything else) and manipulating it in any which way is always safe - Dereferencing `*T` is unsafe - Creating `&T` out of `*T` is unsafe - Dereferencing `&T` (and whatever else the language lets you do with it) is safe Behind it is proof obligations. `*T` has no implied invariants and therefore doesn't require proof of anything, while as long as you stick to `&T`, safety is proved by the compiler. It's at the boundary where the burden is on the programmer: to assert (with an `unsafe` block) that the invariants required for dereferencing `*T` and/or converting it to `&T` really do hold. The use case for `*T` is operations which are not known to respect invariants: notably foreign functions, also e.g. pointer arithmetic. The invariants required of `&T` but not `*T` are: 1. The pointer is not null 2. The pointed-to object is of type `T` 3. The pointed-to object is alive and initialized 4. (Im)mutability and aliasing related invariants The latter three of which are guaranteed for the lifetime associated with the pointer. Now crazy ideas: We can waive the first invariant by using `Option`. If we could guarantee in the language that `None : Option<&T>` is represented as a null pointer, then I see no reason whatsoever to keep allowing implicit nullability. It's binary compatible with C, so (except where can't-be-null is known) C interfaces would simply use Option. It forces proper attention to nulls, and I don't actually see any drawback. We can waive the other invariants by taking advantage of the fact that they're predicated on a lifetime, to introduce a new special lifetime `'unsafe`, which is the inverse of `'static`. Where `'static` is always known to be alive, `'unsafe` never is. (So `'static` is top and `'unsafe` is bottom.) Therefore converting `&'a T` to `&'unsafe T` is always allowed, while if you have an `&'unsafe T` and want to convert it to a pointer with a longer lifetime and dereference it, you have to use `unsafe { }`, just as with `*T`. Functions parameterized over lifetime variables would continue to require that the lifetime encompass the duration of the call, so if you want to allow `&'unsafe T` as an argument, you have to write that explicitly (again as with `*T`). One question is whether you might want to waive 2-4. with finer granularity: - You could waive only 2. by using `&()`. It's not clear to me if it makes sense to talk about a definitely-live-and-initialized(-and-immutable) value of unknown type, but if there's a use case for it, it can be satisfied. - I don't think it makes sense to waive only 3.: you can't say a dead or uninitialized value is of type T, because it could be *anything* (which is why `'unsafe` above, conceptually most closely tied to 3., also waives 2. and 4.). - It might make sense to waive only 4.: you might care only that a value is alive and of type T, not whether anyone else is mutating it: this is `&const T` (which is hoped to be removed). You might also want to mutate it while not caring whether anyone else is also reading or writing: there's no separate mutability qualifier for this, a use case might be e.g. atomic operations. But even in the absence of any special features, these can still be satisfied by using `&'unsafe [mut] T`, which is an overapproximation, just as with `*[mut] T` today. (Corresponding to the separate invariants, it might make sense to have separate functions for unsafely manipulating the pointed-to type, lifetime, and mutability of a borrowed pointer, instead of just the catch-all `transmute()`, similarly to C++.) Summary: I think we could replace `*` pointers with a combination of guaranteeing the null pointer optimization for `Option` (kinda like TCO) and introducing a new special lifetime `'unsafe`. This would retain the desirable properties of the current system, while being superior in other ways, such as orthogonality. Whether and how to waive aliasing and mutability related invariants separately from the others might need more thinking, but is independent. Thoughts? -- Your ship was destroyed in a monadic eruption. -------------- next part -------------- An HTML attachment was scrubbed... URL: From zo1980 at gmail.com Sat Jul 27 08:48:29 2013 From: zo1980 at gmail.com (=?UTF-8?B?Wm9sdMOhbiBUw7N0aA==?=) Date: Sat, 27 Jul 2013 17:48:29 +0200 Subject: [rust-dev] 'in' for for loops and alloc exprs In-Reply-To: <51F077BE.9090601@mozilla.com> References: <51F077BE.9090601@mozilla.com> Message-ID: On Thu, Jul 25, 2013 at 2:56 AM, Graydon Hoare wrote: > > for in { ... } > > What about changing the order? I mean: in for { ... } or loop with { ... } Then the coder can drop the pattern part without making the wording weird: loop 10.times() { ... } My motivation is actaully something different: I feel this order more intuitive. I during coding generally like to be able to write the code in the order that I think. When I want to write a loop, first I think about that I want to iterate over some collection. Only after that do I think about a suitable name for the loop_variable / iterator. I understand that most programming languages use the order and that programmers are used to it, but I think to be be intuitive is more important than to be similar, especially for a new language. -------------- next part -------------- An HTML attachment was scrubbed... URL: From armin.ronacher at active-4.com Sat Jul 27 09:27:14 2013 From: armin.ronacher at active-4.com (Armin Ronacher) Date: Sat, 27 Jul 2013 18:27:14 +0200 Subject: [rust-dev] 'in' for for loops and alloc exprs In-Reply-To: References: <51F077BE.9090601@mozilla.com> Message-ID: <51F3F4E2.5000000@active-4.com> Hi, On 27/07/2013 17:48, Zolt?n T?th wrote: > What about changing the order? Not a fan. However at that point you can also use "=>": loop [1, 2, 3] => i { ... } Generally though huge +1 on "for in " just because it's very familiar to people. "in" is a common keyword and can also be utilized for other things. If no other use can be found then you can make " in " a binop that compiles to .contains() similar to how it works in Python. Regards, Armin From ipc at informatic.io Sat Jul 27 09:40:15 2013 From: ipc at informatic.io (Ian P. Cooke) Date: Sat, 27 Jul 2013 11:40:15 -0500 Subject: [rust-dev] 'in' for for loops and alloc exprs In-Reply-To: References: <51F077BE.9090601@mozilla.com> Message-ID: On Jul 27, 2013, at 10:48 , Zolt?n T?th wrote: > Then the coder can drop the pattern part without making the wording weird: > > loop 10.times() { ... } > This syntax has always bugged me. I always read it as "send the message 'times' to the object named '10'" but 10 is an integer literal and integers don't have behavior. The '10.times()' syntax makes it look to the reader that he's observing a conversation with a number rather than a dictation of the actions that 'self' is about to perform. I know Smalltalk and Ruby use similar syntax but I feel like they're also wrong to do so. I like any of the following: for i in 1..10 {} for i in range(10) {} for _ in range(10) {} //if you don't care about the index of the iteration for i in range(1, 20, 2) {} all of which are more clear to me. Something as core as control flow should have a simple syntax without object-oriented-looking, DSL-type cleverness. I don't intend to start a debate on the merit of any the various syntax choices but this thread made me want to assure at least one anti-'10.times()' opinion was heard :) > My motivation is actaully something different: I feel this order more intuitive. I during coding generally like to be able to write the code in the order that I think. When I want to write a loop, first I think about that I want to iterate over some collection. Only after that do I think about a suitable name for the loop_variable / iterator. I understand that most programming languages use the order and that programmers are used to it, but I think to be be intuitive is more important than to be similar, especially for a new language. I do agree with this. SQL has a similar issue: FROM t SELECT x, y, z makes more sense (and as such can get more context-sensitive help) than SELECT x, y, z FROM t. Microsoft's Linq gets this order right IMO. In fact, Linq is pretty awesome in general ( http://msdn.microsoft.com/en-us/library/vstudio/bb397906.aspx, http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b ) although my opinion is mostly academic there. Having language-level support for the notion of a query would be incredibly useful to me (unifying local and remote collections). -ipc -------------- next part -------------- An HTML attachment was scrubbed... URL: From illissius at gmail.com Sat Jul 27 10:10:20 2013 From: illissius at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Sat, 27 Jul 2013 19:10:20 +0200 Subject: [rust-dev] RFC: Removing *T In-Reply-To: References: Message-ID: Some discussion has sprouted on reddit: http://www.reddit.com/r/rust/comments/1j5vbn/rustdev_rfc_removing_t/ On Sat, Jul 27, 2013 at 4:51 PM, G?bor Lehel wrote: > Spurred by https://github.com/mozilla/rust/issues/7694 I was thinking > about the differences between `*` and `&` and the reason both need to > exist. > > As far as I can tell the differences boil down to: > > - The compiler makes no attempt to enforce any invariants for `*T` > > Meaning that, in an interesting duality-ish: > > - Creating `*T` out of `&T` (or anything else) and manipulating it in > any which way is always safe > - Dereferencing `*T` is unsafe > - Creating `&T` out of `*T` is unsafe > - Dereferencing `&T` (and whatever else the language lets you do with it) > is safe > > Behind it is proof obligations. `*T` has no implied invariants and > therefore doesn't require proof of anything, while as long as you stick to > `&T`, safety is proved by the compiler. It's at the boundary where the > burden is on the programmer: to assert (with an `unsafe` block) that the > invariants required for dereferencing `*T` and/or converting it to `&T` > really do hold. > > The use case for `*T` is operations which are not known to respect > invariants: notably foreign functions, also e.g. pointer arithmetic. > > The invariants required of `&T` but not `*T` are: > > 1. The pointer is not null > 2. The pointed-to object is of type `T` > 3. The pointed-to object is alive and initialized > 4. (Im)mutability and aliasing related invariants > > The latter three of which are guaranteed for the lifetime associated with > the pointer. > > Now crazy ideas: > > We can waive the first invariant by using `Option`. If we could guarantee > in the language that `None : Option<&T>` is represented as a null pointer, > then I see no reason whatsoever to keep allowing implicit nullability. It's > binary compatible with C, so (except where can't-be-null is known) C > interfaces would simply use Option. It forces proper attention to nulls, > and I don't actually see any drawback. > > We can waive the other invariants by taking advantage of the fact that > they're predicated on a lifetime, to introduce a new special lifetime > `'unsafe`, which is the inverse of `'static`. Where `'static` is always > known to be alive, `'unsafe` never is. (So `'static` is top and `'unsafe` > is bottom.) Therefore converting `&'a T` to `&'unsafe T` is always allowed, > while if you have an `&'unsafe T` and want to convert it to a pointer with > a longer lifetime and dereference it, you have to use `unsafe { }`, just > as with `*T`. Functions parameterized over lifetime variables would > continue to require that the lifetime encompass the duration of the call, > so if you want to allow `&'unsafe T` as an argument, you have to write that > explicitly (again as with `*T`). > > One question is whether you might want to waive 2-4. with finer > granularity: > > - You could waive only 2. by using `&()`. It's not clear to me if it makes > sense to talk about a definitely-live-and-initialized(-and-immutable) value > of unknown type, but if there's a use case for it, it can be satisfied. > > - I don't think it makes sense to waive only 3.: you can't say a dead or > uninitialized value is of type T, because it could be *anything* (which is > why `'unsafe` above, conceptually most closely tied to 3., also waives 2. > and 4.). > > - It might make sense to waive only 4.: you might care only that a value > is alive and of type T, not whether anyone else is mutating it: this is > `&const T` (which is hoped to be removed). You might also want to mutate it > while not caring whether anyone else is also reading or writing: there's no > separate mutability qualifier for this, a use case might be e.g. atomic > operations. But even in the absence of any special features, these can > still be satisfied by using `&'unsafe [mut] T`, which is an > overapproximation, just as with `*[mut] T` today. > > (Corresponding to the separate invariants, it might make sense to have > separate functions for unsafely manipulating the pointed-to type, lifetime, > and mutability of a borrowed pointer, instead of just the catch-all > `transmute()`, similarly to C++.) > > Summary: > > I think we could replace `*` pointers with a combination of guaranteeing > the null pointer optimization for `Option` (kinda like TCO) and introducing > a new special lifetime `'unsafe`. This would retain the desirable > properties of the current system, while being superior in other ways, such > as orthogonality. Whether and how to waive aliasing and mutability related > invariants separately from the others might need more thinking, but is > independent. > > Thoughts? > > -- > Your ship was destroyed in a monadic eruption. > -- Your ship was destroyed in a monadic eruption. -------------- next part -------------- An HTML attachment was scrubbed... URL: From thadguidry at gmail.com Sat Jul 27 17:26:47 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Sat, 27 Jul 2013 19:26:47 -0500 Subject: [rust-dev] 'in' for for loops and alloc exprs In-Reply-To: References: <51F077BE.9090601@mozilla.com> Message-ID: Ian, Graydon, Community, I am fairly NEW to programming in current languages at all... So I am a great guinea pig for testing all these conversations about "What would a beginner to Rust...or even programming languages in general" think about this ? I personally think that "dot notation" is fine, and I have learned why others, such as yourself, think that using "dot notation" might bring some unfamiliarity in using it. It does not rub me the wrong way, and has a "functional order" to it, but that is because my background way, way back when, was only with functional languages. In the end, folks have preferences, primarily based on "what your used to using that did not make your brain explode trying to understand it, and made you fairly productive". In this case, I would hope that the language design is decided by not a majority vote wins, but what represents a "pleasant taste in the mouth" 90% of the time when programming Rust, no matter their background. I would encourage the community to repeat good designs, and stretch out against bad designs and debated language preferences that folks have. You cannot please everyone, but a good goal would be that "90% pleasant taste in the mouth". That's not trademarked, so your free to use that Graydon, if necessary. :-) So, back to the original thread subject you brought up... Re-using "in" seems to also leave a pleasant taste in my mouth, simply because I do not have a high preference, and am easily adaptable. I find that if you can design a language that reads fairly well, WORKS AS DOCUMENTED, and as a bonus is intuitive for 90% of the folks that read 50% of the docs or less...then you've got a winning language design. (and I would not hope that your sealing up the language just yet - since there is no high visibility, in production system that is using it - but I do understand the causal effects of introducing more keywords in this later stage of design) On Sat, Jul 27, 2013 at 11:40 AM, Ian P. Cooke wrote: > > On Jul 27, 2013, at 10:48 , Zolt?n T?th wrote: > > Then the coder can drop the pattern part without making the wording weird: > > loop 10.times() { ... } > > > This syntax has always bugged me. I always read it as "send the message > 'times' to the object named '10'" but 10 is an integer literal and integers > don't have behavior. The '10.times()' syntax makes it look to the reader > that he's observing a conversation with a number rather than a dictation of > the actions that 'self' is about to perform. I know Smalltalk and Ruby use > similar syntax but I feel like they're also wrong to do so. I like any of > the following: > > for i in 1..10 {} > for i in range(10) {} > for _ in range(10) {} //if you don't care about the index of the iteration > for i in range(1, 20, 2) {} > > all of which are more clear to me. Something as core as control flow > should have a simple syntax without object-oriented-looking, DSL-type > cleverness. > > I don't intend to start a debate on the merit of any the various syntax > choices but this thread made me want to assure at least one > anti-'10.times()' opinion was heard :) > > My motivation is actaully something different: I feel this order more > intuitive. I during coding generally like to be able to write the code in > the order that I think. When I want to write a loop, first I think about > that I want to iterate over some collection. Only after that do I think > about a suitable name for the loop_variable / iterator. I understand that > most programming languages use the order and that > programmers are used to it, but I think to be be intuitive is more > important than to be similar, especially for a new language. > > > I do agree with this. SQL has a similar issue: > > FROM t SELECT x, y, z > > makes more sense (and as such can get more context-sensitive help) than > > SELECT x, y, z FROM t. > > Microsoft's Linq gets this order right IMO. In fact, Linq is pretty > awesome in general ( > http://msdn.microsoft.com/en-us/library/vstudio/bb397906.aspx, > http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b ) although my > opinion is mostly academic there. Having language-level support for the > notion of a query would be incredibly useful to me (unifying local and > remote collections). > > -ipc > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -- -Thad Thad on Freebase.com Thad on LinkedIn -------------- next part -------------- An HTML attachment was scrubbed... URL: From erick.tryzelaar at gmail.com Sat Jul 27 18:34:36 2013 From: erick.tryzelaar at gmail.com (Erick Tryzelaar) Date: Sat, 27 Jul 2013 18:34:36 -0700 Subject: [rust-dev] RFC: Removing *T In-Reply-To: References: Message-ID: Hey G?bor! This is a neat observation! I especially like how Option<&T> represents nullable pointers. However, I am not sure if a bottom region as you described quite captures the right semantics. While it's neat how it falls out naturally that you need to use an unsafe block to dereference a `&'unsafe T`, this bottom region also have a shorter lifetime then every other region. So this would mean we couldn't safely return these pointers without a cast. Because of this, I think pointers have a couple orthogonal semantics: 1. Mutablility 2. Safety 3. Lifetime If my unsafe region pointers patch lands, we support all these cases. That said, I still think there is a good argument about whether or not we need unsafe pointers in the library or in the language. bstrie brought up this idea of moving *T out of the language and into a library, as in an Unsafe or RawPtr type. If we implement RawPtr as: struct RawPtr; impl RawPtr { unsafe fn get(&self) -> T { intrinsics::get(self) } unsafe fn set(&self, x: T) -> T { intrinsics::set(self, x) } ... } Then I *think* it supports all the semantics we need. If I'm not missing anything, I'd rather have this, reject my patch, and remove unsafe pointers altogether from the compiler. -Erick On Saturday, July 27, 2013, G?bor Lehel wrote: > Some discussion has sprouted on reddit: > http://www.reddit.com/r/rust/comments/1j5vbn/rustdev_rfc_removing_t/ > > On Sat, Jul 27, 2013 at 4:51 PM, G?bor Lehel wrote: > > Spurred by https://github.com/mozilla/rust/issues/7694 I was thinking > about the differences between `*` and `&` and the reason both need to > exist. > > As far as I can tell the differences boil down to: > > - The compiler makes no attempt to enforce any invariants for `*T` > > Meaning that, in an interesting duality-ish: > > - Creating `*T` out of `&T` (or anything else) and manipulating it in > any which way is always safe > - Dereferencing `*T` is unsafe > - Creating `&T` out of `*T` is unsafe > - Dereferencing `&T` (and whatever else the language lets you do with it) > is safe > > Behind it is proof obligations. `*T` has no implied invariants and > therefore doesn't require proof of anything, while as long as you stick to > `&T`, safety is proved by the compiler. It's at the boundary where the > burden is on the programmer: to assert (with an `unsafe` block) that the > invariants required for dereferencing `*T` and/or converting it to `&T` > really do hold. > > The use case for `*T` is operations which are not known to respect > invariants: notably foreign functions, also e.g. pointer arithmetic. > > The invariants required of `&T` but not `*T` are: > > 1. The pointer is not null > 2. The pointed-to object is of type `T` > 3. The pointed-to object is alive and initialized > 4. (Im)mutability and aliasing related invariants > > The latter three of which are guaranteed for the lifetime associated with > the pointer. > > Now crazy ideas: > > We can waive the first invariant by using `Option`. If we could guarantee > in the language that `None : Option<&T>` is represented as a null pointer, > then I see no reason whatsoever to keep allowing implicit nullability. It's > binary compatible with C, so (except where can't-be-null is known) C > interfaces would simply use Option. It forces proper attention to nulls, > and I don't actually see any drawback. > > We can waive the other invariants by taking advantage of the fact that > they're predicated on a lifetime, to introduce a new special lifetime > `'unsafe`, which is the inverse of `'static`. Where `'static` is always > known to be alive, `'unsafe` never is. (So `'static` is top and `'unsafe` > is bottom.) Therefore converting `&'a T` to `&'unsafe T` is always allowed, > while if you have an `&'unsafe T` and want to convert it to a pointer with > a longer lifetime and dereference it, you have to use `unsafe { }`, just > as with `*T`. Functions parameterized over lifetime variables would > continue to require that the lifetime encompass the duration of the call, > so if you want to allow `&'unsafe T` as an argument, you have to write that > explicitly (again as with `*T`). > > One question is whether you might want to waive 2-4. with finer > granularity: > > - You could waive only 2. by using `&()`. It's not clear to me if it makes > sense to talk about a definitely-live-and-initialized(-and-immutable) value > of unknown type, but if there's a use case for it, it can be satisfied. > > - I don't think it makes sense to waive only 3.: you can't say a dead or > uninitialized value is of type T, because it could be *anything* (which is > why `'unsafe` above, conceptually most closely tied to 3., also waives 2. > and 4.). > > - It might make sense to waive only 4.: you might care only that a value > is alive and of type T, not whether anyone else is mutating it: this is > `&const T` (which is hoped to be removed). You might also want to mutate it > while not caring whether anyone else is also reading or writing: there's no > separate mutability qualifier for this, a use case might be e.g. atomic > operations. But even in the absence of any special features, these can > still be satisfied by using `&'unsafe [mut] T`, which is an > overapproximation, just as with `*[mut] T` today. > > (Corresponding to the separate invariants, it might make sense to have > separate functions for unsafely manipulating the pointed-to type, lifetime, > and mutability of a borrowed pointer, instead of just the catch-all > `transmute()`, similarly to C++.) > > Summary: > > I think we could replace `*` pointers with a combination of guarantee > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Sat Jul 27 21:56:18 2013 From: banderson at mozilla.com (Brian Anderson) Date: Sat, 27 Jul 2013 21:56:18 -0700 Subject: [rust-dev] Portland, OR Friday 6:30pm: Patrick Walton & Jack Moffitt talk sprocketnes & Servo In-Reply-To: References: Message-ID: <51F4A472.8080404@mozilla.com> On 07/24/2013 11:05 PM, Tom Lee wrote: > Hey all, > > If you're in Portland, OR this week -- as many are for OSCON -- > Patrick Walton & Jack Moffitt are taking some time out of their > schedules to talk Rust this Friday evening, 26th of July @ 6:30pm: > > http://calagator.org/events/1250464569 > > All welcome, feel free to pop in & say hi -- elevators should be open > from around 6:15pm. > > We'll be supplying beer & pizza. There's also plenty of soda if you're > not alcohol-ly inclined. Any other questions, feel free to ping me at > this address. > I had a fantastic time at this event, and heartily recommend that any Rusties in Portland attend these in the future. Great work, Tom, and thanks. -Brian From armin.ronacher at active-4.com Sun Jul 28 01:57:40 2013 From: armin.ronacher at active-4.com (Armin Ronacher) Date: Sun, 28 Jul 2013 10:57:40 +0200 Subject: [rust-dev] RFC: Removing *T In-Reply-To: References: Message-ID: <51F4DD04.5010805@active-4.com> Hi, On 28/07/2013 03:34, Erick Tryzelaar wrote: > That said, I still think there is a good argument about whether or not > we need unsafe pointers in the library or in the language. bstrie > brought up this idea of moving *T out of the language and into a > library, as in an Unsafe or RawPtr type. Right now one of Rust's biggest strengths is how easy it is to interface with C libraries. Rust stands alone in how well integrated it is. Removing *T and replacing it with a generic struct is going to make this very simple thing very complicated. Why do that? Just to get rid of a star? It would be a different thing if we could build things like std::shared_ptr and overload all operators and it integrates well into the rest of the language, but Rust is not built with that in mind. Just look at how much more complicated bindings to C libraries would become if you remove *T. Regards, Armin From dbau.pp at gmail.com Sun Jul 28 02:13:04 2013 From: dbau.pp at gmail.com (Huon Wilson) Date: Sun, 28 Jul 2013 19:13:04 +1000 Subject: [rust-dev] RFC: Removing *T In-Reply-To: <51F4DD04.5010805@active-4.com> References: <51F4DD04.5010805@active-4.com> Message-ID: <51F4E0A0.3070107@gmail.com> On 28/07/13 18:57, Armin Ronacher wrote: > It would be a different thing if we could build things like > std::shared_ptr and overload all operators and it integrates well > into the rest of the language, but Rust is not built with that in mind. > As I understand it, this is planned[1] as part of the move-GC-to-the-libraries proposal[2]: that is, provide some traits with lang-items (like Eq, Add, Drop, etc.) which, for example, give library pointers the ability to be auto-borrowed to &. Huon [1]: http://www.reddit.com/r/rust/comments/1fkhe6/removing_garbage_collection_from_the_rust_language/cab7tv5?context=3 [2]: http://pcwalton.github.io/blog/2013/06/02/removing-garbage-collection-from-the-rust-language/ From bsteinbr at gmail.com Sun Jul 28 03:06:13 2013 From: bsteinbr at gmail.com (=?iso-8859-1?Q?Bj=F6rn?= Steinbrink) Date: Sun, 28 Jul 2013 12:06:13 +0200 Subject: [rust-dev] LLVM assertions Message-ID: <20130728100613.GA4693@atjola.homenet> Hi, out of curiosity (and because perf results hinted me to do so), I tried compiling rustc with disabled LLVM assertions. Compile times were reduced by about 25%-30%. For example stage1 librustc takes about 2m12s with assertions enabled and 1m38s with assertions disabled. So if you're only working on e.g. libstd, it seems like a good idea to disable them. Bj?rn From armin.ronacher at active-4.com Sun Jul 28 04:00:41 2013 From: armin.ronacher at active-4.com (Armin Ronacher) Date: Sun, 28 Jul 2013 13:00:41 +0200 Subject: [rust-dev] RFC: Removing *T In-Reply-To: <51F4E0A0.3070107@gmail.com> References: <51F4DD04.5010805@active-4.com> <51F4E0A0.3070107@gmail.com> Message-ID: <51F4F9D9.2040700@active-4.com> Hi, On 28/07/2013 11:13, Huon Wilson wrote: > As I understand it, this is planned[1] as part of the > move-GC-to-the-libraries proposal[2]: that is, provide some traits with > lang-items (like Eq, Add, Drop, etc.) which, for example, give library > pointers the ability to be auto-borrowed to &. This however will be quite a complex undertaking. To make that work the compiler would have to perform quite a few syntax transformation (like moving code into closures etc.). That sounds quite a bit like opening a new can of worms. Regards, Armin From alcosholik at gmail.com Sun Jul 28 09:18:53 2013 From: alcosholik at gmail.com (Alexei Sholik) Date: Sun, 28 Jul 2013 19:18:53 +0300 Subject: [rust-dev] Implement Digest trait for MD4 and MD5 Message-ID: Hi guys, I have implemented Digest for MD4 and added an implementation of MD5. I'm keeping the code in a separate repo so that I don't have to rebuild Rust -- https://github.com/alco/rust-digest. There is also a draft of HMAC and an additional utility trait to make it easy to get one-off digests from vectors and strings. I hope that at least MD4 and MD5 can make it into upstream. Can you please take a look and give some advice on how I should integrate my MD4 changes (just replace the old implementation?) and new MD5 implementation into libextra. One thing in particular that I'm wary about is that the implementations for MD4 and MD5 are almost identical -- only the inner loop is different. Naturally, I would like to unify them as much as possible by putting both into a single module. Any advice on that will be appreciated. Thanks! -- Best regards Alexei Sholik -------------- next part -------------- An HTML attachment was scrubbed... URL: From alcosholik at gmail.com Sun Jul 28 09:21:38 2013 From: alcosholik at gmail.com (Alexei Sholik) Date: Sun, 28 Jul 2013 19:21:38 +0300 Subject: [rust-dev] Implement Digest trait for MD4 and MD5 In-Reply-To: References: Message-ID: BTW, while I'm at it, I was also thinking about adding basic implementations of Adler-32 and CRC32. Any opinions or wishes regarding this? Thanks! On Sun, Jul 28, 2013 at 7:18 PM, Alexei Sholik wrote: > Hi guys, > > I have implemented Digest for MD4 and added an implementation of MD5. I'm > keeping the code in a separate repo so that I don't have to rebuild Rust -- > https://github.com/alco/rust-digest. There is also a draft of HMAC and an > additional utility trait to make it easy to get one-off digests from > vectors and strings. > > I hope that at least MD4 and MD5 can make it into upstream. Can you please > take a look and give some advice on how I should integrate my MD4 changes > (just replace the old implementation?) and new MD5 implementation into > libextra. > > One thing in particular that I'm wary about is that the implementations > for MD4 and MD5 are almost identical -- only the inner loop is different. > Naturally, I would like to unify them as much as possible by putting both > into a single module. Any advice on that will be appreciated. > > Thanks! > > -- > Best regards > Alexei Sholik > -- Best regards Alexei Sholik -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Sun Jul 28 09:44:05 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Sun, 28 Jul 2013 09:44:05 -0700 Subject: [rust-dev] LLVM assertions In-Reply-To: <20130728100613.GA4693@atjola.homenet> References: <20130728100613.GA4693@atjola.homenet> Message-ID: <51F54A55.6010106@mozilla.com> On 7/28/13 3:06 AM, Bj?rn Steinbrink wrote: > Hi, > > out of curiosity (and because perf results hinted me to do so), I tried > compiling rustc with disabled LLVM assertions. Compile times were > reduced by about 25%-30%. For example stage1 librustc takes about 2m12s > with assertions enabled and 1m38s with assertions disabled. > > So if you're only working on e.g. libstd, it seems like a good idea to > disable them. Wow! We should do this by default. Patrick From pwalton at mozilla.com Sun Jul 28 09:46:15 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Sun, 28 Jul 2013 09:46:15 -0700 Subject: [rust-dev] RFC: Removing *T In-Reply-To: <51F4F9D9.2040700@active-4.com> References: <51F4DD04.5010805@active-4.com> <51F4E0A0.3070107@gmail.com> <51F4F9D9.2040700@active-4.com> Message-ID: <51F54AD7.20806@mozilla.com> On 7/28/13 4:00 AM, Armin Ronacher wrote: > Hi, > > On 28/07/2013 11:13, Huon Wilson wrote: >> As I understand it, this is planned[1] as part of the >> move-GC-to-the-libraries proposal[2]: that is, provide some traits with >> lang-items (like Eq, Add, Drop, etc.) which, for example, give library >> pointers the ability to be auto-borrowed to &. > This however will be quite a complex undertaking. To make that work the > compiler would have to perform quite a few syntax transformation (like > moving code into closures etc.). That sounds quite a bit like opening a > new can of worms. It's not that complicated. Most of the hard work is in placement new. And it's not like we have a choice really: Servo is starting to grow custom smart pointers all over the place (the DOM, probably the Flow tree, all JS objects, ARC, RWARC...) Making them stay second-class forever is kind of a non-starter at this point. Patrick From pwalton at mozilla.com Sun Jul 28 09:50:05 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Sun, 28 Jul 2013 09:50:05 -0700 Subject: [rust-dev] RFC: Removing *T In-Reply-To: References: Message-ID: <51F54BBD.6050504@mozilla.com> On 7/27/13 7:51 AM, G?bor Lehel wrote: > Thoughts? Niko and I discussed and debated this exact proposal a few months ago :) The outcome was that it wasn't worth it for a few reasons: * The FFI really wants sweet syntax for C pointers. * `'unsafe` isn't really a region, as it doesn't fit in the region hierarchy. Regions are related by a subtyping relationship, and `'unsafe` is neither at the top nor the bottom of the hierarchy. You really don't want the compiler inferring `'unsafe` as the least upper bound or greatest lower bound when relating two regions, for example. I'm as sympathetic as anybody to want to reduce the number of pointer types in the language, as it's folks' #1 complaint about Rust. But I think this one is probably a necessary evil. Patrick From corey at octayn.net Sun Jul 28 09:52:06 2013 From: corey at octayn.net (Corey Richardson) Date: Sun, 28 Jul 2013 12:52:06 -0400 Subject: [rust-dev] LLVM assertions In-Reply-To: <51F54A55.6010106@mozilla.com> References: <20130728100613.GA4693@atjola.homenet> <51F54A55.6010106@mozilla.com> Message-ID: On Sun, Jul 28, 2013 at 12:44 PM, Patrick Walton wrote: > Wow! We should do this by default. > Not sure this is a good idea, not as long as we still have LLVM-related ICEs and assertions. From pwalton at mozilla.com Sun Jul 28 10:30:56 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Sun, 28 Jul 2013 10:30:56 -0700 Subject: [rust-dev] LLVM assertions In-Reply-To: References: <20130728100613.GA4693@atjola.homenet> <51F54A55.6010106@mozilla.com> Message-ID: <51F55550.8080606@mozilla.com> On 7/28/13 9:52 AM, Corey Richardson wrote: > On Sun, Jul 28, 2013 at 12:44 PM, Patrick Walton wrote: >> Wow! We should do this by default. >> > > Not sure this is a good idea, not as long as we still have > LLVM-related ICEs and assertions. > Well, keep in mind that debug logging is now turned off unless you build with CFG_ENABLE_DEBUG, so assertions aren't really debuggable anymore without building the compiler in debug mode. So folks debugging assertions will have to build without CFG_ENABLE_DEBUG, and I think it's reasonable to have LLVM assertions on for those builds. Patrick From pwalton at mozilla.com Sun Jul 28 10:31:28 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Sun, 28 Jul 2013 10:31:28 -0700 Subject: [rust-dev] LLVM assertions In-Reply-To: <51F55550.8080606@mozilla.com> References: <20130728100613.GA4693@atjola.homenet> <51F54A55.6010106@mozilla.com> <51F55550.8080606@mozilla.com> Message-ID: <51F55570.2010209@mozilla.com> On 7/28/13 10:30 AM, Patrick Walton wrote: > On 7/28/13 9:52 AM, Corey Richardson wrote: >> On Sun, Jul 28, 2013 at 12:44 PM, Patrick Walton >> wrote: >>> Wow! We should do this by default. >>> >> >> Not sure this is a good idea, not as long as we still have >> LLVM-related ICEs and assertions. >> > > Well, keep in mind that debug logging is now turned off unless you build > with CFG_ENABLE_DEBUG, so assertions aren't really debuggable anymore > without building the compiler in debug mode. So folks debugging > assertions will have to build without CFG_ENABLE_DEBUG, and I think it's > reasonable to have LLVM assertions on for those builds. Err, *with* CFG_ENABLE_DEBUG. Patrick From danielmicay at gmail.com Sun Jul 28 10:34:41 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Sun, 28 Jul 2013 13:34:41 -0400 Subject: [rust-dev] LLVM assertions In-Reply-To: <51F55550.8080606@mozilla.com> References: <20130728100613.GA4693@atjola.homenet> <51F54A55.6010106@mozilla.com> <51F55550.8080606@mozilla.com> Message-ID: On Sun, Jul 28, 2013 at 1:30 PM, Patrick Walton wrote: > On 7/28/13 9:52 AM, Corey Richardson wrote: >> >> On Sun, Jul 28, 2013 at 12:44 PM, Patrick Walton >> wrote: >>> >>> Wow! We should do this by default. >>> >> >> Not sure this is a good idea, not as long as we still have >> LLVM-related ICEs and assertions. >> > > Well, keep in mind that debug logging is now turned off unless you build > with CFG_ENABLE_DEBUG, so assertions aren't really debuggable anymore > without building the compiler in debug mode. So folks debugging assertions > will have to build without CFG_ENABLE_DEBUG, and I think it's reasonable to > have LLVM assertions on for those builds. > > Patrick I think the issue is that we may have silent, uncaught bugs if we turn off LLVM assertions by default. An assertion might not be easy to debug by default, but we'll still get a bug report from a user who runs into one. From danielmicay at gmail.com Sun Jul 28 10:42:51 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Sun, 28 Jul 2013 13:42:51 -0400 Subject: [rust-dev] RFC: Removing *T In-Reply-To: <51F54BBD.6050504@mozilla.com> References: <51F54BBD.6050504@mozilla.com> Message-ID: On Sun, Jul 28, 2013 at 12:50 PM, Patrick Walton wrote: > > I'm as sympathetic as anybody to want to reduce the number of pointer types > in the language, as it's folks' #1 complaint about Rust. But I think this > one is probably a necessary evil. > > > Patrick We can reduce the number of pointer types in the language by describing the language with semantic terms rather than implementation details of the compiler. The safe subset of Rust lacks pointers in the same way that a language like Ruby lacks them. For example, `~[T]` is described as a unique vector, despite being a pointer. It feels like we're going out of our way to make the language complex when we use a term like "borrowed pointer" instead of just calling it a reference like Java. The documentation would be so much simpler if it just referred to references and unique/managed boxes. Rust only has two types that are semantically pointers, `*` and `*mut`. From illissius at gmail.com Sun Jul 28 13:10:11 2013 From: illissius at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Sun, 28 Jul 2013 22:10:11 +0200 Subject: [rust-dev] RFC: Removing *T In-Reply-To: References: Message-ID: I've found the short circuit in my brain: the problem is that an (in hindsight embarrassingly obvious) invariant of `&'a T` is that it's outlived by whatever it's pointing at, which is what has the lifetime (at least) 'a. So if 'unsafe is the empty lifetime, then `&'unsafe T` is an oxymoron: it can't exist. What I was consistently confusing it with (I think I might've relied on different interpretations in different places) is the idea of a pointer which lives however long, but can only *be dereferenced* within the given lifetime. I wonder if the latter is theoretically feasible at all? In any case, I think this also shows that the ban on `&'a &'b T` where 'a outlives 'b is principled, and follows from simple transitivity: if the given `&'b T` has lifetime at least 'a, and is outlived by the given T with lifetime at least 'b, it follows that 'b must be greater than 'a. Pseudo-formally: 1. 'a >= lifetime(given &'a &'b T) 2. lifetime(given &'b T) >= 'a 3. 'b >= lifetime(given &'b T) 4. lifetime(given T) >= 'b ----- 'b >= 'a (from 2. and 3.) On Sat, Jul 27, 2013 at 4:51 PM, G?bor Lehel wrote: > > Summary: > > I think we could replace `*` pointers with a combination of guaranteeing > the null pointer optimization for `Option` (kinda like TCO) and introducing > a new special lifetime `'unsafe`. This would retain the desirable > properties of the current system, while being superior in other ways, such > as orthogonality. Whether and how to waive aliasing and mutability related > invariants separately from the others might need more thinking, but is > independent. > > Thoughts? > > -- > Your ship was destroyed in a monadic eruption. > -- Your ship was destroyed in a monadic eruption. -------------- next part -------------- An HTML attachment was scrubbed... URL: From illissius at gmail.com Sun Jul 28 13:17:33 2013 From: illissius at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Sun, 28 Jul 2013 22:17:33 +0200 Subject: [rust-dev] RFC: Removing *T In-Reply-To: References: <51F54BBD.6050504@mozilla.com> Message-ID: On Sun, Jul 28, 2013 at 7:42 PM, Daniel Micay wrote: > > On Sun, Jul 28, 2013 at 12:50 PM, Patrick Walton wrote: > > > > I'm as sympathetic as anybody to want to reduce the number of pointer types > > in the language, as it's folks' #1 complaint about Rust. But I think this > > one is probably a necessary evil. > > > > > > Patrick > > We can reduce the number of pointer types in the language by > describing the language with semantic terms rather than implementation > details of the compiler. The safe subset of Rust lacks pointers in the > same way that a language like Ruby lacks them. > > For example, `~[T]` is described as a unique vector, despite being a > pointer. It feels like we're going out of our way to make the language > complex when we use a term like "borrowed pointer" instead of just > calling it a reference like Java. > > The documentation would be so much simpler if it just referred to > references and unique/managed boxes. Rust only has two types that are > semantically pointers, `*` and `*mut`. +infinity -- Your ship was destroyed in a monadic eruption. From banderson at mozilla.com Sun Jul 28 13:48:45 2013 From: banderson at mozilla.com (Brian Anderson) Date: Sun, 28 Jul 2013 13:48:45 -0700 Subject: [rust-dev] Implement Digest trait for MD4 and MD5 In-Reply-To: References: Message-ID: <51F583AD.6060503@mozilla.com> On 07/28/2013 09:18 AM, Alexei Sholik wrote: > Hi guys, > > I have implemented Digest for MD4 and added an implementation of MD5. > I'm keeping the code in a separate repo so that I don't have to > rebuild Rust -- https://github.com/alco/rust-digest. There is also a > draft of HMAC and an additional utility trait to make it easy to get > one-off digests from vectors and strings. > > I hope that at least MD4 and MD5 can make it into upstream. Can you > please take a look and give some advice on how I should integrate my > MD4 changes (just replace the old implementation?) and new MD5 > implementation into libextra. > > One thing in particular that I'm wary about is that the > implementations for MD4 and MD5 are almost identical -- only the inner > loop is different. Naturally, I would like to unify them as much as > possible by putting both into a single module. Any advice on that will > be appreciated. > Right now it looks like we an extra::crypto module that contains a Digest trait, implemented by a number of SHA variants in crypto::sha1 and crypto::sha2. Curiously extra::md4 looks to be unrelated to extra::crypto (I guess it's just old and unmaintained). So I have a few questions: * Can all digest functions implement Digest? * Is it appropriate for all digests to live in extra::crypto? Not all hashes are crypto hashes... Based on what we have now I'd recommend deleting extra::md4, moving your md4/5 into extra::crypto, and integrating them with the Digest trait. Certainly though I've only given this cursory thought (and I haven't read your code yet), so other opinions welcome. -Brian From banderson at mozilla.com Sun Jul 28 13:54:18 2013 From: banderson at mozilla.com (Brian Anderson) Date: Sun, 28 Jul 2013 13:54:18 -0700 Subject: [rust-dev] RFC: Removing *T In-Reply-To: References: <51F54BBD.6050504@mozilla.com> Message-ID: <51F584FA.6020307@mozilla.com> On 07/28/2013 01:17 PM, G?bor Lehel wrote: > On Sun, Jul 28, 2013 at 7:42 PM, Daniel Micay wrote: >> On Sun, Jul 28, 2013 at 12:50 PM, Patrick Walton wrote: >>> I'm as sympathetic as anybody to want to reduce the number of pointer types >>> in the language, as it's folks' #1 complaint about Rust. But I think this >>> one is probably a necessary evil. >>> >>> >>> Patrick >> We can reduce the number of pointer types in the language by >> describing the language with semantic terms rather than implementation >> details of the compiler. The safe subset of Rust lacks pointers in the >> same way that a language like Ruby lacks them. >> >> For example, `~[T]` is described as a unique vector, despite being a >> pointer. It feels like we're going out of our way to make the language >> complex when we use a term like "borrowed pointer" instead of just >> calling it a reference like Java. >> >> The documentation would be so much simpler if it just referred to >> references and unique/managed boxes. Rust only has two types that are >> semantically pointers, `*` and `*mut`. FWIW I prefer the terms box and reference. I don't really understand the idea that only * is 'semantically a pointer' though. From illissius at gmail.com Sun Jul 28 14:06:48 2013 From: illissius at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Sun, 28 Jul 2013 23:06:48 +0200 Subject: [rust-dev] RFC: Removing *T In-Reply-To: References: Message-ID: On Sun, Jul 28, 2013 at 3:34 AM, Erick Tryzelaar wrote: > Hey G?bor! > > This is a neat observation! Thanks. > I especially like how Option<&T> represents > nullable pointers. However, I am not sure if a bottom region as you > described quite captures the right semantics. While it's neat how it falls > out naturally that you need to use an unsafe block to dereference a > `&'unsafe T`, this bottom region also have a shorter lifetime then every > other region. So this would mean we couldn't safely return these pointers > without a cast. > > Because of this, I think pointers have a couple orthogonal semantics: > > 1. Mutablility > 2. Safety > 3. Lifetime > > If my unsafe region pointers patch lands, we support all these cases. I think I still don't grok the meaning of lifetimes on *T. Is the lifetime a necessary or sufficient condition for anything, or is it just a helpful guardrail? > > That said, I still think there is a good argument about whether or not we > need unsafe pointers in the library or in the language. bstrie brought up > this idea of moving *T out of the language and into a library, as in an > Unsafe or RawPtr type. If we implement RawPtr as: > > struct RawPtr; > > impl RawPtr { > unsafe fn get(&self) -> T { intrinsics::get(self) } > unsafe fn set(&self, x: T) -> T { intrinsics::set(self, x) } > ... > } > > Then I *think* it supports all the semantics we need. If I'm not missing > anything, I'd rather have this, reject my patch, and remove unsafe pointers > altogether from the compiler. I think there's two independent questions. One is syntax. *T or RawPtr? (@T or Gc?) Syntax sugar isn't inherently good or bad: it's sweet, but too much can make you feel bad. We have Lisp at one extreme and Perl at the other. We should strive to find a pleasant balance. It might be worthwhile to have it really be "just sugar" by making @T, ~T, &T, and *T be aliases for distinguished types Gc, Owned, Ref<'a, T>, and Ptr (for example), regardless of which syntax candies we ultimately keep (I think I saw something like this in the bug tracker?). (Personally I lean towards keeping, in part because nested This> is unpleasant, and it's nice to avoid it .) The other is implementation. In the compiler or as a library? This one seems less ambiguous: anything that can be done in a library probably should be. If we can put Gc, Ptr etc. in libraries and have the compiler just do desugaring (if anything), why not? (I think this wouldn't be possible for Owned, because it's not parametric in T (the representation depends on whether T is managed)? Rust doesn't have anything like C++'s template specialization. Won't all of them have this issue with DST, with representations depending on whether T is Sized?) > > -Erick > > > On Saturday, July 27, 2013, G?bor Lehel wrote: >> >> Some discussion has sprouted on reddit: >> http://www.reddit.com/r/rust/comments/1j5vbn/rustdev_rfc_removing_t/ >> >> On Sat, Jul 27, 2013 at 4:51 PM, G?bor Lehel wrote: >> >> Spurred by https://github.com/mozilla/rust/issues/7694 I was thinking >> about the differences between `*` and `&` and the reason both need to exist. >> >> As far as I can tell the differences boil down to: >> >> - The compiler makes no attempt to enforce any invariants for `*T` >> >> Meaning that, in an interesting duality-ish: >> >> - Creating `*T` out of `&T` (or anything else) and manipulating it in >> any which way is always safe >> - Dereferencing `*T` is unsafe >> - Creating `&T` out of `*T` is unsafe >> - Dereferencing `&T` (and whatever else the language lets you do with it) >> is safe >> >> Behind it is proof obligations. `*T` has no implied invariants and >> therefore doesn't require proof of anything, while as long as you stick to >> `&T`, safety is proved by the compiler. It's at the boundary where the >> burden is on the programmer: to assert (with an `unsafe` block) that the >> invariants required for dereferencing `*T` and/or converting it to `&T` >> really do hold. >> >> The use case for `*T` is operations which are not known to respect >> invariants: notably foreign functions, also e.g. pointer arithmetic. >> >> The invariants required of `&T` but not `*T` are: >> >> 1. The pointer is not null >> 2. The pointed-to object is of type `T` >> 3. The pointed-to object is alive and initialized >> 4. (Im)mutability and aliasing related invariants >> >> The latter three of which are guaranteed for the lifetime associated with >> the pointer. >> >> Now crazy ideas: >> >> We can waive the first invariant by using `Option`. If we could guarantee >> in the language that `None : Option<&T>` is represented as a null pointer, >> then I see no reason whatsoever to keep allowing implicit nullability. It's >> binary compatible with C, so (except where can't-be-null is known) C >> interfaces would simply use Option. It forces proper attention to nulls, and >> I don't actually see any drawback. >> >> We can waive the other invariants by taking advantage of the fact that >> they're predicated on a lifetime, to introduce a new special lifetime >> `'unsafe`, which is the inverse of `'static`. Where `'static` is always >> known to be alive, `'unsafe` never is. (So `'static` is top and `'unsafe` is >> bottom.) Therefore converting `&'a T` to `&'unsafe T` is always allowed, >> while if you have an `&'unsafe T` and want to convert it to a pointer with a >> longer lifetime and dereference it, you have to use `unsafe { }`, just as >> with `*T`. Functions parameterized over lifetime variables would continue to >> require that the lifetime encompass the duration of the call, so if you want >> to allow `&'unsafe T` as an argument, you have to write that explicitly >> (again as with `*T`). >> >> One question is whether you might want to waive 2-4. with finer >> granularity: >> >> - You could waive only 2. by using `&()`. It's not clear to me if it makes >> sense to talk about a definitely-live-and-initialized(-and-immutable) value >> of unknown type, but if there's a use case for it, it can be satisfied. >> >> - I don't think it makes sense to waive only 3.: you can't say a dead or >> uninitialized value is of type T, because it could be *anything* (which is >> why `'unsafe` above, conceptually most closely tied to 3., also waives 2. >> and 4.). >> >> - It might make sense to waive only 4.: you might care only that a value >> is alive and of type T, not whether anyone else is mutating it: this is >> `&const T` (which is hoped to be removed). You might also want to mutate it >> while not caring whether anyone else is also reading or writing: there's no >> separate mutability qualifier for this, a use case might be e.g. atomic >> operations. But even in the absence of any special features, these can still >> be satisfied by using `&'unsafe [mut] T`, which is an overapproximation, >> just as with `*[mut] T` today. >> >> (Corresponding to the separate invariants, it might make sense to have >> separate functions for unsafely manipulating the pointed-to type, lifetime, >> and mutability of a borrowed pointer, instead of just the catch-all >> `transmute()`, similarly to C++.) >> >> Summary: >> >> I think we could replace `*` pointers with a combination of guarantee -- Your ship was destroyed in a monadic eruption. From masanori.ogino at gmail.com Sun Jul 28 14:32:35 2013 From: masanori.ogino at gmail.com (Masanori Ogino) Date: Mon, 29 Jul 2013 06:32:35 +0900 Subject: [rust-dev] Implement Digest trait for MD4 and MD5 In-Reply-To: <51F583AD.6060503@mozilla.com> References: <51F583AD.6060503@mozilla.com> Message-ID: Please take with a pinch of salt since I'm not an expert. > BTW, while I'm at it, I was also thinking about adding basic implementations of Adler-32 and CRC32. CRC-32 and Adler-32 are not digest functions but checksum functions, aren't they? > * Can all digest functions implement Digest? Probably. > * Is it appropriate for all digests to live in extra::crypto? Not all hashes are crypto hashes... AFAIK usually (message) digests means hash values of *cryptographic* hash functions. Non-cryptographic hash functions could be in std::hash, I think. -- Masanori Ogino http://twitter.com/omasanori http://gplus.to/omasanori -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Sun Jul 28 14:34:06 2013 From: banderson at mozilla.com (Brian Anderson) Date: Sun, 28 Jul 2013 14:34:06 -0700 Subject: [rust-dev] Redesigning fmt! In-Reply-To: References: Message-ID: <51F58E4E.2000809@mozilla.com> On 07/26/2013 11:37 PM, Alex Crichton wrote: > I recently looked into redesigning fmt!, and I wanted to post my ideas before > going all the way to ensure that I'm not missing out on anything. Fabulous. There's a number of related info in #2249 and sub-bugs. Other designs have been floated for this before as well, but I don't know where they are. > == Today's state == > > As of today, fmt! works pretty well. It's a very useful function and will likely > be a very common thing in all rust code using libstd. It does have a few > drawbacks though: > > 1. It always returns ~str. This should not be the case, rather it should always > write into some form of stream (io::Writer/io::rt::Writer). This avoids any > unnecessary allocations. Certainly the implementation should work by writing to a buffer and not concatenating strings, and the core interface should take a Writer or similar. The `let foo = fmt!(...);` use case is very convenient though. > 2. If you're formatting via %X, then the value must have one, and only one type > (you can't implement %s for your own types). > 3. Format specifiers are a predefined compiler constant. It would be pretty > awesome if libraries/programs could specify their own fmt! specifiers via > something like a #[fmt="name"] attribute Maybe. This would likely require some deep magic. There maybe other options for specifying format placeholders that don't require allocating alphabetic characters for the task ala printf. I really think we should be looking outside the printf box. > 4. Currently fmt! results in a lot of code at the callsite. This is because the > string allocation and building the string are all implemented inline. Only > the actual conversions to strings are performed in function calls. Yep. Reducing inline bloat is critical. > 5. It's generally slow right now due to performing large numbers of intermediate > allocations. A printing function should perform 0 allocations. > > There are probably other limitations, but those are the big ones I can think of. > > == What I'd like to see == > > I'm envisioning a rustc that predefines two macros, fmt! and fprintf! (maybe > ffmt!). The former would be as it is today, returning ~str, and the latter would > take a stream instance to write information to. Then fmt! would be implemented > with a memory buffer to fprintf!. This would solve problem 1 (kinda, more down > below). > > Furthermore, the codegen would be different. Format strings would still be > parsed at compile time, but the format string would be passed through instead of > passing around these Conv structures at runtime. This means that the actual > function will then take a string and a slice of values to print (the types of > the values are verified at compile-time still). This would solve problem 2. I don't see why this solves problem 2 (overloading format specifiers for different types). By passing the original string it will have to reparse at runtime. I don't understand the reasoning here. > All printing will be done through traits. For example: > > #[fmt="d"] > trait Signed { > // Emit to Formatter's stream using its parameters for > width/precision/etc. > fn fmt(&Self, &mut std::fmt::Formatter); > } > > Anything which implements this trait can then be used with the '%d' format > specifier. Furthermore this means that you can create user-defined format > specifiers (via the fmt attribute). I would imaging that multi-char format > specifiers could be something like: "%(mytype)". This solves problems 3 and 4. I'm not a fan of printf-style format specifiers in general, largely because the specifiers have to be allocated in some way (fmt attribute) so are not particularly extensible. I can't imagine how this fmt attribute can be implemented in a general way using current compiler mechanisms, and am in favor of looking to other languages for guidance on how formatting should be done instead of leaning on crusty old C here. > > I'd also do my best at the same time to remove any and all allocations, but it's > not guaranteed that the system today can do that. Right now I think that there's > limitations blocking this. > > == Is this possible? == > > In my opinion, the way to go about this is not to use trait parameterization, > but rather trait objects. In order to avoid allocations, the functions should > also take &Trait. From what I can tell, however, this is fairly broken and most > operations don't work at all. Plus I don't think there's any coercion from > ~Trait and @Trait to &Trait yet. It does seem like &Trait has a role here. I'd like to see a firm idea of what the runtime interface looks like. I imagine it can all be encapsulated in a simple signature like `fn format(&mut io::Writer, &[(&Formattable, FormatSpecifier)])`, where every chunk of the format string and the values to insert into it are cast to a stack object and paired with some metadata indicating how it should be formatted. Such an interface doesn't have any room for type-specific format traits like `Signed` though. > > Regardless, for now I don't think that fprintf! can exist, but I do believe that > I can rewrite fmt! to use this new system of defining formats. I can also try to > open up specific bugs about &Traits to get them to a working conditions. > > === > > Does this sound like a sane replacement for fmt? All code today would > work the same as it used to, but in theory it would be a bit faster > and hopefully more powerful as well. In my opinion it is not ambitious enough since it leaves the printf style intact, but I have something of a vendetta against printf. It does seem likely though that we can come up with a runtime interface that is reasonably decoupled from the string-based specification of formats; create a migration path from printf-style formatting to something better. -Brian From palmercox at gmail.com Sun Jul 28 14:36:02 2013 From: palmercox at gmail.com (Palmer Cox) Date: Sun, 28 Jul 2013 17:36:02 -0400 Subject: [rust-dev] Implement Digest trait for MD4 and MD5 In-Reply-To: <51F583AD.6060503@mozilla.com> References: <51F583AD.6060503@mozilla.com> Message-ID: The thing about the existing MD4 implementation is that it wants to process the entire message all at once, whereas the Digest trait defines an interface to incrementally pass in chunks of the message before getting a final digest value at the end. There is no fundamental reason that I'm aware of that MD4 couldn't be updated to implement that interface. However, I didn't do that work when I implemented the Digest trait so I figured moving it to crypto wouldn't make sense until it was updated. I actually just submitted a pull request that implements MD5 along with creating some utility code that should hopefully be useful for implementing block based digest functions: https://github.com/mozilla/rust/pull/8097 On Sun, Jul 28, 2013 at 4:48 PM, Brian Anderson wrote: > On 07/28/2013 09:18 AM, Alexei Sholik wrote: > >> Hi guys, >> >> I have implemented Digest for MD4 and added an implementation of MD5. I'm >> keeping the code in a separate repo so that I don't have to rebuild Rust -- >> https://github.com/alco/rust-**digest. >> There is also a draft of HMAC and an additional utility trait to make it >> easy to get one-off digests from vectors and strings. >> >> I hope that at least MD4 and MD5 can make it into upstream. Can you >> please take a look and give some advice on how I should integrate my MD4 >> changes (just replace the old implementation?) and new MD5 implementation >> into libextra. >> >> One thing in particular that I'm wary about is that the implementations >> for MD4 and MD5 are almost identical -- only the inner loop is different. >> Naturally, I would like to unify them as much as possible by putting both >> into a single module. Any advice on that will be appreciated. >> >> > Right now it looks like we an extra::crypto module that contains a Digest > trait, implemented by a number of SHA variants in crypto::sha1 and > crypto::sha2. Curiously extra::md4 looks to be unrelated to extra::crypto > (I guess it's just old and unmaintained). > > So I have a few questions: > > * Can all digest functions implement Digest? > * Is it appropriate for all digests to live in extra::crypto? Not all > hashes are crypto hashes... > > Based on what we have now I'd recommend deleting extra::md4, moving your > md4/5 into extra::crypto, and integrating them with the Digest trait. > Certainly though I've only given this cursory thought (and I haven't read > your code yet), so other opinions welcome. > > -Brian > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Sun Jul 28 14:39:41 2013 From: banderson at mozilla.com (Brian Anderson) Date: Sun, 28 Jul 2013 14:39:41 -0700 Subject: [rust-dev] Redesigning fmt! In-Reply-To: References: Message-ID: <51F58F9D.70906@mozilla.com> On 07/26/2013 11:37 PM, Alex Crichton wrote: > I recently looked into redesigning fmt!, and I wanted to post my ideas before > going all the way to ensure that I'm not missing out on anything. Another thing that needs to be considered is how format modifiers (things like significant digits etc. in printf) can be generalized to arbitrary types and what those requirements are. The options available to printf are very specific to ints, floats and whatever other few types it supports. From danielmicay at gmail.com Sun Jul 28 14:54:21 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Sun, 28 Jul 2013 17:54:21 -0400 Subject: [rust-dev] RFC: Removing *T In-Reply-To: <51F584FA.6020307@mozilla.com> References: <51F54BBD.6050504@mozilla.com> <51F584FA.6020307@mozilla.com> Message-ID: On Sun, Jul 28, 2013 at 4:54 PM, Brian Anderson wrote: > On 07/28/2013 01:17 PM, G?bor Lehel wrote: >> >> On Sun, Jul 28, 2013 at 7:42 PM, Daniel Micay >> wrote: >>> >>> On Sun, Jul 28, 2013 at 12:50 PM, Patrick Walton >>> wrote: >>>> >>>> I'm as sympathetic as anybody to want to reduce the number of pointer >>>> types >>>> in the language, as it's folks' #1 complaint about Rust. But I think >>>> this >>>> one is probably a necessary evil. >>>> >>>> >>>> Patrick >>> >>> We can reduce the number of pointer types in the language by >>> describing the language with semantic terms rather than implementation >>> details of the compiler. The safe subset of Rust lacks pointers in the >>> same way that a language like Ruby lacks them. >>> >>> For example, `~[T]` is described as a unique vector, despite being a >>> pointer. It feels like we're going out of our way to make the language >>> complex when we use a term like "borrowed pointer" instead of just >>> calling it a reference like Java. >>> >>> The documentation would be so much simpler if it just referred to >>> references and unique/managed boxes. Rust only has two types that are >>> semantically pointers, `*` and `*mut`. > > > FWIW I prefer the terms box and reference. I don't really understand the > idea that only * is 'semantically a pointer' though. Unique boxes can be implemented without a pointer as long as the type is no larger than the slot needed to contain a pointer-size object. The pointer itself just isn't part of the type's contract, since there's no pointer arithmetic. Type-based alias analysis will prevent treating anything but raw pointers as plain old addresses you can mutate whenever you want or cast to any type. From steven at ashley.net.nz Sun Jul 28 16:06:38 2013 From: steven at ashley.net.nz (Steven Ashley) Date: Mon, 29 Jul 2013 11:06:38 +1200 Subject: [rust-dev] Redesigning fmt! In-Reply-To: <51F58F9D.70906@mozilla.com> References: <51F58F9D.70906@mozilla.com> Message-ID: On Sunday, July 28, 2013, Brian Anderson wrote: > > I'm not a fan of printf-style format specifiers in general, largely > because the specifiers have to be allocated in some way (fmt attribute) so > are not particularly extensible. I can't imagine how this fmt attribute can > be implemented in a general way using current compiler mechanisms, and am > in favor of looking to other languages for guidance on how formatting > should be done instead of leaning on crusty old C here. In the "bike shedding println() and friends" thread Greydon posted a summary of his thoughts in this area. In particular: - format strings with nestable {n} placeholders rather than non-nesting %-placeholders, and simple conditional forms borrowed from the work Java and ICU/CLDR have done in this field. I've had a brief look through these and really like the approach. > It does seem like &Trait has a role here. I'd like to see a firm idea of > what the runtime interface looks like. I imagine it can all be encapsulated > in a simple signature like `fn format(&mut io::Writer, &[(&Formattable, > FormatSpecifier)])`, where every chunk of the format string and the values > to insert into it are cast to a stack object and paired with some metadata > indicating how it should be formatted. Such an interface doesn't have any > room for type-specific format traits like `Signed` though. I was thinking along similar lines myself though in my case I had a type signature of fn format(&mut io::Writer, &string) where string is the format associated with the chunk. For example for the format string "the value of x is {0:####.##}" the string passed to format would be "####.##". Nestable format strings complicate implementation a little more. The rough idea is: {0:( if count == 0 then (You have no messages.) else (You have {count:#####} messages.) )} I have found format strings of this sort to be very useful in the past, in particular for a job that involved formatting driving instructions in 30+ languages - think "At the end of the street turn left then take the next right." In that case we used an in house XML based system. I think it was mostly equivalent. The formatter would need some way of getting the "count" member of 0 for the condition and then again for formatting in the nested expression. It would be pretty neat to evaluate all this at compile time. I think we would have to know the specific type of each chunk. i.e. the arguments cannot be simply of type &Trait. Perhaps a macro could be (somehow) attached to the type being formatted and the fmt! macro could look it up (somehow) to format the arguments. Tricky stuff. Thoughts? Cheers, Steven -------------- next part -------------- An HTML attachment was scrubbed... URL: From armin.ronacher at active-4.com Sun Jul 28 16:54:52 2013 From: armin.ronacher at active-4.com (Armin Ronacher) Date: Mon, 29 Jul 2013 01:54:52 +0200 Subject: [rust-dev] RFC: Removing *T In-Reply-To: <51F54AD7.20806@mozilla.com> References: <51F4DD04.5010805@active-4.com> <51F4E0A0.3070107@gmail.com> <51F4F9D9.2040700@active-4.com> <51F54AD7.20806@mozilla.com> Message-ID: <51F5AF4C.5020805@active-4.com> Hi, On 28/07/2013 18:46, Patrick Walton wrote: > It's not that complicated. Most of the hard work is in placement new. > > And it's not like we have a choice really: Servo is starting to grow > custom smart pointers all over the place (the DOM, probably the Flow > tree, all JS objects, ARC, RWARC...) Making them stay second-class > forever is kind of a non-starter at this point. Fair enough. I am however a bit concerned about this considering that the last proposal I saw was rewriting things to be closures and then passing those closures to methods. Currently that just does not work yet well because stack closures are not transparent. For instance a break or continue work break if it's moved into a closure (#3064). Pretty sure there are some other things as well that will not survive a silent move into a closure. Regards, Armin From ben.striegel at gmail.com Sun Jul 28 17:21:20 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Sun, 28 Jul 2013 20:21:20 -0400 Subject: [rust-dev] Implement Digest trait for MD4 and MD5 In-Reply-To: <51F583AD.6060503@mozilla.com> References: <51F583AD.6060503@mozilla.com> Message-ID: > Is it appropriate for all digests to live in extra::crypto? While I'd hope that anyone actually doing crypto would know better, it seems Wrong Wrong Wrong to put non-cryptographic hashes in such a namespace. -------------- next part -------------- An HTML attachment was scrubbed... URL: From me at kevincantu.org Sun Jul 28 17:27:24 2013 From: me at kevincantu.org (Kevin Cantu) Date: Sun, 28 Jul 2013 17:27:24 -0700 Subject: [rust-dev] Implement Digest trait for MD4 and MD5 In-Reply-To: References: <51F583AD.6060503@mozilla.com> Message-ID: AFAIK new algorithms using MD4 (and probably MD5) would also be simply wrong, too. Kevin -- Kevin Cantu On Sun, Jul 28, 2013 at 5:21 PM, Benjamin Striegel wrote: > > Is it appropriate for all digests to live in extra::crypto? > > While I'd hope that anyone actually doing crypto would know better, it > seems Wrong Wrong Wrong to put non-cryptographic hashes in such a namespace. > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alex at crichton.co Sun Jul 28 21:24:44 2013 From: alex at crichton.co (Alex Crichton) Date: Sun, 28 Jul 2013 21:24:44 -0700 Subject: [rust-dev] Redesigning fmt! In-Reply-To: <51F58E4E.2000809@mozilla.com> References: <51F58E4E.2000809@mozilla.com> Message-ID: Having thought a bit more concretely about this, using the suggestions here, and talking to Graydon on IRC I've come up with the following design for a string formatting library. I think that this addresses the comments in the responses to my original email, but if not please let me know! == Format Language == On of the major goals of the "formatting language" is to support internationalization as necessary. This means that must be nested format patterns, some form of a few functions that can be executed at runtime, and be able to test the equivalence of format strings at runtime. To this end, I drew from these links: http://docs.python.org/3/library/string.html#formatstrings http://www.icu-project.org/apiref/icu4j/com/ibm/icu/text/MessageFormat.html http://docs.oracle.com/javase/7/docs/api/java/text/ChoiceFormat.html?is-external=true http://www.icu-project.org/apiref/icu4j/com/ibm/icu/text/PluralFormat.html http://www.icu-project.org/apiref/icu4j/com/ibm/icu/text/SelectFormat.html https://github.com/SlexAxton/messageformat.js And settled on this grammar: format_string := [ format ] * format := '{' [ argument [ ':' format_spec ] ',' ] function_spec ] '}' argument := '' | integer format_spec := [[fill]align][sign]['#'][width][.precision][type] fill := character align := '<' | '>' sign := '+' | '-' width := count precision := count | '*' type := identifier | '' count := parameter | integer parameter := integer '$' function_spec := plural | select plural := 'plural' ',' [ 'offset:' integer ] ( selector arm ) * selector := '=' integer | keyword keyword := 'zero' | 'one' | 'two' | 'few' | 'many' select := 'select' ',' ( identifier arm ) * arm := '{' format_string '}' Some examples would be: {} {1} {1:d} {:date} {: <} {:+#} {plural, other {...}} {1, plural, offset:1 =1{...} one{...} many{...} other {...}} {select, s1{...} s2{...} other{...}} {select, selector{{2, plural, other{...}}} other{...}} An overview of this: * Any argument can be selected (0-indexed from the start) * Any argument can be formatted any way (or at least the formatter requests a particular format * There are two internationalization functions 'select' and 'plural'. I've also seen a 'choice' function and I haven't quite been able to grasp it, but there's enough foundation here that it should be easy to add. * Nested format strings are allowed * Multi-char format names are allowed. * I'm not conviced the format-specifiers are the best they could be, they're currently modified from python's version, and do differ slightly from what currently exists today. Implementation-wise, there will be a parser in a `fmt` module which parses these strings and yields ast-like items representing the structure of the format string. == Compile-time suport == All of the formats available for use will be defined at compile-time. Each format will be defined as implementors of a particular trait, and these traits will have one method each defining a format function. For example: #[fmt="b"] pub trait Bool { fn fmt(&Self, &mut Formatter); } #[fmt="c"] pub trait Char { fn fmt(&Self, &mut Formatter); } #[fmt="d"] pub trait Signed { fn fmt(&Self, &mut Formatter); } #[fmt="u"] #[fmt="i"] pub trait Unsigned { fn fmt(&Self, &mut Formatter); } #[fmt="s"] pub trait String { fn fmt(&Self, &mut Formatter); } #[fmt="?"] pub trait Poly { fn fmt(&Self, &mut Formatter); } Here each format specifier is specified via a #[fmt] attribute. There is one static function called `fmt` which takes the type as a first parameter and then a `Formatter` object as a second. The `Formatter` object contains the output stream and any relevant flags like width/precision/fill/alignment. It will be up to each implementation of each trait to implement these flags, but there will be a number of helper functions in a `fmt` package for dealing with these options. >From the compiler's point of view, there will be a new macro, let's call it ifmt!, which will have the following transformation: ifmt!("{:s}, {}!", "Hello", "World") { let l1 = "Hello"; let l2 = "World"; ::std::fmt::sprintf("{:s}, {}!", [c(String::fmt, &l1), c(Poly::fmt, &l2)]) } A few notable points: * If you're wondering what this `c` function is, look below * An attempt is made to make this as little code as possible. Each format location should purely pass all the arguments along to someone else. * The argument list is a list of tuples where the first element is a function which takes the second element (and a formatter) to format the result into a stream. The exact function selected depends on the format parameter specified in the string, such as: "s" == String::fmt, default == Poly::fmt * A bit of magic goes on under the hood with unsafe casts to make these all typecheck to the same thing (more details below) == Runtime support == The crux of the implementation will be around this function signature: type FormatFn = extern "Rust" fn(&T, &mut Formatter); type Argument = (FormatFn, &Void); unsafe fn fprintf(w: &mut io::Writer, fmt: &str, args: &[Argument]) { ... } Here, the stream to output to is taken, the format string, and the list of arguments. Each argument is an "opaque" pointer/function pair where the function knows how to format the value at the pointer. The validity of each FormatFn/pointer type is validated at compile time, so only valid calls to this function will be emitted. The function is then also tagged as `unsafe` so if it's manually called at runtime there's a knowledge that if you mix up the arguments then serious problems will happen. >From above, the compiler would emit calls to the `c` function as so: fn c(f: FormatFn, t: &T) -> Argument { ... } The actual implementation is just a wrapper around `transmute`. This gets us a lot of nice error messages and compile-time checks that guarantee the type of each argument is sane (regarding its format specifier). For example an invalid program would yield the following: ifmt!("{:s}", MyStruct{ foo: "bar" }) //~^ ERROR: No implementation of `String` trait found for `MyStruct` This comes about because the 's' format specifier is registered to the `String` trait (or rather `std::fmt::String`), and due to the signature of the `c` function it will attempt to look up an implementation of that trait for the `MyStruct` type (passed as the second argument of `c`). Algorithm-wise, this will create a parser for the fmt string, and iterate over each of the "tokens" performing the necessary action (streaming output to the specified stream). A few notes: * I believe that parsing must occur at runtime, because otherwise i18n wouldn't work because it could generate any arbitrary format string at runtime based on the current locale. * Currently traits don't work well enough such that `&mut io::Writer` is a thing that works, so the current interface would only export an `sprintf` function which emits to a `&mut ~str` object (essentially a stream). == Internationalization == I also wanted to touch on how this covers internationalization. The main point of this is located within the query language, but the runtime must also support some constructs. The format string and arguments are validated at compile-time, but any format string could be run at runtime. For this reason an equivalence function will be needed that takes the original format string and a translated format string and ensures at runtime that the two are equivalent in terms of types, position, and number of arguments. On a related note, any argument as a parameter to the `plural` function will be required to be of the `&uint` type, and any argument to the `select` function will be required to thbe of the `& &str` type. Additionally, the function pointer of the argument pair these are in will be some dummy function that fails if called (because they should never be called). I haven't given too much thought to these constructs, but that was kinda the first thing I came up with. == Summing up == Currently I have implemented the format language parsing, and the runtime support necessary for this (without dealing with formatting flags). I haven't started the compiler work yet, and there's no reason that any of this couldn't completely change in the meantime. I would love comments/suggestions on this system. I think that this takes into account almost all of the feedback which I've received about how formatting strings should work, but extra sets of eyes are always useful! From graydon at mozilla.com Sun Jul 28 22:36:03 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Sun, 28 Jul 2013 22:36:03 -0700 Subject: [rust-dev] Redesigning fmt! In-Reply-To: References: <51F58F9D.70906@mozilla.com> Message-ID: <51F5FF43.101@mozilla.com> On 13-07-28 04:06 PM, Steven Ashley wrote: > {0:( > if count == 0 then (You have no messages.) > else (You have {count:#####} messages.) > )} That's exactly the case that the nested pluralization forms are for. Read the docs on MessageFormat. They've been working on this problem space for quite a long time and have reasonable mechanisms mapped out for the most common value-driven grammar alteration cases (plural, gender, selects). -Graydon From graydon at mozilla.com Sun Jul 28 23:32:12 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Sun, 28 Jul 2013 23:32:12 -0700 Subject: [rust-dev] Redesigning fmt! In-Reply-To: References: <51F58E4E.2000809@mozilla.com> Message-ID: <51F60C6C.5020106@mozilla.com> On 13-07-28 09:24 PM, Alex Crichton wrote: > I would love comments/suggestions on this system. I think that this takes into > account almost all of the feedback which I've received about how formatting > strings should work, but extra sets of eyes are always useful! In general I'm really happy you're taking this on. Hopefully you've been able to recycle bits of code from https://github.com/Aatch/rust-fmt or at least chat with Aatch, Huon and Kimundi about it? Some comments: - There are six CLDR pural keywords, not five: there's also 'other'. You use it in your examples but not in the grammar given. - I don't see how the example {:date} is generated from the grammar. Though I do think custom (especially culture-specific) formatter functions do need some support. Money and dates are the big two. - I agree with others that the formatting of decimal has wiggle room in the design; python's choice is ... so-so? C# has a version[1] that includes culture-specific hooks for number formatting and fairly extensive control over individual axes of formatting. You should probably also spend a little while digging through the way C++ locales and facets work[2]. Possibly try to get Nathan Myers into the conversation (he's on this mailing list) as I believe he designed that system. The second link in [2] is to his site. - I also agree with Brian that _generalizing_ format modifiers somewhat (so that formatting options can pass from format-string through to formatter) might be worth thinking about some more. It's related to the previous point, in the modifiers-for-numbers case. Can we pass modifiers for strings? (width, case, justification?) how about iterators (common lisp supports formatting sequences, the specifier takes a separator as a formatting option[3]) or tabulation (also in CL[4])? All this is a bit overkill for most formatting; but I wonder if we'll find ourselves in a position in a few years of thinking "formatting would be great if only there was a switch for $THING" and the mechanism for adding switches was set a bit too much in stone. - Your implementation is extremely clever and appears to be low overhead, which is _great_. I am a little saddened, though, that it rests not just on something that can dynamically fail but that can (presumably) fail _badly_ (memory unsafe?) if called wrong. I wonder if there's any sort of trickery to make the innermost fprintf function memory-safe, just dynamically fail on bad args. I can think of a number of ways of approaching that using &Trait, enums of the different format strings, visitor methods, etc. Not sure which would be best. I don't wish to diminish the cleverness of your approach; making the innermost function memory safe would just be icing on the cake. But these are mostly minor nits, nothing to talk you out of it. I think you're on the right track. Thanks again for digging into it. -Graydon [1] http://msdn.microsoft.com/en-us/library/system.globalization.numberformatinfo.aspx [2] http://stdcxx.apache.org/doc/stdlibug/VII.html http://www.cantrip.org/lib-locales.html [3] http://www.lispworks.com/documentation/HyperSpec/Body/22_cgd.htm [4] http://www.lispworks.com/documentation/HyperSpec/Body/22_cfa.htm From graydon at mozilla.com Sun Jul 28 23:53:06 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Sun, 28 Jul 2013 23:53:06 -0700 Subject: [rust-dev] Implement Digest trait for MD4 and MD5 In-Reply-To: References: <51F583AD.6060503@mozilla.com> Message-ID: <51F61152.5030701@mozilla.com> On 13-07-28 05:27 PM, Kevin Cantu wrote: > AFAIK new algorithms using MD4 (and probably MD5) would also be simply > wrong, too. They were designed as CHFs; they are now weak-or-broken but code that's interoperating with old cryptosystems do need them from time to time. CRCs and Checksums aren't CHFs and shouldn't be put anywhere near them. I'd be somewhat cautious even calling them hash functions, but I guess it's a short enough name. I suggest (humbly and willing to listen to counterarguments) that we have a trait std::crypto::Digest and a trait std::hash::Hash, with default implementations of each that we consider state of the art, in std; and then a bucket of "extra" named algorithms that satisfy the same trait in extra::crypto and extra::hash. In general I _think_ I'd like important / widely-used traits to be specified in std, even if "most" implementations don't live in std. There's value to getting the interface widely standardized. The same issue comes up with a lot of other interfaces: the container types (hashtables and balanced trees), random number generators, serialization schemes, compressors and such are all like this: there are 95 different known, named variants someone _might_ want to use for some particular interoperability or taste reason, but I suggest that the interface and a promise of at least 1 "reasonably good" implementation -- hidden behind &Trait or a non-specified typedef or something -- ought to be standardized. -Graydon From me at kevincantu.org Mon Jul 29 00:31:20 2013 From: me at kevincantu.org (Kevin Cantu) Date: Mon, 29 Jul 2013 00:31:20 -0700 Subject: [rust-dev] Implement Digest trait for MD4 and MD5 In-Reply-To: <51F61152.5030701@mozilla.com> References: <51F583AD.6060503@mozilla.com> <51F61152.5030701@mozilla.com> Message-ID: I almost think we shouldn't try. Any code running with one default implementation will have to change when we update the default to something more secure, or else we'll have to version everything, and at that point rather than worry about what it was, we'll wish we'd just named Rust 0.X's std::crypto::Digest as std::crypto::SHA2::Digest256 or whatever name everyone else knows it by. But I like the idea. Is there a way to provide even a little bit of that value of perpetually sane defaults? Kevin -- Kevin Cantu On Sun, Jul 28, 2013 at 11:53 PM, Graydon Hoare wrote: > On 13-07-28 05:27 PM, Kevin Cantu wrote: > >> AFAIK new algorithms using MD4 (and probably MD5) would also be simply >> wrong, too. >> > > They were designed as CHFs; they are now weak-or-broken but code that's > interoperating with old cryptosystems do need them from time to time. > > CRCs and Checksums aren't CHFs and shouldn't be put anywhere near them. > I'd be somewhat cautious even calling them hash functions, but I guess it's > a short enough name. > > I suggest (humbly and willing to listen to counterarguments) that we have > a trait std::crypto::Digest and a trait std::hash::Hash, with default > implementations of each that we consider state of the art, in std; and then > a bucket of "extra" named algorithms that satisfy the same trait in > extra::crypto and extra::hash. > > In general I _think_ I'd like important / widely-used traits to be > specified in std, even if "most" implementations don't live in std. There's > value to getting the interface widely standardized. > > The same issue comes up with a lot of other interfaces: the container > types (hashtables and balanced trees), random number generators, > serialization schemes, compressors and such are all like this: there are 95 > different known, named variants someone _might_ want to use for some > particular interoperability or taste reason, but I suggest that the > interface and a promise of at least 1 "reasonably good" implementation -- > hidden behind &Trait or a non-specified typedef or something -- ought to be > standardized. > > -Graydon > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From masklinn at masklinn.net Mon Jul 29 01:26:10 2013 From: masklinn at masklinn.net (Masklinn) Date: Mon, 29 Jul 2013 10:26:10 +0200 Subject: [rust-dev] Redesigning fmt! In-Reply-To: References: <51F58E4E.2000809@mozilla.com> Message-ID: <77930DB6-5F16-49A9-AA4B-F2BAA91B0F74@masklinn.net> I don't have much to say, but On 2013-07-29, at 06:24 , Alex Crichton wrote: > > * Any argument can be selected (0-indexed from the start) keyword/named selection is *really* great for longer/more busy patterns, it makes format string much more readable both in-code and for translators (who usually lack part of the context, even with comments, especially if they are non-technical). I think this is one of the great strengths of Python's string formatting (both C-style and C#-style) or Ruby's string interpolation, and if the formatting language is going to be reworked away from C-style formats it would be nice to include it if possible. I don't think it can be integrated directly into the current grammar though, as there'd be ambiguity with the function spec. From alcosholik at gmail.com Mon Jul 29 02:05:33 2013 From: alcosholik at gmail.com (Alexei Sholik) Date: Mon, 29 Jul 2013 12:05:33 +0300 Subject: [rust-dev] Implement Digest trait for MD4 and MD5 In-Reply-To: <51F61152.5030701@mozilla.com> References: <51F583AD.6060503@mozilla.com> <51F61152.5030701@mozilla.com> Message-ID: I mentioned checksum algorithms because I have a motivation to work on them and thought Rust could have the most popular ones in stdlib. I wasn't suggesting to put them into the same category as digests. For the record, I'm looking at Go's crypto[1] and hash[2] packages as an indicator of what could find its way into the standard lib. [1]: http://golang.org/pkg/crypto/ (scroll to the bottom to see subpackages) [2]: http://golang.org/pkg/hash/ On Mon, Jul 29, 2013 at 9:53 AM, Graydon Hoare wrote: > On 13-07-28 05:27 PM, Kevin Cantu wrote: > >> AFAIK new algorithms using MD4 (and probably MD5) would also be simply >> wrong, too. >> > > They were designed as CHFs; they are now weak-or-broken but code that's > interoperating with old cryptosystems do need them from time to time. > > CRCs and Checksums aren't CHFs and shouldn't be put anywhere near them. > I'd be somewhat cautious even calling them hash functions, but I guess it's > a short enough name. > > I suggest (humbly and willing to listen to counterarguments) that we have > a trait std::crypto::Digest and a trait std::hash::Hash, with default > implementations of each that we consider state of the art, in std; and then > a bucket of "extra" named algorithms that satisfy the same trait in > extra::crypto and extra::hash. > > In general I _think_ I'd like important / widely-used traits to be > specified in std, even if "most" implementations don't live in std. There's > value to getting the interface widely standardized. > > The same issue comes up with a lot of other interfaces: the container > types (hashtables and balanced trees), random number generators, > serialization schemes, compressors and such are all like this: there are 95 > different known, named variants someone _might_ want to use for some > particular interoperability or taste reason, but I suggest that the > interface and a promise of at least 1 "reasonably good" implementation -- > hidden behind &Trait or a non-specified typedef or something -- ought to be > standardized. > > -Graydon > > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -- Best regards Alexei Sholik -------------- next part -------------- An HTML attachment was scrubbed... URL: From dbau.pp at gmail.com Mon Jul 29 02:04:18 2013 From: dbau.pp at gmail.com (Huon Wilson) Date: Mon, 29 Jul 2013 19:04:18 +1000 Subject: [rust-dev] Redesigning fmt! In-Reply-To: <77930DB6-5F16-49A9-AA4B-F2BAA91B0F74@masklinn.net> References: <51F58E4E.2000809@mozilla.com> <77930DB6-5F16-49A9-AA4B-F2BAA91B0F74@masklinn.net> Message-ID: <51F63012.4020809@gmail.com> On 29/07/13 18:26, Masklinn wrote: > I don't have much to say, but > > On 2013-07-29, at 06:24 , Alex Crichton wrote: >> * Any argument can be selected (0-indexed from the start) > keyword/named selection is *really* great for longer/more busy patterns, > it makes format string much more readable both in-code and for > translators (who usually lack part of the context, even with comments, > especially if they are non-technical). I think this is one of the great > strengths of Python's string formatting (both C-style and C#-style) or > Ruby's string interpolation, and if the formatting language is going > to be reworked away from C-style formats it would be nice to include > it if possible. > > I don't think it can be integrated directly into the current grammar > though, as there'd be ambiguity with the function spec. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev fmt! is a syntax extension (which receive their arguments as tokens, not at all parsed), so it can actually "define" its own syntax for named arguments, without any modifications to Rust's grammar (as long as it tokenises), so some or all of fmt!("{foo}", foo) fmt!("{foo}", foo=bar) fmt!("{foo} {bar}", let (foo, bar) = baz) could be made to work; although, `foo = bar` is a valid expression (with return type ()), so it might be suboptimal to change its behaviour here. The `let` form allows for pattern matching in fmt! args, and still allows the fmt! implementation to have a simple parser. From armin.ronacher at active-4.com Mon Jul 29 02:08:49 2013 From: armin.ronacher at active-4.com (Armin Ronacher) Date: Mon, 29 Jul 2013 11:08:49 +0200 Subject: [rust-dev] Redesigning fmt! In-Reply-To: References: <51F58E4E.2000809@mozilla.com> Message-ID: <51F63121.4060603@active-4.com> Hi, On 29/07/2013 06:24, Alex Crichton wrote: > Having thought a bit more concretely about this, using the suggestions here, > and talking to Graydon on IRC I've come up with the following design for a > string formatting library. I think that this addresses the comments in the > responses to my original email, but if not please let me know! I love the proposal. I have been hoping for extensible and rearrangable formatting for a really long time. Just a few notes on i18n support. > A few notes: > * I believe that parsing must occur at runtime, because otherwise i18n > wouldn't work because it could generate any arbitrary format string at > runtime based on the current locale. Can we have both? Parse at compile time if the string is constant but parse at compile time if the string comes from something like a gettext-ish function that loads the string from a message catalog. > I also wanted to touch on how this covers internationalization. The main point > of this is located within the query language, but the runtime must also support > some constructs. The format string and arguments are validated at compile-time, > but any format string could be run at runtime. For this reason an equivalence > function will be needed that takes the original format string and a translated > format string and ensures at runtime that the two are equivalent in terms of > types, position, and number of arguments. Having done some i18n work through Babel i can tell you that people vastly prefer keyword based syntax over positional one. Granted, part of it is because in Babel (which uses old Python printf style formatting) you can rearrange them. A bit part of the reason however is because sometimes translations lag behind and a new argument was added later. If that new argument does not show up in the new format string it's silently ignored. The whole translation workflow should not be forgotten. Very few projects can afford to not have translations lagging behind. I believe formatting for i18n should be as lenient as possible, something that does not hold true for normal format strings. Maybe some compromise can be added to have strictness levels on the formatting? Regards, Armin From masklinn at masklinn.net Mon Jul 29 02:39:10 2013 From: masklinn at masklinn.net (Masklinn) Date: Mon, 29 Jul 2013 11:39:10 +0200 Subject: [rust-dev] Redesigning fmt! In-Reply-To: <51F63012.4020809@gmail.com> References: <51F58E4E.2000809@mozilla.com> <77930DB6-5F16-49A9-AA4B-F2BAA91B0F74@masklinn.net> <51F63012.4020809@gmail.com> Message-ID: <320BA949-BDE3-4057-96B0-7565EBEF52A3@masklinn.net> On 2013-07-29, at 11:04 , Huon Wilson wrote: > On 29/07/13 18:26, Masklinn wrote: >> I don't have much to say, but >> >> On 2013-07-29, at 06:24 , Alex Crichton wrote: >>> * Any argument can be selected (0-indexed from the start) >> keyword/named selection is *really* great for longer/more busy patterns, >> it makes format string much more readable both in-code and for >> translators (who usually lack part of the context, even with comments, >> especially if they are non-technical). I think this is one of the great >> strengths of Python's string formatting (both C-style and C#-style) or >> Ruby's string interpolation, and if the formatting language is going >> to be reworked away from C-style formats it would be nice to include >> it if possible. >> >> I don't think it can be integrated directly into the current grammar >> though, as there'd be ambiguity with the function spec. >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev > > fmt! is a syntax extension (which receive their arguments as tokens, not at all parsed), so it can actually "define" its own syntax for named arguments, without any modifications to Rust's grammar (as long as it tokenises) I was talking about the fmt! syntax described by Alex here, not Rust's grammar. From steven at ashley.net.nz Mon Jul 29 02:41:20 2013 From: steven at ashley.net.nz (Steven Ashley) Date: Mon, 29 Jul 2013 21:41:20 +1200 Subject: [rust-dev] Redesigning fmt! In-Reply-To: <51F5FF43.101@mozilla.com> References: <51F58F9D.70906@mozilla.com> <51F5FF43.101@mozilla.com> Message-ID: On 29/07/2013 6:36 AM, "Graydon Hoare" wrote: > > On 13-07-28 04:06 PM, Steven Ashley wrote: > >> {0:( >> if count == 0 then (You have no messages.) >> else (You have {count:#####} messages.) >> )} > > > That's exactly the case that the nested pluralization forms are for. Read the docs on MessageFormat. They've been working on this problem space for quite a long time and have reasonable mechanisms mapped out for the most common value-driven grammar alteration cases (plural, gender, selects). > > -Graydon Apologies. This was exactly the use case I was trying to convey. Unfortunately I was writing the email from my phone while on the run and couldn't recall the specifics of the syntax. I should have indicated it was pseudo code of sorts. In any case I really like the direction this is heading and I'm really looking forward to playing with it. Thanks again Alex for kicking this off. Cheers -------------- next part -------------- An HTML attachment was scrubbed... URL: From illissius at gmail.com Mon Jul 29 07:47:18 2013 From: illissius at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Mon, 29 Jul 2013 16:47:18 +0200 Subject: [rust-dev] RFC: Removing *T In-Reply-To: References: <51F54BBD.6050504@mozilla.com> <51F584FA.6020307@mozilla.com> Message-ID: On Sun, Jul 28, 2013 at 11:54 PM, Daniel Micay wrote: > On Sun, Jul 28, 2013 at 4:54 PM, Brian Anderson wrote: >> FWIW I prefer the terms box and reference. I don't really understand the >> idea that only * is 'semantically a pointer' though. > > Unique boxes can be implemented without a pointer as long as the type > is no larger than the slot needed to contain a pointer-size object. > The pointer itself just isn't part of the type's contract, since > there's no pointer arithmetic. Hmm. Given immutability, in the absence of Cell or destructors, ditto for &T and @T? Do we even specify that it will be pointer-sized? Kind of amusing: you could have &&&&@@~~@@~~int with the same representation as int, and "dereferencing" at each level just transmute(self). It may look like this is only of theoretical interest, because no one in their right mind would pass int by pointer, but it would be a useful optimization for generic code - for the same reason. -- Your ship was destroyed in a monadic eruption. From graydon at mozilla.com Mon Jul 29 08:56:19 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 29 Jul 2013 08:56:19 -0700 Subject: [rust-dev] Redesigning fmt! In-Reply-To: References: <51F58F9D.70906@mozilla.com> <51F5FF43.101@mozilla.com> Message-ID: <51F690A3.9090504@mozilla.com> On 13-07-29 02:41 AM, Steven Ashley wrote: > Apologies. This was exactly the use case I was trying to convey. > Unfortunately I was writing the email from my phone while on the run and > couldn't recall the specifics of the syntax. I should have indicated it > was pseudo code of sorts. Oh, no worries! Just re-reading what I wrote, it sounds a bit snippish. Didn't mean to sound that way at all. I just wanted to point out that it's been covered (and I guess try to head off a bikeshed on this subgrammar; or for that matter the common refrain that this is a bottomless problem to which no reasonable solution can be found). > In any case I really like the direction this is heading and I'm really > looking forward to playing with it. Thanks again Alex for kicking this off. Likewise. Fmt (like log) is quite old and in need of some love. -Graydon From corey at octayn.net Mon Jul 29 09:59:44 2013 From: corey at octayn.net (Corey Richardson) Date: Mon, 29 Jul 2013 12:59:44 -0400 Subject: [rust-dev] Last Week in Rust Message-ID: Hello and welcome to the eighth issue of *This Week in Rust*. Due to me being busy and forgetful over the weekend, this is a special issue, *Last Week in Rust*. # What's cooking on `master`? Issue churn continues to be negative, -15 this week. A total of 63 PRs were merged. ## Breaking Changes There were impressively few breaking changes last week. - **You now need to pass `--cfg debug` to `rustc` to emit debug logging.** - [**`mod.rs` is now "blessed".**](https://github.com/mozilla/rust/pull/7926). When loading `mod foo;`, rustc will now look for `foo.rs`, then `foo/mod.rs`, and will generate an error when both are present. - [A bunch of `str` functions](https://github.com/mozilla/rust/pull/7996) were renamed or shuffled around to be more consistent. - [`SmallIntSet` was removed](https://github.com/mozilla/rust/pull/7934) in favor for the more efficient, equivalent `BitvSet`. - [`Bitv` and `Bitvset` have switched to external iterators](https://github.com/mozilla/rust/pull/7703). - [`extra::net` and a bunch of other obsolete features](https://github.com/mozilla/rust/pull/7883) have been removed. ## Notable library additions, bugfixes, and cleanup - Various [TCP/UDP additions](https://github.com/mozilla/rust/pull/8040) have been made in the new rt. - Some more [atomic operations](https://github.com/mozilla/rust/pull/8039) have been added. - A [`chain_mut_ref` method](https://github.com/mozilla/rust/pull/7931) was added to `Option`. - [Random access iterators](https://github.com/mozilla/rust/pull/7982) have been implemented. - Some missing [memory orderings on atomic types](https://github.com/mozilla/rust/pull/7993) have been added. - [workcache has seen a bunch of attention](https://github.com/mozilla/rust/pull/7885). - [DList has seen some more cleanup too](https://github.com/mozilla/rust/pull/7944). - [Timers have been added to the new rt](https://github.com/mozilla/rust/pull/7916). - [Vectors now implement `slice_from` and `slice_to`](https://github.com/mozilla/rust/pull/7943). ## Notable compiler additions, bugfixes, and cleanup - [debuginfo for destructured locals and function args](https://github.com/mozilla/rust/pull/8045) is now implemented. - [Raw representations are now consolidated](https://github.com/mozilla/rust/pull/7986). - [Impossible branches on constants](https://github.com/mozilla/rust/pull/8041) are now omitted. - [It is now possible to link against crates with `#[no_std]`](https://github.com/mozilla/rust/pull/7924). - [There is now a warning when matching against NaN](https://github.com/mozilla/rust/pull/8029), since it is impossible to match against NaN (NaN != NaN). - A lot of [default method and trait inheritance bugs](https://github.com/mozilla/rust/pull/8015) have been fixed. - [`uint` enum discriminants are now allowed](https://github.com/mozilla/rust/pull/8000). - The [section placement of static and fn items is now configurable](https://github.com/mozilla/rust/pull/7958). - Some [trans naming modernization has occured](https://github.com/mozilla/rust/pull/7848). - Some unnecessary branches and blocks [have been removed](https://github.com/mozilla/rust/pull/7941), resulting in a 10% speedup of unoptimized rustc. ## Documentation, tools, and other stuff - [Some benchmarks](https://github.com/mozilla/rust/pull/7912), and [some more benchmarks](https://github.com/mozilla/rust/pull/7980). - Crnobog has [fixed](https://github.com/mozilla/rust/pull/8001) [some](https://github.com/mozilla/rust/pull/7979) Windows testsuite issues. - [`Makefile` dependencies](https://github.com/mozilla/rust/pull/7820) have been fixed. `rustc` will never be invoked without its dependencies being built. - [`rust-mode` has been rewritten](https://github.com/mozilla/rust/pull/8031). - [There are some build system changes surrounding the `--cfg debug` changes](https://github.com/mozilla/rust/pull/8020). # Meetings The [Tuesday meeting](https://github.com/mozilla/rust/wiki/Meeting-weekly-2013-07-23) was quite productive. A quick summary: - Graydon wants to investigate using the Memory Pool System as the Rust GC, rather than a bespoke one. The [MPS](http://www.ravenbrook.com/project/mps/) is a very mature and robust memory management library. - The buildbots now collect and report some metrics as JSON. Take a poke in `http://static.rust-lang.org/build-metrics////.json` if you're interested. - pcwalton proposes allowing `Self` in impls, like in trait definitions. - There was some discussion of destructors taking `self` by value. - There was a proposal to remove `*mut`, but it can be useful. There was no consensus. - There was also some discussion on closures and mutable captures. I don't really have enough context to understand the conversation, something to do with "thunks". - Removing `&const` was discussed as well. The "plan is that we add a lint flag but document it as a reserved word", as it doesn't really seem to be useful. # Discussion + Blog posts - [Iterator Blocks for Rust](http://michaelwoerister.github.io/2013/07/26/Iterator-Blocks.html) - [RFC: Removing `*T`](http://www.reddit.com/r/rust/comments/1j5vbn/rustdev_rfc_removing_t/) - [dherman's OSCON slides](https://speakerdeck.com/dherman/rust-low-level-programming-without-the-segfaults) - [Mozilla is hiring a Rust research engineer](https://careers.mozilla.org/en-US/position/oKiEXfwn) - [An alpha release of the MongoDB Driver](http://blog.mongodb.org/post/56426792420/introducing-the-mongodb-driver-for-the-rust-programming) - [A fairly useless benchmark of random number generation](https://togototo.wordpress.com/2013/07/23/benchmarking-level-generation-go-rust-haskell-and-d/) # Projects - [color-rs: A library that provides types and conversions for working with various color formats.](https://github.com/bjz/color-rs) - [grease-bench: a runtimeless benchmarker](https://github.com/Aatch/grease-bench) - [rustfind, a "jump to definition" tool](https://github.com/dobkeratops/rustfind) - [RustyXML, a pure-Rust XML parser](https://github.com/Florob/RustyXML) From thiezz at gmail.com Mon Jul 29 10:21:49 2013 From: thiezz at gmail.com (Thiez) Date: Mon, 29 Jul 2013 19:21:49 +0200 Subject: [rust-dev] RFC: Removing *T In-Reply-To: References: <51F54BBD.6050504@mozilla.com> <51F584FA.6020307@mozilla.com> Message-ID: This would make for some interesting/confusing calling conventions. It would also mean &T and &mut T would no longer share a representation; &int would simply be int, but &mut int would still have to be a pointer. Borrowing &mut T to &T would be a dereference if T is pointer size or smaller? The only reliable way of taking an address would be taking &mut because & would fail for some types. Transmuting *something to &something or back would fail for some types, unless we make transmute smarter. I think for our sanity it would be best to let LLVM perform this kind of magic when it figures out we won't notice the difference. On Mon, Jul 29, 2013 at 4:47 PM, G?bor Lehel wrote: > On Sun, Jul 28, 2013 at 11:54 PM, Daniel Micay > wrote: > > On Sun, Jul 28, 2013 at 4:54 PM, Brian Anderson > wrote: > >> FWIW I prefer the terms box and reference. I don't really understand the > >> idea that only * is 'semantically a pointer' though. > > > > Unique boxes can be implemented without a pointer as long as the type > > is no larger than the slot needed to contain a pointer-size object. > > The pointer itself just isn't part of the type's contract, since > > there's no pointer arithmetic. > > Hmm. Given immutability, in the absence of Cell or destructors, ditto > for &T and @T? Do we even specify that it will be pointer-sized? > > Kind of amusing: you could have &&&&@@~~@@~~int with the same > representation as int, and "dereferencing" at each level just > transmute(self). > > It may look like this is only of theoretical interest, because no one > in their right mind would pass int by pointer, but it would be a > useful optimization for generic code - for the same reason. > > -- > Your ship was destroyed in a monadic eruption. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From thadguidry at gmail.com Mon Jul 29 10:41:23 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Mon, 29 Jul 2013 12:41:23 -0500 Subject: [rust-dev] MPS investigation for Rust GC Message-ID: REGARDING: - Graydon wants to investigate using the Memory Pool System as the Rust GC, rather than a bespoke one. The [MPS](http://www.ravenbrook.com/project/mps/) is a very mature and robust memory management library. Reading through and seeing one of the MPS creators initial design goals : "The MPS was not designed for C++, but as a memory manager for dynamic language run-time systems. In fact, it was specifically designed not to require C++." ...instantly gained my respect for this system and its potential. -- -Thad Thad on Freebase.com Thad on LinkedIn -------------- next part -------------- An HTML attachment was scrubbed... URL: From fredrik at haard.se Mon Jul 29 10:58:04 2013 From: fredrik at haard.se (=?UTF-8?B?RnJlZHJpayBIw6XDpXJk?=) Date: Mon, 29 Jul 2013 19:58:04 +0200 Subject: [rust-dev] Text encoding Message-ID: I wrote an implementation of text encoding/decoding for ISO*<->Unicode in Rust, available here: https://github.com/haard/rust-codecs I use approximately the same technique as the cpython implementation, and it works by parsing unicode.org specifications and generating Rust source; a charmap for each encoding and a codecs.rs which can be used to encode/decode text. The implementation depends on std::unicode being public, which it is not right now. Although it is in need of cleanup, more than the single naive testcase, and adding stream handling etc to the API, since I got a working version (aka the fun part), I thought it best to ask if an implementation along those lines could be considered for inclusion? If so I'll dedicate some time to clean it up, otherwise I'll find something else to work on instead. Regards, fredrik From someone at mearie.org Mon Jul 29 11:17:28 2013 From: someone at mearie.org (Kang Seonghoon) Date: Tue, 30 Jul 2013 03:17:28 +0900 Subject: [rust-dev] Text encoding In-Reply-To: References: Message-ID: Wow, it *is* indeed a coincidence: I'm also working on the character encoding library. https://github.com/lifthrasiir/rust-encoding Although this one is much more sophiscated that it supports an API for error detection and recovery. I'm not sure the whole library merits the inclusion however, as CJK needs several hundreds of kilobytes of data which is certainly duplicated with the system library. I would prefer the character encoding interface (`src/types.rs`) included in `std` however. 2013/7/30 Fredrik H??rd : > I wrote an implementation of text encoding/decoding for ISO*<->Unicode > in Rust, available here: https://github.com/haard/rust-codecs > > I use approximately the same technique as the cpython implementation, > and it works by parsing unicode.org specifications and generating Rust > source; a charmap for each encoding and a codecs.rs which can be used > to encode/decode text. > > The implementation depends on std::unicode being public, which it is > not right now. > > Although it is in need of cleanup, more than the single naive > testcase, and adding stream handling etc to the API, since I got a > working version (aka the fun part), I thought it best to ask if an > implementation along those lines could be considered for inclusion? If > so I'll dedicate some time to clean it up, otherwise I'll find > something else to work on instead. > > Regards, > fredrik > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -- -- Kang Seonghoon | Software Engineer, iPlateia Inc. | http://mearie.org/ -- Opinions expressed in this email do not necessarily represent the views of my employer. -- From simon.sapin at exyr.org Mon Jul 29 11:18:06 2013 From: simon.sapin at exyr.org (Simon Sapin) Date: Mon, 29 Jul 2013 19:18:06 +0100 Subject: [rust-dev] Text encoding In-Reply-To: References: Message-ID: <51F6B1DE.3020304@exyr.org> Le 29/07/2013 18:58, Fredrik H??rd a ?crit : > I wrote an implementation of text encoding/decoding for ISO*<->Unicode > in Rust, available here:https://github.com/haard/rust-codecs > > I use approximately the same technique as the cpython implementation, > and it works by parsing unicode.org specifications and generating Rust > source; a charmap for each encoding and a codecs.rs which can be used > to encode/decode text. > > The implementation depends on std::unicode being public, which it is > not right now. > > Although it is in need of cleanup, more than the single naive > testcase, and adding stream handling etc to the API, since I got a > working version (aka the fun part), I thought it best to ask if an > implementation along those lines could be considered for inclusion? If > so I'll dedicate some time to clean it up, otherwise I'll find > something else to work on instead. Hi, This looks great, thanks a lot for sharing! Please choose a software license (preferably an open-source one ;)) and add a LICENSE file to the repository. Servo will eventually need an implementation (ideally in Rust) of http://encoding.spec.whatwg.org/ , which has a lot in common with what you?re doing. Cheers, -- Simon Sapin From danielmicay at gmail.com Mon Jul 29 11:43:13 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Mon, 29 Jul 2013 14:43:13 -0400 Subject: [rust-dev] RFC: Removing *T In-Reply-To: References: <51F54BBD.6050504@mozilla.com> <51F584FA.6020307@mozilla.com> Message-ID: On Mon, Jul 29, 2013 at 1:21 PM, Thiez wrote: > This would make for some interesting/confusing calling conventions. It would > also mean &T and &mut T would no longer share a representation; &int would > simply be int, but &mut int would still have to be a pointer. Borrowing &mut > T to &T would be a dereference if T is pointer size or smaller? The only > reliable way of taking an address would be taking &mut because & would fail > for some types. Transmuting *something to &something or back would fail for > some types, unless we make transmute smarter. > > I think for our sanity it would be best to let LLVM perform this kind of > magic when it figures out we won't notice the difference. It will only do this for internal functions and only at --opt-level=3. From j.boggiano at seld.be Mon Jul 29 12:00:59 2013 From: j.boggiano at seld.be (Jordi Boggiano) Date: Mon, 29 Jul 2013 21:00:59 +0200 Subject: [rust-dev] Preview of the new rustdoc_web frontend Message-ID: <51F6BBEB.8020600@seld.be> Heya, Crossposting from Reddit [1], just so more people see it and we can get feedback: It's a node project (sources [2]) feeding on the json output that cmr's rustdoc_ng [3] generates to build a static site. See http://seld.be/rustdoc/std/index.html for a preview of the std docs. TODOs: - follow new features in rustdoc_ng (impls are missing, closures incomplete, some ids are buggy still) - implement search - parameterization/customizability - design tweaks [1] http://www.reddit.com/r/rust/comments/1jalfe/rustdoc_web_preview_of_a_new_doc_frontend/ [2] https://github.com/Seldaek/rustdoc_web [3] https://github.com/cmr/rustdoc_ng Cheers -- Jordi Boggiano @seldaek - http://nelm.io/jordi From fredrik at haard.se Mon Jul 29 12:10:00 2013 From: fredrik at haard.se (=?UTF-8?B?RnJlZHJpayBIw6XDpXJk?=) Date: Mon, 29 Jul 2013 21:10:00 +0200 Subject: [rust-dev] Text encoding In-Reply-To: <51F6B1DE.3020304@exyr.org> References: <51F6B1DE.3020304@exyr.org> Message-ID: Added a MIT license. 2013/7/29 Simon Sapin : > Le 29/07/2013 18:58, Fredrik H??rd a ?crit : > >> I wrote an implementation of text encoding/decoding for ISO*<->Unicode >> in Rust, available here:https://github.com/haard/rust-codecs >> >> I use approximately the same technique as the cpython implementation, >> and it works by parsing unicode.org specifications and generating Rust >> source; a charmap for each encoding and a codecs.rs which can be used >> to encode/decode text. >> >> The implementation depends on std::unicode being public, which it is >> not right now. >> >> Although it is in need of cleanup, more than the single naive >> testcase, and adding stream handling etc to the API, since I got a >> working version (aka the fun part), I thought it best to ask if an >> implementation along those lines could be considered for inclusion? If >> so I'll dedicate some time to clean it up, otherwise I'll find >> something else to work on instead. > > > Hi, > > This looks great, thanks a lot for sharing! > > Please choose a software license (preferably an open-source one ;)) and add > a LICENSE file to the repository. > > Servo will eventually need an implementation (ideally in Rust) of > http://encoding.spec.whatwg.org/ , which has a lot in common with what > you?re doing. > > Cheers, > -- > Simon Sapin > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -- /f I reject your reality and substitute my own. http://courteous.ly/yp3Zgd From jeaye at arrownext.com Mon Jul 29 12:10:40 2013 From: jeaye at arrownext.com (Jeaye) Date: Mon, 29 Jul 2013 13:10:40 -0600 Subject: [rust-dev] =?utf-8?q?Preview_of_the_new_rustdoc=5Fweb_frontend?= In-Reply-To: <51F6BBEB.8020600@seld.be> References: <51F6BBEB.8020600@seld.be> Message-ID: <106a0263ab5f5362215fce88ddd23937@arrownext.com> On 2013-07-29 13:00, Jordi Boggiano wrote: > Heya, > > Crossposting from Reddit [1], just so more people see it and we can > get > feedback: > > It's a node project (sources [2]) feeding on the json output that > cmr's > rustdoc_ng [3] generates to build a static site. > > See http://seld.be/rustdoc/std/index.html for a preview of the std > docs. > Wow, this is looking pretty great! I'm definitely looking forward to the search functionality; it'll save me loads of time. Will it just search function/module names, or also descriptions? What about having the documentation link the the appropriate source files on Github (or embedding them within the page)? If it's tied into the Github API, could it also show open issues relating to certain modules, or perhaps TODOS/XXX within them? Cheers, Jeaye From thadguidry at gmail.com Mon Jul 29 12:11:46 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Mon, 29 Jul 2013 14:11:46 -0500 Subject: [rust-dev] Text encoding In-Reply-To: <51F6B1DE.3020304@exyr.org> References: <51F6B1DE.3020304@exyr.org> Message-ID: Incidentally, Simon, to get the Rust community to help a bit more with needed libraries, etc..that Servo will need... Where are the current "needs" of Servo listed at ? are they on the Roadmap ? https://github.com/mozilla/servo/wiki/Roadmap or somewhere else ? On Mon, Jul 29, 2013 at 1:18 PM, Simon Sapin wrote: > Le 29/07/2013 18:58, Fredrik H??rd a ?crit : > > I wrote an implementation of text encoding/decoding for ISO*<->Unicode >> in Rust, available here:https://github.com/haard/**rust-codecs >> >> I use approximately the same technique as the cpython implementation, >> and it works by parsing unicode.org specifications and generating Rust >> source; a charmap for each encoding and a codecs.rs which can be used >> to encode/decode text. >> >> The implementation depends on std::unicode being public, which it is >> not right now. >> >> Although it is in need of cleanup, more than the single naive >> testcase, and adding stream handling etc to the API, since I got a >> working version (aka the fun part), I thought it best to ask if an >> implementation along those lines could be considered for inclusion? If >> so I'll dedicate some time to clean it up, otherwise I'll find >> something else to work on instead. >> > > Hi, > > This looks great, thanks a lot for sharing! > > Please choose a software license (preferably an open-source one ;)) and > add a LICENSE file to the repository. > > Servo will eventually need an implementation (ideally in Rust) of > http://encoding.spec.whatwg.**org/ , > which has a lot in common with what you?re doing. > > Cheers, > -- > Simon Sapin > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -- -Thad Thad on Freebase.com Thad on LinkedIn -------------- next part -------------- An HTML attachment was scrubbed... URL: From j.boggiano at seld.be Mon Jul 29 12:17:41 2013 From: j.boggiano at seld.be (Jordi Boggiano) Date: Mon, 29 Jul 2013 21:17:41 +0200 Subject: [rust-dev] Preview of the new rustdoc_web frontend In-Reply-To: <106a0263ab5f5362215fce88ddd23937@arrownext.com> References: <51F6BBEB.8020600@seld.be> <106a0263ab5f5362215fce88ddd23937@arrownext.com> Message-ID: <51F6BFD5.7020001@seld.be> > Wow, this is looking pretty great! I'm definitely looking forward to the > search functionality; it'll save me loads of time. Will it just search > function/module names, or also descriptions? We'll need to see what's feasible since this needs to be a plain js solution, but I guess we can do at least names and short descriptions. I guess parsing through the entire descriptions will be rather slow and will yield tons of false positives. In any case this is not my specialty so if anyone has a clue or wants to help ping me on #rustdoc-wg > What about having the > documentation link the the appropriate source files on Github (or > embedding them within the page)? If it's tied into the Github API, could > it also show open issues relating to certain modules, or perhaps > TODOS/XXX within them? It isn't tied to the GH API no, though I suppose if we see #\d+ in comments we could infer that they are issue numbers and link to that. Regarding the source, there is a "[src]" link (icon pending) on every page that brings you to the definition in the libstd source. Cheers -- Jordi Boggiano @seldaek - http://nelm.io/jordi From graydon at mozilla.com Mon Jul 29 12:29:57 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 29 Jul 2013 12:29:57 -0700 Subject: [rust-dev] Preview of the new rustdoc_web frontend In-Reply-To: <51F6BBEB.8020600@seld.be> References: <51F6BBEB.8020600@seld.be> Message-ID: <51F6C2B5.80503@mozilla.com> On 29/07/2013 12:00 PM, Jordi Boggiano wrote: > Heya, > > Crossposting from Reddit [1], just so more people see it and we can get > feedback: > > It's a node project (sources [2]) feeding on the json output that cmr's > rustdoc_ng [3] generates to build a static site. > > See http://seld.be/rustdoc/std/index.html for a preview of the std docs. Very nice. A few things I notice browsing-around: - Many type refs appear as raw IDs. I know you mentioned this. - Markdown isn't being formatted. `, *, _, ~~~ etc. show up in the docstrings. See: http://seld.be/rustdoc/std/rand/distributions/struct.StandardNormal.html - //! isn't being stripped / interpreted correctly. See http://seld.be/rustdoc/std/task/fn.get_task.html - Likewise leading * when digesting a block comment full of /* ... * */ is not being stripped properly. See http://seld.be/rustdoc/std/run/struct.Process.html - The use of color is interesting but I find it a little distracting since red is visited-link-color on my browser. In general the formatting seems a little too-large / too-bold also. These are just aesthetic bits though. Overall it seems like a big improvement though. Thanks so much for the work! I'm excited to see it having come so far. -Graydon From illissius at gmail.com Mon Jul 29 13:53:01 2013 From: illissius at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Mon, 29 Jul 2013 22:53:01 +0200 Subject: [rust-dev] RFC: Removing *T In-Reply-To: References: <51F54BBD.6050504@mozilla.com> <51F584FA.6020307@mozilla.com> Message-ID: On Mon, Jul 29, 2013 at 7:21 PM, Thiez wrote: > This would make for some interesting/confusing calling conventions. It would > also mean &T and &mut T would no longer share a representation; &int would > simply be int, but &mut int would still have to be a pointer. Yes. > Borrowing &mut T to &T would be a dereference if T is pointer size or smaller? Yes. I would expect borrowing and never dereferencing is uncommon, but of course possible. > The only > reliable way of taking an address would be taking &mut because & would fail > for some types. If by "taking an address" you mean transmute::<&T, *T>(&foo), then yes. But that's the same as the next point. You could have an addressof() which returns *T directly, instead of going through &T. > Transmuting *something to &something or back would fail for > some types, unless we make transmute smarter. Yes. That's what decoupling the semantics of a type from its representation means. Unsafe code would have to be more careful. Maybe there would be special functions to deal with some things. It would mean there would be no way /at all/, for some T, to go from an &T to a *T pointing at the object it was borrowed from. You could point it at the &T, but that might have a shorter lifetime. Not clear if this would be problematic anywhere. (It would have be something like calling a C function with a pointer, where the C function not only accesses the pointer but returns or stores it (but doesn't mutate through it), for a lifetime that's shorter than the original T's lifetime but longer than the &T's.) > > I think for our sanity it would be best to let LLVM perform this kind of > magic when it figures out we won't notice the difference. (Can it?) Anyway, this wasn't meant to be a proposal. Just exploring an idea. It's fun to think about. Obviously there would be both complications and benefits. But it definitely seems like a good idea to think through what representation details should be specified on top of the observable semantics, and what should be left up to the implementation. *Reserving the right* to do this kind of thing might be worthwhile (like we already do for enums). > On Mon, Jul 29, 2013 at 4:47 PM, G?bor Lehel wrote: >> >> On Sun, Jul 28, 2013 at 11:54 PM, Daniel Micay >> wrote: >> > On Sun, Jul 28, 2013 at 4:54 PM, Brian Anderson >> > wrote: >> >> FWIW I prefer the terms box and reference. I don't really understand >> >> the >> >> idea that only * is 'semantically a pointer' though. >> > >> > Unique boxes can be implemented without a pointer as long as the type >> > is no larger than the slot needed to contain a pointer-size object. >> > The pointer itself just isn't part of the type's contract, since >> > there's no pointer arithmetic. >> >> Hmm. Given immutability, in the absence of Cell or destructors, ditto >> for &T and @T? Do we even specify that it will be pointer-sized? >> >> Kind of amusing: you could have &&&&@@~~@@~~int with the same >> representation as int, and "dereferencing" at each level just >> transmute(self). >> >> It may look like this is only of theoretical interest, because no one >> in their right mind would pass int by pointer, but it would be a >> useful optimization for generic code - for the same reason. >> >> -- >> Your ship was destroyed in a monadic eruption. >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev > > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- Your ship was destroyed in a monadic eruption. From milkowski at gmail.com Mon Jul 29 16:29:39 2013 From: milkowski at gmail.com (=?ISO-8859-2?Q?Wojciech_Mi=B3kowski?=) Date: Tue, 30 Jul 2013 01:29:39 +0200 Subject: [rust-dev] Function definition syntax Message-ID: Hi, I'm observing rust development for some time, and I must say it slowly encourages me to use it. Especially the progress from Perl-like syntax to more sane and quiet form is enjoyable. That said I wonder why the function definition has form: fn name(var: type, ...) -> return_type {...} instead of more unified: fn name(var: type, ...): return_type {...} Is it constructed to mimic mathematical form f(x)->y or is there other reason i.e. syntax ambiguity? Cheers, W. From pwalton at mozilla.com Mon Jul 29 17:29:01 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Mon, 29 Jul 2013 17:29:01 -0700 Subject: [rust-dev] Function definition syntax In-Reply-To: References: Message-ID: <51F708CD.8030801@mozilla.com> On 7/29/13 4:29 PM, Wojciech Mi?kowski wrote: > Hi, > > I'm observing rust development for some time, and I must say it slowly > encourages me to use it. Especially the progress from Perl-like syntax > to more sane and quiet form is enjoyable. > That said I wonder why the function definition has form: > fn name(var: type, ...) -> return_type {...} > instead of more unified: > fn name(var: type, ...): return_type {...} > > Is it constructed to mimic mathematical form f(x)->y or is there other > reason i.e. syntax ambiguity? Personal preference of Graydon, I believe. This is one of the few decisions that has survived from Rust 0.1 :) I slightly prefer `:` to `->` but never enough to bring it up. Patrick From coder543 at gmail.com Mon Jul 29 17:32:41 2013 From: coder543 at gmail.com (Josh Leverette) Date: Mon, 29 Jul 2013 19:32:41 -0500 Subject: [rust-dev] Function definition syntax In-Reply-To: <51F708CD.8030801@mozilla.com> References: <51F708CD.8030801@mozilla.com> Message-ID: That modification could be subtle, yet powerful. It would make the language more consistent, at the very least. Sincerely, Josh On Jul 29, 2013 7:29 PM, "Patrick Walton" wrote: > On 7/29/13 4:29 PM, Wojciech Mi?kowski wrote: > >> Hi, >> >> I'm observing rust development for some time, and I must say it slowly >> encourages me to use it. Especially the progress from Perl-like syntax >> to more sane and quiet form is enjoyable. >> That said I wonder why the function definition has form: >> fn name(var: type, ...) -> return_type {...} >> instead of more unified: >> fn name(var: type, ...): return_type {...} >> >> Is it constructed to mimic mathematical form f(x)->y or is there other >> reason i.e. syntax ambiguity? >> > > Personal preference of Graydon, I believe. This is one of the few > decisions that has survived from Rust 0.1 :) > > I slightly prefer `:` to `->` but never enough to bring it up. > > Patrick > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From wmilkowski at interia.pl Mon Jul 29 18:02:52 2013 From: wmilkowski at interia.pl (=?ISO-8859-2?Q?Wojciech_Mi=B3kowski?=) Date: Tue, 30 Jul 2013 03:02:52 +0200 Subject: [rust-dev] Function definition syntax In-Reply-To: References: <51F708CD.8030801@mozilla.com> Message-ID: Patrick Walton wrote: > I slightly prefer `:` to `->` but never enough to bring it up. Josh Leverette wrote: > That modification could be subtle, yet powerful. It would make the language more > consistent, at the very least. Strong +1 if it could be considered, but I can live with that. Regards, W. On Tue, Jul 30, 2013 at 2:32 AM, Josh Leverette wrote: > That modification could be subtle, yet powerful. It would make the language > more consistent, at the very least. > > Sincerely, > Josh > > On Jul 29, 2013 7:29 PM, "Patrick Walton" wrote: >> >> On 7/29/13 4:29 PM, Wojciech Mi?kowski wrote: >>> >>> Hi, >>> >>> I'm observing rust development for some time, and I must say it slowly >>> encourages me to use it. Especially the progress from Perl-like syntax >>> to more sane and quiet form is enjoyable. >>> That said I wonder why the function definition has form: >>> fn name(var: type, ...) -> return_type {...} >>> instead of more unified: >>> fn name(var: type, ...): return_type {...} >>> >>> Is it constructed to mimic mathematical form f(x)->y or is there other >>> reason i.e. syntax ambiguity? >> >> >> Personal preference of Graydon, I believe. This is one of the few >> decisions that has survived from Rust 0.1 :) >> >> I slightly prefer `:` to `->` but never enough to bring it up. >> >> Patrick >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From ben.striegel at gmail.com Mon Jul 29 18:18:19 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Mon, 29 Jul 2013 21:18:19 -0400 Subject: [rust-dev] Function definition syntax In-Reply-To: <51F708CD.8030801@mozilla.com> References: <51F708CD.8030801@mozilla.com> Message-ID: I don't agree that the type of a function and the return type of a function are the same thing (specifically, the type of the function contains the return type). :) If nothing else, this would make the function signatures of higher-order functions much harder to read IMO. On Mon, Jul 29, 2013 at 8:29 PM, Patrick Walton wrote: > On 7/29/13 4:29 PM, Wojciech Mi?kowski wrote: > >> Hi, >> >> I'm observing rust development for some time, and I must say it slowly >> encourages me to use it. Especially the progress from Perl-like syntax >> to more sane and quiet form is enjoyable. >> That said I wonder why the function definition has form: >> fn name(var: type, ...) -> return_type {...} >> instead of more unified: >> fn name(var: type, ...): return_type {...} >> >> Is it constructed to mimic mathematical form f(x)->y or is there other >> reason i.e. syntax ambiguity? >> > > Personal preference of Graydon, I believe. This is one of the few > decisions that has survived from Rust 0.1 :) > > I slightly prefer `:` to `->` but never enough to bring it up. > > Patrick > > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ben.striegel at gmail.com Mon Jul 29 18:56:05 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Mon, 29 Jul 2013 21:56:05 -0400 Subject: [rust-dev] Function definition syntax In-Reply-To: References: <51F708CD.8030801@mozilla.com> Message-ID: Come to think of it, it might also make the grammar for function signatures ambiguous, given that we allow null return types to be omitted. On Mon, Jul 29, 2013 at 9:18 PM, Benjamin Striegel wrote: > I don't agree that the type of a function and the return type of a > function are the same thing (specifically, the type of the function > contains the return type). :) If nothing else, this would make the function > signatures of higher-order functions much harder to read IMO. > > > On Mon, Jul 29, 2013 at 8:29 PM, Patrick Walton wrote: > >> On 7/29/13 4:29 PM, Wojciech Mi?kowski wrote: >> >>> Hi, >>> >>> I'm observing rust development for some time, and I must say it slowly >>> encourages me to use it. Especially the progress from Perl-like syntax >>> to more sane and quiet form is enjoyable. >>> That said I wonder why the function definition has form: >>> fn name(var: type, ...) -> return_type {...} >>> instead of more unified: >>> fn name(var: type, ...): return_type {...} >>> >>> Is it constructed to mimic mathematical form f(x)->y or is there other >>> reason i.e. syntax ambiguity? >>> >> >> Personal preference of Graydon, I believe. This is one of the few >> decisions that has survived from Rust 0.1 :) >> >> I slightly prefer `:` to `->` but never enough to bring it up. >> >> Patrick >> >> >> ______________________________**_________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/**listinfo/rust-dev >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bjzaba at yahoo.com.au Mon Jul 29 19:08:01 2013 From: bjzaba at yahoo.com.au (Brendan Zabarauskas) Date: Tue, 30 Jul 2013 12:08:01 +1000 Subject: [rust-dev] Function definition syntax In-Reply-To: References: Message-ID: This would make function signatures harder to read in some instances, particularly when using closures and higher-order functions: let f: fn(T): T = ?; fn hof(x: T, f: fn(T): T): fn(T): T { ? } Compare to the current syntax: let f: fn(T) -> T = ?; fn hof(x: T, f: fn(T) -> T) -> fn(T) -> T { ? } ~Brendan On 30/07/2013, at 9:29 AM, Wojciech Mi?kowski wrote: > Hi, > > I'm observing rust development for some time, and I must say it slowly > encourages me to use it. Especially the progress from Perl-like syntax > to more sane and quiet form is enjoyable. > That said I wonder why the function definition has form: > fn name(var: type, ...) -> return_type {...} > instead of more unified: > fn name(var: type, ...): return_type {...} > > Is it constructed to mimic mathematical form f(x)->y or is there other > reason i.e. syntax ambiguity? > > > Cheers, > W. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From coder543 at gmail.com Mon Jul 29 19:18:40 2013 From: coder543 at gmail.com (Josh Leverette) Date: Mon, 29 Jul 2013 21:18:40 -0500 Subject: [rust-dev] Function definition syntax In-Reply-To: References: Message-ID: Neither is perfect. There is definitely room for improvement in both options. On Jul 29, 2013 9:08 PM, "Brendan Zabarauskas" wrote: > This would make function signatures harder to read in some instances, > particularly when using closures and higher-order functions: > > let f: fn(T): T = ?; > > fn hof(x: T, f: fn(T): T): fn(T): T { ? } > > Compare to the current syntax: > > let f: fn(T) -> T = ?; > > fn hof(x: T, f: fn(T) -> T) -> fn(T) -> T { ? } > > ~Brendan > > On 30/07/2013, at 9:29 AM, Wojciech Mi?kowski wrote: > > > Hi, > > > > I'm observing rust development for some time, and I must say it slowly > > encourages me to use it. Especially the progress from Perl-like syntax > > to more sane and quiet form is enjoyable. > > That said I wonder why the function definition has form: > > fn name(var: type, ...) -> return_type {...} > > instead of more unified: > > fn name(var: type, ...): return_type {...} > > > > Is it constructed to mimic mathematical form f(x)->y or is there other > > reason i.e. syntax ambiguity? > > > > > > Cheers, > > W. > > _______________________________________________ > > Rust-dev mailing list > > Rust-dev at mozilla.org > > https://mail.mozilla.org/listinfo/rust-dev > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alex at crichton.co Mon Jul 29 19:26:44 2013 From: alex at crichton.co (Alex Crichton) Date: Mon, 29 Jul 2013 19:26:44 -0700 Subject: [rust-dev] Redesigning fmt! In-Reply-To: <51F60C6C.5020106@mozilla.com> References: <51F58E4E.2000809@mozilla.com> <51F60C6C.5020106@mozilla.com> Message-ID: Thanks for all the comments everyone! I'll see if I can address a good number of them here: > - I don't see how the example {:date} is generated from the grammar. > Though I do think custom (especially culture-specific) formatter > functions do need some support. Money and dates are the big two. At the end of the format spec a `type` could be any identifier. I wanted to make multi-char identifiers possible because `:date` makes a lot of sense just reading it to see what it does. I also believe that because the formatting is trait-based, it should be easy to implement something like `idate` and `imoney` for the internationalized versions in a library. I believe though that this is definitely possible! > - I agree with others that the formatting of decimal has wiggle room in > the design; python's choice is ... so-so? I agree, I think that the way I want to go now is to implement the formatting specifiers in whatever syntax seems natural at first, and then before we start converting everything over to the new formatting system take some time to bikeshed the syntax of this. The syntax itself will be pretty easy to change along with the formatting routines at the beginning. I'm going to try to get most other stuff working first before tackling the specific syntax though (if that's ok). > - I also agree with Brian that _generalizing_ format modifiers somewhat > (so that formatting options can pass from format-string through to > formatter) might be worth thinking about some more. One cool thing that python does is allow `{:%d/%m%y}` for formatting dates. I agree that it's an awesome ability and has some really cool potential. The downsides to this are that the format string can't be checked at compile-time, and you may still want to specify alignment and things like that. Good news is that this is probably pretty easy to deal with (like the decimal format syntax) once all the rest of the infrastructure is in place. > - Your implementation is extremely clever and appears to be low > overhead, which is _great_. I am a little saddened, though, that > it rests not just on something that can dynamically fail but that > can (presumably) fail _badly_ (memory unsafe?) I think there might be some cleverness that could happy with TyDesc objects, but that would result is something like a static array in each executable with a mapping from "string format name" to TyDesc object. I do agree that this would be nice to have, though, because I was similarly saddened when I realized that I would have to flag the function as unsafe. > keyword/named selection is *really* great for longer/more busy patterns I agree that this would be nice to have, and I think that Huon's suggestion is a fantastic one! I'll try to target the `fmt!("{foo}", foo=bar)` syntax to start out with. > Can we have both? Parse at compile time if the string is constant but parse > at compile time if the string comes from something like a gettext-ish > function that loads the string from a message catalog. I can imagine a system where we do have both. One difficult part of this is that I wanted the runtime cost at the callsites to be as small as possible (with the goal of reducing codegen size). Precompiling this into something which doesn't result in massive codegen is a difficult problem that I was having a lot of trouble figuring out how to do. One thing I wanted to do in the long term was to implement purely runtime-based parsing, benchmark it, and then toy around with various precompiled versions to see how much the actual speedup is. If there's a noticeable 3x speedup, then it's probably worth the extra code overhead, but if it's like 10% it may not be as worth it. From me at kevincantu.org Mon Jul 29 19:59:50 2013 From: me at kevincantu.org (Kevin Cantu) Date: Mon, 29 Jul 2013 19:59:50 -0700 Subject: [rust-dev] MPS investigation for Rust GC In-Reply-To: References: Message-ID: I'm personally not very familiar with the Sleepycat license (as MPS seems to use: https://github.com/Ravenbrook/mps-temporary). Would proprietary code have to be shipped in separate binaries than the Rust runtime, or would commercial licensing be required? Kevin -- Kevin Cantu On Mon, Jul 29, 2013 at 10:41 AM, Thad Guidry wrote: > REGARDING: > - Graydon wants to investigate using the Memory Pool System as the Rust GC, > rather than a bespoke one. The > [MPS](http://www.ravenbrook.com/project/mps/) is > a very mature and robust memory management library. > > Reading through and seeing one of the MPS creators initial design goals : > > "The MPS was not designed for C++, but as a memory manager for dynamic > language run-time systems. In fact, it was specifically designed not to > require C++." > > ...instantly gained my respect for this system and its potential. > > -- > -Thad > Thad on Freebase.com > Thad on LinkedIn > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From explodingmind at gmail.com Mon Jul 29 20:33:37 2013 From: explodingmind at gmail.com (I.T. Daniher) Date: Mon, 29 Jul 2013 23:33:37 -0400 Subject: [rust-dev] MPS investigation for Rust GC In-Reply-To: References: Message-ID: If the licensing terms aren't suitable for you (for example, you're developing a closed-source commercial product or a *compiler run-time* *system*) you can easily license the MPS under different terms from Ravenbrook. Please write to us at `<*mps-questions at ravenbrook.com*>`_ for more information. from https://github.com/Ravenbrook/mps-temporary/blob/master/license.txt If there's serious interest in this, we could reach out. I don't know the state of the gc library project. On Mon, Jul 29, 2013 at 10:59 PM, Kevin Cantu wrote: > I'm personally not very familiar with the Sleepycat license (as MPS seems > to use: https://github.com/Ravenbrook/mps-temporary). > Would proprietary code have to be shipped in separate binaries than the > Rust runtime, or would commercial licensing be required? > > > Kevin > > > > > -- > Kevin Cantu > > > On Mon, Jul 29, 2013 at 10:41 AM, Thad Guidry wrote: > >> REGARDING: >> - Graydon wants to investigate using the Memory Pool System as the Rust >> GC, >> rather than a bespoke one. The >> [MPS](http://www.ravenbrook.com/project/mps/) is >> a very mature and robust memory management library. >> >> Reading through and seeing one of the MPS creators initial design goals : >> >> "The MPS was not designed for C++, but as a memory manager for dynamic >> language run-time systems. In fact, it was specifically designed not to >> require C++." >> >> ...instantly gained my respect for this system and its potential. >> >> -- >> -Thad >> Thad on Freebase.com >> Thad on LinkedIn >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From uther.ii at gmail.com Mon Jul 29 21:50:57 2013 From: uther.ii at gmail.com (Uther) Date: Tue, 30 Jul 2013 06:50:57 +0200 Subject: [rust-dev] Function definition syntax In-Reply-To: References: Message-ID: <51F74631.5030508@gmail.com> I didn't raise the subject since it seems late for a huge syntax change but if I had to change something about the function syntax I would change it to: fn function (var: type, ... -> returnType) {...} I really think it would be more readable especially in the case of Brendan Zabarauskas exemple : fn hof(x: T, f: fn(T->T) -> fn(T->T)) { ? } Le 30/07/13 04:08, Brendan Zabarauskas a ?crit : > This would make function signatures harder to read in some instances, particularly when using closures and higher-order functions: > > let f: fn(T): T = ?; > > fn hof(x: T, f: fn(T): T): fn(T): T { ? } > > Compare to the current syntax: > > let f: fn(T) -> T = ?; > > fn hof(x: T, f: fn(T) -> T) -> fn(T) -> T { ? } > > ~Brendan > > On 30/07/2013, at 9:29 AM, Wojciech Mi?kowski wrote: > >> Hi, >> >> I'm observing rust development for some time, and I must say it slowly >> encourages me to use it. Especially the progress from Perl-like syntax >> to more sane and quiet form is enjoyable. >> That said I wonder why the function definition has form: >> fn name(var: type, ...) -> return_type {...} >> instead of more unified: >> fn name(var: type, ...): return_type {...} >> >> Is it constructed to mimic mathematical form f(x)->y or is there other >> reason i.e. syntax ambiguity? >> >> >> Cheers, >> W. >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From ben.striegel at gmail.com Mon Jul 29 22:08:11 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Tue, 30 Jul 2013 01:08:11 -0400 Subject: [rust-dev] Function definition syntax In-Reply-To: <51F74631.5030508@gmail.com> References: <51F74631.5030508@gmail.com> Message-ID: This would make deeply-nested HOF easier to read, but I'm not a fan of the way that `fn foo(->int) {` looks for functions with no arguments. Because I forgot to register my opinion previously, I do like the way that the current syntax reads in the common case, including the use of the otherwise-idiosyncratic arrow symbol. "Call this function with these parameters, this type pops out." Coming from C-family languages and dynamic languages, I never gave the syntax for this a second thought. On Tue, Jul 30, 2013 at 12:50 AM, Uther wrote: > I didn't raise the subject since it seems late for a huge syntax change > but if I had to change something about the function syntax I would change > it to: > > fn function (var: type, ... -> returnType) {...} > > I really think it would be more readable especially in the case of Brendan > Zabarauskas exemple : > > fn hof(x: T, f: fn(T->T) -> fn(T->T)) { ? } > > > Le 30/07/13 04:08, Brendan Zabarauskas a ?crit : > > This would make function signatures harder to read in some instances, >> particularly when using closures and higher-order functions: >> >> let f: fn(T): T = ?; >> >> fn hof(x: T, f: fn(T): T): fn(T): T { ? } >> >> Compare to the current syntax: >> >> let f: fn(T) -> T = ?; >> >> fn hof(x: T, f: fn(T) -> T) -> fn(T) -> T { ? } >> >> ~Brendan >> >> On 30/07/2013, at 9:29 AM, Wojciech Mi?kowski >> wrote: >> >> Hi, >>> >>> I'm observing rust development for some time, and I must say it slowly >>> encourages me to use it. Especially the progress from Perl-like syntax >>> to more sane and quiet form is enjoyable. >>> That said I wonder why the function definition has form: >>> fn name(var: type, ...) -> return_type {...} >>> instead of more unified: >>> fn name(var: type, ...): return_type {...} >>> >>> Is it constructed to mimic mathematical form f(x)->y or is there other >>> reason i.e. syntax ambiguity? >>> >>> >>> Cheers, >>> W. >>> ______________________________**_________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/**listinfo/rust-dev >>> >> ______________________________**_________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/**listinfo/rust-dev >> > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Mon Jul 29 22:28:48 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Mon, 29 Jul 2013 22:28:48 -0700 Subject: [rust-dev] RFC: Overloadable dereference operator Message-ID: <51F74F10.5060808@mozilla.com> Hi everyone, I've recently started thinking that a number of use cases that we've wanted to solve at some point could be solved if the dereference operator could be overloaded much like the other operators. Most importantly, this addresses a missing part of the puzzle for custom smart pointers, but it also fixes issues relating to autoderef on newtypes and "common fields". # Mechanics We introduce a new lang item trait: #[lang="deref"] pub trait Deref { fn deref(&'self self) -> &'self Result; } This `deref` method is invoked by the compiler in two cases: 1. When the unary `*` operator is used on a value. In this case, the result pointer type is automatically dereferenced and becomes an lvalue (albeit an immutable one). 2. When method lookup or field projection fails. In this case, the method lookup or field projection is tried again with the `Result` type. It would be nice if `Result` were a functional dependency of `Self` above (e.g. simultaneous `impl Result for Foo` and `impl Result for Foo` would be forbidden). Unfortunately we don't have the trait machinery to enforce this yet, as this is associated types. We could just enforce this in an ad hoc way, or we could not enforce it. I don't care too much either way. # Use cases There are several use cases that this enables: ## Custom smart pointers For custom smart pointers it is highly desirable to support autoderef and to have the `*` operator enable access to fields. For example, suppose `@T` becomes `Gc`. We would like to avoid something like: let p: Gc = ...; do p.read |x| { printfln!("Your lucky number is %d", *x) } With overloadable deref it would look like: let p: Gc = ...; printfln!("Your lucky number is %d", *p) I *believe* that this does not cause liveness issues for GC and RC because the lifetime of the resulting reference is tied to the lifetime of the GC/RC box itself, so the reference piggybacks off the pointer's reference count and everything is OK. However, I could be mistaken here; here I'd like others to check my reasoning. In particular I'm also interested in legitimate use cases that this might forbid. ## Controllable newtype autoderef Currently, newtype structs automatically dereference to the value they contain; for example: struct MyInt(int); fn main() { let x = MyInt(3); printfln("1 + 2 = " + x.to_str()); // prints "1 + 2 = 3" } This behavior is sometimes undesirable, as Brian often points out. Haskell allows behavior similar to this to be controlled on an opt-in basis with `GeneralizedNewtypeDeriving`. We could support something similar by turning off autoderef for newtype structs and leaning on overloadable dereferencing when it is desirable. In this new world, to get the behavior above one would write: struct MyInt(int); impl Deref for MyInt { fn deref(&'self self) -> &'self int { let MyInt(ref inner) = *self; inner } } We could imagine something like this to make it simpler: #[deriving(Deref)] struct MyInt(int); ## Anonymous fields In Go (and in C with Plan 9 extensions) it is possible to place one struct inside another struct and inherit its fields: type Foo struct { X int Y int } type Bar struct { Foo Z int } x = Bar { Foo { X: 1, Y: 2, } Z: 3, } fmt.Println("%d", x.Y) // prints 2 This is almost multiple inheritance, except that the type of the `this` pointer will be different when invoking `Foo` methods on a `Bar` instance. With overloadable deref this would be possible in Rust as well: struct Bar { base: Foo, z: int, } impl Deref for Bar { fn deref(&'self self) -> &'self Foo { &self.base } } One could imagine macro sugar for this use case, for example: #[deriving(Deref(base))] struct Bar { base: Foo, z: int, } ## Common fields It is a common pattern, for example in Servo, to simulate inheritance in Rust with something like: struct Bar { base: FooCommon, ... } struct Baz { base: FooCommon, ... } struct Boo { base: FooCommon, ... } enum Foo { BarClass(~Bar), BazClass(~Baz), BooClass(~Boo), } The problem here is that if you have a `Foo` instance there is no convenient way to access the common fields short of a `match`. Again, overloadable deref comes to the rescue here. We could imagine an overloaded `Deref` as follows: impl Deref for Foo { fn deref(&'self self) -> &'self FooCommon { match *self { BarClass(ref bar) => &bar.base, BazClass(ref baz) => &baz.base, BooClass(ref boo) => &boo.base, } } } And once again we could come up with some sort of syntactic sugar for this. # Conclusion This one small feature seems to encompass a lot of use cases which we had previously thought we might have to solve using multiple disparate features. That cleanliness is attractive to me, assuming that this scheme works. I'd be interested to hear everyone's thoughts. From lindsey at composition.al Mon Jul 29 22:40:37 2013 From: lindsey at composition.al (Lindsey Kuper) Date: Mon, 29 Jul 2013 22:40:37 -0700 Subject: [rust-dev] Function definition syntax In-Reply-To: References: Message-ID: On Mon, Jul 29, 2013 at 4:29 PM, Wojciech Mi?kowski wrote: > That said I wonder why the function definition has form: > fn name(var: type, ...) -> return_type {...} > instead of more unified: > fn name(var: type, ...): return_type {...} > > Is it constructed to mimic mathematical form f(x)->y or is there other > reason i.e. syntax ambiguity? There's long precedent for `->` in function type signatures in, among other languages, Haskell, ML, and OCaml. In Rust, I like it better than `:` for reasons of readability -- it visually splits up the argument and return types nicely. If it came to a vote, my vote would be to keep it. Lindsey From armin.ronacher at active-4.com Mon Jul 29 23:45:41 2013 From: armin.ronacher at active-4.com (Armin Ronacher) Date: Tue, 30 Jul 2013 08:45:41 +0200 Subject: [rust-dev] Function definition syntax In-Reply-To: References: Message-ID: <51F76115.8010609@active-4.com> Hi, On 30/07/2013 01:29, Wojciech Mi?kowski wrote: > Is it constructed to mimic mathematical form f(x)->y or is there other > reason i.e. syntax ambiguity? I find it makes it vastly easier to read if a function shows up in a another function's signature. fn foo(f: &fn() -> int) vs fn foo(f: &fn(): int) Aside from that I just want to point out that this syntax for types is consistent with Python which uses the colon as a general general indentation marker: def foo(bar: int) -> int: pass Regards, Armin From graydon at mozilla.com Tue Jul 30 00:32:29 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 30 Jul 2013 00:32:29 -0700 Subject: [rust-dev] Function definition syntax In-Reply-To: References: Message-ID: <51F76C0D.20802@mozilla.com> On 13-07-29 04:29 PM, Wojciech Mi?kowski wrote: > Hi, > > I'm observing rust development for some time, and I must say it slowly > encourages me to use it. Especially the progress from Perl-like syntax > to more sane and quiet form is enjoyable. > That said I wonder why the function definition has form: > fn name(var: type, ...) -> return_type {...} > instead of more unified: > fn name(var: type, ...): return_type {...} Sigh. Speaking of Perl! "Larry's First Law of Language Redesign: Everyone wants the colon." We get this question every now and then, which is perhaps an indication that we're attracting more people from Scala-land than I expected. I can't imagine it's converts from Pascal! Let's tally up some function tycons from the world of languages: In the "->" column: Normal Mathematics[1] Simply Typed Lambda Calculus[2] C++11 alternative function syntax[3] Typed Racket[4] Typed Python[5] The term-rewrite languages (OBJ, Maude, Q, Pure) The ISWIM languages (Miranda, Hope, Clean, Haskell, ML, Ocaml, F#) In the ":" column: Scala One older Pike language (Limbo) The Wirth languages (Pascal, Modula-3, Oberon) Eiffel and Sather Our extremely worthy competitors Clay and Nimrod In the "some form of juxtaposition" column: C and C++ C#, Java D Cyclone Alef and Go If the argument's about consistency, I think the consistent thing to do is to keep ":" as a separator between bindings and types. My eyes get a little fuzzy guessing the associativity of "let x : fn(T) : U;" in a way that they do not when reading "let x : fn(T) -> U;". But I suppose reasonable people could disagre, or phrase the consistency requirement differently. My math professors would cry. Do people feel strongly? I think we've many better things to spend time on, and I'm not certain it won't raise an ambiguity. It'd also break every single patch, branch and package in progress (and personally, my heart is with the ISWIMs). -Graydon [1] http://en.wikipedia.org/wiki/Function_%28mathematics%29#Notation [2] http://en.wikipedia.org/wiki/Simply_typed_lambda_calculus#Syntax [3] https://en.wikipedia.org/wiki/C%2B%2B11#Alternative_function_syntax [4] http://docs.racket-lang.org/ts-guide/types.html#%28part._.Function_.Types%29 [5] http://www.python.org/dev/peps/pep-3107/ From wmilkowski at interia.pl Tue Jul 30 02:01:44 2013 From: wmilkowski at interia.pl (=?ISO-8859-2?Q?Wojciech_Mi=B3kowski?=) Date: Tue, 30 Jul 2013 11:01:44 +0200 Subject: [rust-dev] Function definition syntax In-Reply-To: <51F76C0D.20802@mozilla.com> References: <51F76C0D.20802@mozilla.com> Message-ID: On Tue, Jul 30, 2013 at 9:32 AM, Graydon Hoare wrote: > On 13-07-29 04:29 PM, Wojciech Mi?kowski wrote: > Sigh. Speaking of Perl! > > "Larry's First Law of Language Redesign: Everyone wants the colon." > Do people feel strongly? I think we've many better things to spend time on, > and I'm not certain it won't raise an ambiguity. It'd also break every > single patch, branch and package in progress (and personally, my heart is > with the ISWIMs). Fair enough. I just needed to clarify that for myself. As I said, it's not a deal breaker for me, and the examples of better readability are convinced. Thanks for the explanation. Regards, W. From reshef.dov at gmail.com Tue Jul 30 05:09:07 2013 From: reshef.dov at gmail.com (Dov Reshef) Date: Tue, 30 Jul 2013 15:09:07 +0300 Subject: [rust-dev] Crate local visibility Message-ID: Hello, I'd like to get people's opinions about crate local visibility. I feel that the way the public / private scope is divided now is encouraging making either too much code public or creating very large modules. If crate local visibility is not doable / too complex, then I'd ask to at least allow inner modules access to their ancestors' private items. What do you think? Is it a good idea? Thanks for reading, Dov -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Tue Jul 30 05:10:48 2013 From: corey at octayn.net (Corey Richardson) Date: Tue, 30 Jul 2013 08:10:48 -0400 Subject: [rust-dev] Crate local visibility In-Reply-To: References: Message-ID: On Tue, Jul 30, 2013 at 8:09 AM, Dov Reshef wrote: > Hello, > > I'd like to get people's opinions about crate local visibility. I feel that > the way the public / private scope is divided now is encouraging making > either too much code public or creating very large modules. I agree! It's very count-intuitive that to access sibling modules they need to be exposed to the whole world. From julius.pfrommer at web.de Tue Jul 30 05:56:31 2013 From: julius.pfrommer at web.de (Julius Pfrommer) Date: Tue, 30 Jul 2013 14:56:31 +0200 Subject: [rust-dev] sys::size_of() gives an unresolved name error Message-ID: <51F7B7FF.7050207@web.de> Hi everyone, I want to serialize certain data types into a vector of bytes ~[u8]. Most notably the integers and floats up to 64 bit. I also want to extract data from (the middle of) a ~[u8] vector back. Since this involves unsafe pointer operations, the size of the type is relevant for boundary checking. trait BaseType { fn to_binary(&self) -> ~[u8]; fn from_binary(bin: ~[u8], index: uint) -> Option { let size = std::sys::size_of(); // the code works if size is set to a fixed value (say 8 or 16) if bin.len() >= index+(size/8) { Some(extract(bin,(index*8)/size))) } else { None } } } fn extract(bin: ~[u8], index: uint) -> T { unsafe { let ptr = std::vec::raw::to_ptr(bin) as *T; std::vec::raw::from_buf_raw(ptr, bin.len())[index] } } The compiler aborts with the following message: datatypes.rs:10:37: 10:41 error: unresolved name `Self`. Did you mean `bin`? datatypes.rs:10 let size = std::sys::size_of()/8; Is it currently possible to access the size (in bits/bytes) of the "Self"-type? My rustc has version 0.8-pre (Ubuntu ppa rust-daily). Best regards, Julius PS: I looked at Bitv, yet chose to implement as a fairly simple trait for my use case. From corey at octayn.net Tue Jul 30 05:58:22 2013 From: corey at octayn.net (Corey Richardson) Date: Tue, 30 Jul 2013 08:58:22 -0400 Subject: [rust-dev] sys::size_of() gives an unresolved name error In-Reply-To: <51F7B7FF.7050207@web.de> References: <51F7B7FF.7050207@web.de> Message-ID: On Tue, Jul 30, 2013 at 8:56 AM, Julius Pfrommer wrote: > The compiler aborts with the following message: > datatypes.rs:10:37: 10:41 error: unresolved name `Self`. Did you mean `bin`? > datatypes.rs:10 let size = std::sys::size_of()/8; > > Is it currently possible to access the size (in bits/bytes) of the > "Self"-type? std::sys::size_of::() (there might be a better way to do what you'r achieving but I don't have time for a "proper" email) From slabode at aim.com Tue Jul 30 06:12:40 2013 From: slabode at aim.com (SiegeLord) Date: Tue, 30 Jul 2013 09:12:40 -0400 Subject: [rust-dev] Crate local visibility In-Reply-To: References: Message-ID: <51F7BBC8.1030708@aim.com> On 07/30/2013 08:10 AM, Corey Richardson wrote: > On Tue, Jul 30, 2013 at 8:09 AM, Dov Reshef wrote: >> Hello, >> >> I'd like to get people's opinions about crate local visibility. I feel that >> the way the public / private scope is divided now is encouraging making >> either too much code public or creating very large modules. > > I agree! It's very count-intuitive that to access sibling modules they > need to be exposed to the whole world. I don't think that's the case. I submitted a bug that concerns this: https://github.com/mozilla/rust/issues/7388 . I note, however, that now that code gives you a linker error (which is better than nothing). To reduce the example a bit: // This is a crate-local module, inaccessible from the outside of the crate mod private { pub fn private_fun() { } } // This is a public module, accessible from the outside of the crate pub mod public { use super::private::*; pub fn public_fun() { private_fun(); } } I'm not sure that's how it is supposed to be, but I'd prefer it to be by design. Incidentally, accessing that private_fun() from outside the crate gives you a linker error today. -SL From halperin.dr at gmail.com Tue Jul 30 06:46:07 2013 From: halperin.dr at gmail.com (Dave Halperin) Date: Tue, 30 Jul 2013 09:46:07 -0400 Subject: [rust-dev] Crate local visibility In-Reply-To: References: Message-ID: +1 to dealing this is one way or another. Another issue that dovetails with this is that unit tests are typically put in submodules but can't see private members in their parent. I often want to write tests for private helpers or check invariants that aren't visible in the public interface. AFAICT I either need to skip those tests or break with conventions. (Am I missing something?) Allowing submodules to see their ancestor's private items would fix this but feels too sweeping to me. How about something like C++'s friend declaration where you'd be able to declare which modules can see your module's private items? Hello, I'd like to get people's opinions about crate local visibility. I feel that the way the public / private scope is divided now is encouraging making either too much code public or creating very large modules. If crate local visibility is not doable / too complex, then I'd ask to at least allow inner modules access to their ancestors' private items. What do you think? Is it a good idea? Thanks for reading, Dov _______________________________________________ Rust-dev mailing list Rust-dev at mozilla.org https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From coder543 at gmail.com Tue Jul 30 08:26:40 2013 From: coder543 at gmail.com (Josh Leverette) Date: Tue, 30 Jul 2013 10:26:40 -0500 Subject: [rust-dev] MPS investigation for Rust GC In-Reply-To: References: Message-ID: I really don't think it's just him that the licensing terms aren't suitable for*. *By using MPS, *every single line* of Rust code ever written would be freely requestable by any and every individual unless the company writing the code took care to relicense MPS or to destroy any connection MPS has to their code. This is no way to make a new language accepted by the community, especially not a FOSS community. If MPS would be happy to relicense under the MIT for the whole of the FOSS community, I'm sure we would get along just fine, or, if Rust were to drop MPS... but I don't see any way for Rust to coexist with MPS with its current license. So yes, an investigation into this possibility is fine, but switching to it should wait until the license is appropriate, in my personal opinion. No offense to MPS. On Mon, Jul 29, 2013 at 10:33 PM, I.T. Daniher wrote: > If the licensing terms aren't suitable for you (for example, you're > developing a closed-source commercial product or a *compiler run-time* > *system*) you can easily license the MPS under different terms from > Ravenbrook. Please write to us at `<*mps-questions at ravenbrook.com*>`_ > for more information. > > from https://github.com/Ravenbrook/mps-temporary/blob/master/license.txt > > If there's serious interest in this, we could reach out. I don't know the > state of the gc library project. > > On Mon, Jul 29, 2013 at 10:59 PM, Kevin Cantu wrote: > >> I'm personally not very familiar with the Sleepycat license (as MPS seems >> to use: https://github.com/Ravenbrook/mps-temporary). >> Would proprietary code have to be shipped in separate binaries than the >> Rust runtime, or would commercial licensing be required? >> >> >> Kevin >> >> >> >> >> -- >> Kevin Cantu >> >> >> On Mon, Jul 29, 2013 at 10:41 AM, Thad Guidry wrote: >> >>> REGARDING: >>> - Graydon wants to investigate using the Memory Pool System as the Rust >>> GC, >>> rather than a bespoke one. The >>> [MPS](http://www.ravenbrook.com/project/mps/) is >>> a very mature and robust memory management library. >>> >>> Reading through and seeing one of the MPS creators initial design goals : >>> >>> "The MPS was not designed for C++, but as a memory manager for dynamic >>> language run-time systems. In fact, it was specifically designed not to >>> require C++." >>> >>> ...instantly gained my respect for this system and its potential. >>> >>> -- >>> -Thad >>> Thad on Freebase.com >>> Thad on LinkedIn >>> >>> _______________________________________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/listinfo/rust-dev >>> >>> >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -- Sincerely, Josh -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Tue Jul 30 08:28:46 2013 From: corey at octayn.net (Corey Richardson) Date: Tue, 30 Jul 2013 11:28:46 -0400 Subject: [rust-dev] MPS investigation for Rust GC In-Reply-To: References: Message-ID: On Tue, Jul 30, 2013 at 11:26 AM, Josh Leverette wrote: > I really don't think it's just him that the licensing terms aren't suitable > for. By using MPS, every single line of Rust code ever written would be > freely requestable by any and every individual unless the company writing > the code took care to relicense MPS or to destroy any connection MPS has to > their code. > > This is no way to make a new language accepted by the community, especially > not a FOSS community. If MPS would be happy to relicense under the MIT for > the whole of the FOSS community, I'm sure we would get along just fine, or, > if Rust were to drop MPS... but I don't see any way for Rust to coexist with > MPS with its current license. > > So yes, an investigation into this possibility is fine, but switching to it > should wait until the license is appropriate, in my personal opinion. No > offense to MPS. > This was already taken into consideration, upstream is amenable to relicensing, and have done so in the past. If a licensing agreement can't be worked out, it won't be used. From coder543 at gmail.com Tue Jul 30 08:29:32 2013 From: coder543 at gmail.com (Josh Leverette) Date: Tue, 30 Jul 2013 10:29:32 -0500 Subject: [rust-dev] MPS investigation for Rust GC In-Reply-To: References: Message-ID: Ok, this makes me feel better about the situation. On Tue, Jul 30, 2013 at 10:28 AM, Corey Richardson wrote: > On Tue, Jul 30, 2013 at 11:26 AM, Josh Leverette > wrote: > > I really don't think it's just him that the licensing terms aren't > suitable > > for. By using MPS, every single line of Rust code ever written would be > > freely requestable by any and every individual unless the company writing > > the code took care to relicense MPS or to destroy any connection MPS has > to > > their code. > > > > This is no way to make a new language accepted by the community, > especially > > not a FOSS community. If MPS would be happy to relicense under the MIT > for > > the whole of the FOSS community, I'm sure we would get along just fine, > or, > > if Rust were to drop MPS... but I don't see any way for Rust to coexist > with > > MPS with its current license. > > > > So yes, an investigation into this possibility is fine, but switching to > it > > should wait until the license is appropriate, in my personal opinion. No > > offense to MPS. > > > > This was already taken into consideration, upstream is amenable to > relicensing, and have done so in the past. If a licensing agreement > can't be worked out, it won't be used. > -- Sincerely, Josh -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Tue Jul 30 08:47:01 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 30 Jul 2013 08:47:01 -0700 Subject: [rust-dev] MPS investigation for Rust GC In-Reply-To: References: Message-ID: <51F7DFF5.2090803@mozilla.com> On 13-07-30 08:26 AM, Josh Leverette wrote: > I really don't think it's just him that the licensing terms aren't > suitable for/. /By using MPS, /every single line/ of Rust code ever > written would be freely requestable by any and every individual unless > the company writing the code took care to relicense MPS or to destroy > any connection MPS has to their code. > > This is no way to make a new language accepted by the community, > especially not a FOSS community. If MPS would be happy to relicense > under the MIT for the whole of the FOSS community, I'm sure we would get > along just fine, or, if Rust were to drop MPS... but I don't see any way > for Rust to coexist with MPS with its current license. We'd only be considering it under the (alleged) willingness for them to make an acceptable license for us. They have indicated a certain willingness to do so in the past, eg. for opendylan. We are not considering, nor will we ever consider, adopting anything into our standard libraries that causes licensing restrictions on downstream authors of Rust code. This is why (sadly) we can't take LGPL stuff into the stdlib either: downstream winds up needing to distribute code in relinkable form. Not ok. -Graydon From rossberg at mpi-sws.org Tue Jul 30 08:53:50 2013 From: rossberg at mpi-sws.org (Andreas Rossberg) Date: Tue, 30 Jul 2013 17:53:50 +0200 Subject: [rust-dev] Function definition syntax In-Reply-To: <51F76C0D.20802@mozilla.com> References: <51F76C0D.20802@mozilla.com> Message-ID: <84B1C957-0038-4514-80DF-E906EE6553A6@mpi-sws.org> On Jul 30, 2013, at 09:32 , Graydon Hoare wrote: > On 13-07-29 04:29 PM, Wojciech Mi?kowski wrote: >> Hi, >> >> I'm observing rust development for some time, and I must say it slowly >> encourages me to use it. Especially the progress from Perl-like syntax >> to more sane and quiet form is enjoyable. >> That said I wonder why the function definition has form: >> fn name(var: type, ...) -> return_type {...} >> instead of more unified: >> fn name(var: type, ...): return_type {...} > > Sigh. Speaking of Perl! > > "Larry's First Law of Language Redesign: Everyone wants the colon." > > We get this question every now and then, which is perhaps an indication that we're attracting more people from Scala-land than I expected. I can't imagine it's converts from Pascal! Let's tally up some function tycons from the world of languages: > > In the "->" column: > > Normal Mathematics[1] > Simply Typed Lambda Calculus[2] > C++11 alternative function syntax[3] > Typed Racket[4] > Typed Python[5] > The term-rewrite languages (OBJ, Maude, Q, Pure) > The ISWIM languages (Miranda, Hope, Clean, Haskell, ML, Ocaml, F#) > > In the ":" column: > > Scala > One older Pike language (Limbo) > The Wirth languages (Pascal, Modula-3, Oberon) > Eiffel and Sather > Our extremely worthy competitors Clay and Nimrod Let a lurker nitpick on a false dichotomy in this comparison. There are three separate things going on that the current discussion seems to confuse: 1. The syntax of type annotations. 2. The syntax of function types. 3. The syntax of function definitions. ML, Caml, Haskell, Coq, Agda, as well as Scala, and practically all higher-order languages with strong roots in type theory consistently use ":" for (1) and "->" for (2) (sometimes lexical variations like "::" or "=>"). Moreover, function definitions tend to be viewed as a special kind of equational pattern match where the pattern happens to be a function application. So in all these languages, a fully-annotated function definition would be written with a _colon_, too, contrary to what the above list seems to suggest. That's because it's just another type annotation of a pattern: f(x : t1) : t2 = exp annotates "f(x)" with the type t2. The type of f itself, on the other hand, would be written f : t1 -> t2. And g(x : t) : u -> v = exp is the definition of a function that results in a function, so that g : t -> (u -> v). This is pretty much the standard notation in type-theoretic literature or related languages (although some, notably Haskell, place more restrictions on function definitions and don't allow an inline return type annotation at all). Note how it's both readable and internally consistent. The Rust syntax arguably less so, although it's probably not worth changing. The arcane horrors of C-style type and declaration syntax are another topic altogether that I refrain from touching. :) /Andreas From banderson at mozilla.com Tue Jul 30 09:14:43 2013 From: banderson at mozilla.com (Brian Anderson) Date: Tue, 30 Jul 2013 09:14:43 -0700 Subject: [rust-dev] Crate local visibility In-Reply-To: References: Message-ID: <51F7E673.2000700@mozilla.com> On 07/30/2013 05:09 AM, Dov Reshef wrote: > Hello, > > I'd like to get people's opinions about crate local visibility. I feel > that the way the public / private scope is divided now is encouraging > making either too much code public or creating very large modules. If > crate local visibility is not doable / too complex, then I'd ask to at > least allow inner modules access to their ancestors' private items. > > What do you think? Is it a good idea? > There are bugs in name resolution that cause certain patterns that should work to fail. I believe that child modules are supposed to have access to private items of their parents. From pwalton at mozilla.com Tue Jul 30 09:24:30 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Tue, 30 Jul 2013 09:24:30 -0700 Subject: [rust-dev] Crate local visibility In-Reply-To: <51F7E673.2000700@mozilla.com> References: <51F7E673.2000700@mozilla.com> Message-ID: <51F7E8BE.5010901@mozilla.com> On 7/30/13 9:14 AM, Brian Anderson wrote: > There are bugs in name resolution that cause certain patterns that > should work to fail. I believe that child modules are supposed to have > access to private items of their parents. That's right. Patrick From banderson at mozilla.com Tue Jul 30 09:53:05 2013 From: banderson at mozilla.com (Brian Anderson) Date: Tue, 30 Jul 2013 09:53:05 -0700 Subject: [rust-dev] Function definition syntax In-Reply-To: <51F76C0D.20802@mozilla.com> References: <51F76C0D.20802@mozilla.com> Message-ID: <51F7EF71.3000406@mozilla.com> On 07/30/2013 12:32 AM, Graydon Hoare wrote: > On 13-07-29 04:29 PM, Wojciech Mi?kowski wrote: >> Hi, >> >> I'm observing rust development for some time, and I must say it slowly >> encourages me to use it. Especially the progress from Perl-like syntax >> to more sane and quiet form is enjoyable. >> That said I wonder why the function definition has form: >> fn name(var: type, ...) -> return_type {...} >> instead of more unified: >> fn name(var: type, ...): return_type {...} > > Do people feel strongly? I think we've many better things to spend > time on, and I'm not certain it won't raise an ambiguity. It'd also > break every single patch, branch and package in progress (and > personally, my heart is with the ISWIMs). I have a fairly strong preference for the current syntax for the various stated reasons. From zack.slayton at gmail.com Tue Jul 30 10:00:36 2013 From: zack.slayton at gmail.com (Zack Slayton) Date: Tue, 30 Jul 2013 13:00:36 -0400 Subject: [rust-dev] Function definition syntax In-Reply-To: References: <51F708CD.8030801@mozilla.com> Message-ID: +1 agreed on both accounts. On Mon, Jul 29, 2013 at 9:18 PM, Benjamin Striegel wrote: > I don't agree that the type of a function and the return type of a > function are the same thing (specifically, the type of the function > contains the return type). :) If nothing else, this would make the function > signatures of higher-order functions much harder to read IMO. > > > On Mon, Jul 29, 2013 at 8:29 PM, Patrick Walton wrote: > >> On 7/29/13 4:29 PM, Wojciech Mi?kowski wrote: >> >>> Hi, >>> >>> I'm observing rust development for some time, and I must say it slowly >>> encourages me to use it. Especially the progress from Perl-like syntax >>> to more sane and quiet form is enjoyable. >>> That said I wonder why the function definition has form: >>> fn name(var: type, ...) -> return_type {...} >>> instead of more unified: >>> fn name(var: type, ...): return_type {...} >>> >>> Is it constructed to mimic mathematical form f(x)->y or is there other >>> reason i.e. syntax ambiguity? >>> >> >> Personal preference of Graydon, I believe. This is one of the few >> decisions that has survived from Rust 0.1 :) >> >> I slightly prefer `:` to `->` but never enough to bring it up. >> >> Patrick >> >> >> ______________________________**_________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/**listinfo/rust-dev >> > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Tue Jul 30 10:05:44 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 30 Jul 2013 10:05:44 -0700 Subject: [rust-dev] Function definition syntax In-Reply-To: <84B1C957-0038-4514-80DF-E906EE6553A6@mpi-sws.org> References: <51F76C0D.20802@mozilla.com> <84B1C957-0038-4514-80DF-E906EE6553A6@mpi-sws.org> Message-ID: <51F7F268.8060701@mozilla.com> On 13-07-30 08:53 AM, Andreas Rossberg wrote: > Let a lurker nitpick on a false dichotomy in this comparison. There are three separate things going on that the current discussion seems to confuse: > > 1. The syntax of type annotations. > 2. The syntax of function types. > 3. The syntax of function definitions. Very fair point. > ML, Caml, Haskell, Coq, Agda, as well as Scala, and practically all higher-order languages with strong roots in type theory consistently use ":" for (1) and "->" for (2) (sometimes lexical variations like "::" or "=>"). > > Moreover, function definitions tend to be viewed as a special kind of equational pattern match where the pattern happens to be a function application. So in all these languages, a fully-annotated function definition would be written with a _colon_, too, contrary to what the above list seems to suggest. That's because it's just another type annotation of a pattern: > > f(x : t1) : t2 = exp > > annotates "f(x)" with the type t2. The type of f itself, on the other hand, would be written f : t1 -> t2. And > > g(x : t) : u -> v = exp > > is the definition of a function that results in a function, so that g : t -> (u -> v). Yeah. I was ... aware that the defining-forms varied orthogonally a bit but didn't really know how to summarize them across languages; I guess "a special kind of pattern" is the best summary, though many languages in the lists I mentioned don't even _have_ pattern grammars. But thanks for the clarification. It reminds me somewhat of the asymmetry between (T,U,V) tuple expressions and their type (T*U*V) in the MLs. An asymmetry I feel ... is a bit of a wart? We've tried to keep the expression, pattern and type grammars looking as similar as possible. > This is pretty much the standard notation in type-theoretic literature or related languages (although some, notably Haskell, place more restrictions on function definitions and don't allow an inline return type annotation at all). Note how it's both readable and internally consistent. The Rust syntax arguably less so, although it's probably not worth changing. Trickier call. We don't allow type ascription inside patterns, only at the outermost level. I think we found that our grammars were sufficiently similar that intermixing them inside one another produced ambiguities, though I don't remember off hand which one. Possibly the ambiguity between "{:}" and "{:}". Again: "everyone wants the colon" :) -Graydon From pwalton at mozilla.com Tue Jul 30 10:17:14 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Tue, 30 Jul 2013 10:17:14 -0700 Subject: [rust-dev] Function definition syntax In-Reply-To: <51F7F268.8060701@mozilla.com> References: <51F76C0D.20802@mozilla.com> <84B1C957-0038-4514-80DF-E906EE6553A6@mpi-sws.org> <51F7F268.8060701@mozilla.com> Message-ID: <51F7F51A.20000@mozilla.com> On 7/30/13 10:05 AM, Graydon Hoare wrote: > Trickier call. We don't allow type ascription inside patterns, only at > the outermost level. I think we found that our grammars were > sufficiently similar that intermixing them inside one another produced > ambiguities, though I don't remember off hand which one. Possibly the > ambiguity between "{:}" and "{:}". I actually don't think there's an ambiguity here any longer; type ascription inside patterns seems like a useful feature to me. Patrick From graydon at mozilla.com Tue Jul 30 10:39:04 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 30 Jul 2013 10:39:04 -0700 Subject: [rust-dev] Function definition syntax In-Reply-To: <51F7F51A.20000@mozilla.com> References: <51F76C0D.20802@mozilla.com> <84B1C957-0038-4514-80DF-E906EE6553A6@mpi-sws.org> <51F7F268.8060701@mozilla.com> <51F7F51A.20000@mozilla.com> Message-ID: <51F7FA38.5010403@mozilla.com> On 13-07-30 10:17 AM, Patrick Walton wrote: > On 7/30/13 10:05 AM, Graydon Hoare wrote: >> Trickier call. We don't allow type ascription inside patterns, only at >> the outermost level. I think we found that our grammars were >> sufficiently similar that intermixing them inside one another produced >> ambiguities, though I don't remember off hand which one. Possibly the >> ambiguity between "{:}" and "{:}". > > I actually don't think there's an ambiguity here any longer; type > ascription inside patterns seems like a useful feature to me. Really? How would you resolve it? You have to decide after seeing "{x:" which grammar to switch into parsing. Currently we go with the pattern grammar there. -Graydon From pwalton at mozilla.com Tue Jul 30 11:16:33 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Tue, 30 Jul 2013 11:16:33 -0700 Subject: [rust-dev] Function definition syntax In-Reply-To: <51F7FA38.5010403@mozilla.com> References: <51F76C0D.20802@mozilla.com> <84B1C957-0038-4514-80DF-E906EE6553A6@mpi-sws.org> <51F7F268.8060701@mozilla.com> <51F7F51A.20000@mozilla.com> <51F7FA38.5010403@mozilla.com> Message-ID: <51F80301.7050007@mozilla.com> On 7/30/13 10:39 AM, Graydon Hoare wrote: > Really? How would you resolve it? You have to decide after seeing "{x:" > which grammar to switch into parsing. Currently we go with the pattern > grammar there. Struct literals have to be prefixed with the type of the struct (as we don't have structural record labels anymore). So we don't have arbitrary `{x:` appearing inside patterns anymore; rather it's `Foo {x:`. Patrick From graydon at mozilla.com Tue Jul 30 11:34:40 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 30 Jul 2013 11:34:40 -0700 Subject: [rust-dev] Function definition syntax In-Reply-To: <51F80301.7050007@mozilla.com> References: <51F76C0D.20802@mozilla.com> <84B1C957-0038-4514-80DF-E906EE6553A6@mpi-sws.org> <51F7F268.8060701@mozilla.com> <51F7F51A.20000@mozilla.com> <51F7FA38.5010403@mozilla.com> <51F80301.7050007@mozilla.com> Message-ID: <51F80740.5040105@mozilla.com> On 13-07-30 11:16 AM, Patrick Walton wrote: > On 7/30/13 10:39 AM, Graydon Hoare wrote: >> Really? How would you resolve it? You have to decide after seeing "{x:" >> which grammar to switch into parsing. Currently we go with the pattern >> grammar there. > > Struct literals have to be prefixed with the type of the struct (as we > don't have structural record labels anymore). So we don't have arbitrary > `{x:` appearing inside patterns anymore; rather it's `Foo {x:`. You still have to decide what to parse after you saw "Foo {x:". If it's subpat, then you can't put a type ascription there. Maybe that's semantically unproblematic since Foo uniquely types its fields. But that breaks the symmetry with type-follows-":" in expr context. Now type follows ":" in _some_ places in pat, but pat follows ":" in other places. Personally I prefer our current rule, where "pat:type" and "expr:type" are the point of symmetry, and we don't try to dig further into either. -Graydon From pwalton at mozilla.com Tue Jul 30 11:36:45 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Tue, 30 Jul 2013 11:36:45 -0700 Subject: [rust-dev] Function definition syntax In-Reply-To: <51F80740.5040105@mozilla.com> References: <51F76C0D.20802@mozilla.com> <84B1C957-0038-4514-80DF-E906EE6553A6@mpi-sws.org> <51F7F268.8060701@mozilla.com> <51F7F51A.20000@mozilla.com> <51F7FA38.5010403@mozilla.com> <51F80301.7050007@mozilla.com> <51F80740.5040105@mozilla.com> Message-ID: <51F807BD.1030908@mozilla.com> On 7/30/13 11:34 AM, Graydon Hoare wrote: > You still have to decide what to parse after you saw "Foo {x:". If it's > subpat, then you can't put a type ascription there. Maybe that's > semantically unproblematic since Foo uniquely types its fields. But that > breaks the symmetry with type-follows-":" in expr context. Now type > follows ":" in _some_ places in pat, but pat follows ":" in other places. You're saying it causes problems with `let Foo { x, y } = ...;", to be more specific. That's true, yes. Patrick From graydon at mozilla.com Tue Jul 30 11:45:02 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 30 Jul 2013 11:45:02 -0700 Subject: [rust-dev] Function definition syntax In-Reply-To: <51F807BD.1030908@mozilla.com> References: <51F76C0D.20802@mozilla.com> <84B1C957-0038-4514-80DF-E906EE6553A6@mpi-sws.org> <51F7F268.8060701@mozilla.com> <51F7F51A.20000@mozilla.com> <51F7FA38.5010403@mozilla.com> <51F80301.7050007@mozilla.com> <51F80740.5040105@mozilla.com> <51F807BD.1030908@mozilla.com> Message-ID: <51F809AE.9020104@mozilla.com> On 13-07-30 11:36 AM, Patrick Walton wrote: > On 7/30/13 11:34 AM, Graydon Hoare wrote: >> You still have to decide what to parse after you saw "Foo {x:". If it's >> subpat, then you can't put a type ascription there. Maybe that's >> semantically unproblematic since Foo uniquely types its fields. But that >> breaks the symmetry with type-follows-":" in expr context. Now type >> follows ":" in _some_ places in pat, but pat follows ":" in other places. > > You're saying it causes problems with `let Foo { x, y } = ...;", to be > more specific. That's true, yes. Or other places. match thing { Foo { x:a, y:b } => ... } Is 'a' a type or a pat? Currently it's a pat. If we make it a type (to mirror the expr form) then we can't destructure fields recursively with subpats. If we keep it a pat then it'd be an exception to the putative rule "types follow : in pats". -Graydon From rossberg at mpi-sws.org Tue Jul 30 13:03:11 2013 From: rossberg at mpi-sws.org (Andreas Rossberg) Date: Tue, 30 Jul 2013 22:03:11 +0200 Subject: [rust-dev] Function definition syntax In-Reply-To: <51F7F268.8060701@mozilla.com> References: <51F76C0D.20802@mozilla.com> <84B1C957-0038-4514-80DF-E906EE6553A6@mpi-sws.org> <51F7F268.8060701@mozilla.com> Message-ID: <66765CB4-6AE3-45A5-980B-0A6FD04E683A@mpi-sws.org> On Jul 30, 2013, at 19:05 , Graydon Hoare wrote: > It reminds me somewhat of the asymmetry between (T,U,V) tuple expressions and their type (T*U*V) in the MLs. An asymmetry I feel ... is a bit of a wart? We've tried to keep the expression, pattern and type grammars looking as similar as possible. Ah, actually, this asymmetry, as you call it, is also standard, and quite relevant. It's rather Haskell's pun on using the same syntax for tuples and their classifier that is an outlier (and arguably a wart). The problem with it is that it is essentially a category error: (T,U) is the natural notation for a tuple of types, not for the type of a tuple of values. This becomes an issue if you consider richer languages: having constructs like lambdas or tuples on the type level itself (or even higher universes) is common in higher-order type systems. And then you need to be able to express both (T,U) and T*U, which are completely different beasts. (ML specifically does use type tuples for n-ary type constructors: "(int, string) map" has quite a different meaning from "(int * string) list" .) So overloading the syntax of introduction forms with their classifiers is one of these things that looks neat at first but turns out not to scale well (and to lead to confusion). > Trickier call. We don't allow type ascription inside patterns, only at the outermost level. I think we found that our grammars were sufficiently similar that intermixing them inside one another produced ambiguities, though I don't remember off hand which one. Possibly the ambiguity between "{:}" and "{:}". Of course, the former one is conventionally written "{ = }" for this reason, and the ones mentioned above. :) /Andreas From rossberg at mpi-sws.org Tue Jul 30 13:03:11 2013 From: rossberg at mpi-sws.org (Andreas Rossberg) Date: Tue, 30 Jul 2013 22:03:11 +0200 Subject: [rust-dev] Function definition syntax In-Reply-To: <51F7F268.8060701@mozilla.com> References: <51F76C0D.20802@mozilla.com> <84B1C957-0038-4514-80DF-E906EE6553A6@mpi-sws.org> <51F7F268.8060701@mozilla.com> Message-ID: <038F8135-A85F-414F-B59C-B9B72F1373C3@mpi-sws.org> On Jul 30, 2013, at 19:05 , Graydon Hoare wrote: > It reminds me somewhat of the asymmetry between (T,U,V) tuple expressions and their type (T*U*V) in the MLs. An asymmetry I feel ... is a bit of a wart? We've tried to keep the expression, pattern and type grammars looking as similar as possible. Ah, actually, this asymmetry, as you call it, is also standard, and quite relevant. It's rather Haskell's pun on using the same syntax for tuples and their classifier that is an outlier (and arguably a wart). The problem with it is that it is essentially a category error: (T,U) is the natural notation for a tuple of types, not for the type of a tuple of values. This becomes an issue if you consider richer languages: having constructs like lambdas or tuples on the type level itself (or even higher universes) is common in higher-order type systems. And then you need to be able to express both (T,U) and T*U, which are completely different beasts. (ML specifically does use type tuples for n-ary type constructors: "(int, string) map" has quite a different meaning from "(int * string) list" .) So overloading the syntax of introduction forms with their classifiers is one of these things that looks neat at first but turns out not to scale well (and to lead to confusion). > Trickier call. We don't allow type ascription inside patterns, only at the outermost level. I think we found that our grammars were sufficiently similar that intermixing them inside one another produced ambiguities, though I don't remember off hand which one. Possibly the ambiguity between "{:}" and "{:}". Of course, the former one is conventionally written "{ = }" for this reason, and the ones mentioned above. :) /Andreas From alex at crichton.co Tue Jul 30 13:33:00 2013 From: alex at crichton.co (Alex Crichton) Date: Tue, 30 Jul 2013 13:33:00 -0700 Subject: [rust-dev] Crate local visibility In-Reply-To: <51F7E8BE.5010901@mozilla.com> References: <51F7E673.2000700@mozilla.com> <51F7E8BE.5010901@mozilla.com> Message-ID: I've always wanted to see the correct rules written down in one place, so I wanted to try to at least the best of my ability. Is this what resolve is supposed to do? 1: All items are private by default, with the exception of struct fields. To flag an item as public, you use `pub`. Also `pub` is not allowed on `impl` or `extern` (visibility is determined by each item individually). 2: For a path which is a cross-crate reference, it is only valid of *every* item in the path is marked as `pub`. 3: A module may access any item from its immediate parent. 4. A module may access any item from its immediate children. 5. Any local-crate path which goes outside the bounds of 3/4 will only resolve if each component of the path is `pub`. For example I could reach into a child's private mod's pub items, but not the child's private mod's non-pub items. Those are the rules that at least make sense to me, I'm not sure if that's what is intended. Regardless, this would make for an awesome compile-fail test to showcase how resolve works. I also wanted to mention #8122 because if these rules are true I don't think that `priv` is needed at all for visibility except for enum variants and struct fields. If possible I'd like to make it a compile error to put `priv` on an item if these rules are true. Do others agree with these rules or are there missing ones? I'd be more than willing to open an issue and curate related issues once we've got these all written down. From graydon at mozilla.com Tue Jul 30 14:29:42 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 30 Jul 2013 14:29:42 -0700 Subject: [rust-dev] Function definition syntax In-Reply-To: <66765CB4-6AE3-45A5-980B-0A6FD04E683A@mpi-sws.org> References: <51F76C0D.20802@mozilla.com> <84B1C957-0038-4514-80DF-E906EE6553A6@mpi-sws.org> <51F7F268.8060701@mozilla.com> <66765CB4-6AE3-45A5-980B-0A6FD04E683A@mpi-sws.org> Message-ID: <51F83046.1010003@mozilla.com> On 13-07-30 01:03 PM, Andreas Rossberg wrote: > Ah, actually, this asymmetry, as you call it, is also standard, and quite relevant. It's rather Haskell's pun on using the same syntax for tuples and their classifier that is an outlier (and arguably a wart). The problem with it is that it is essentially a category error: (T,U) is the natural notation for a tuple of types, not for the type of a tuple of values. This becomes an issue if you consider richer languages: having constructs like lambdas or tuples on the type level itself (or even higher universes) is common in higher-order type systems. And then you need to be able to express both (T,U) and T*U, which are completely different beasts. (ML specifically does use type tuples for n-ary type constructors: "(int, string) map" has quite a different meaning from "(int * string) list" .) I'm aware of this but I think Haskell chose right, pushing the onus for differing syntax onto higher order types. In our case as we're targeting a C++ audience, we had to put all our type parameters in form anyways. Of course _this_ has its own lexical headaches when it comes to disambiguating against the < operator: we used to use [T,U,V] like Scala, but user feedback decisively rejected it. My kingdom for a few extra bracket characters! Maybe I should be more dictatorial and less democratic when it comes to such things; I'm a bit of a pushover. > So overloading the syntax of introduction forms with their classifiers is one of these things that looks neat at first but turns out not to scale well (and to lead to confusion). > Of course, the former one is conventionally written "{ = }" for this reason, and the ones mentioned above. :) Yes, and this is what Rust did for quite a while, until we got sufficient user feedback that they preferred ":" here. Maybe once unicode input methods are sufficiently widespread we won't have people fighting over ":" _or_ brackets so much :) -Graydon From reshef.dov at gmail.com Tue Jul 30 15:05:31 2013 From: reshef.dov at gmail.com (Dov Reshef) Date: Wed, 31 Jul 2013 01:05:31 +0300 Subject: [rust-dev] Crate local visibility In-Reply-To: References: <51F7E673.2000700@mozilla.com> <51F7E8BE.5010901@mozilla.com> Message-ID: 3. and 4 do not currently work in all cases. Either that or I'm testing them wrong. see here: https://gist.github.com/DovReshef/6116690. On Tue, Jul 30, 2013 at 11:33 PM, Alex Crichton wrote: > I've always wanted to see the correct rules written down in one place, so I > wanted to try to at least the best of my ability. Is this what resolve is > supposed to do? > > 1: All items are private by default, with the exception of struct fields. > To flag an item as public, you use `pub`. Also `pub` is not allowed on > `impl` > or `extern` (visibility is determined by each item individually). > > 2: For a path which is a cross-crate reference, it is only valid of *every* > item in the path is marked as `pub`. > > 3: A module may access any item from its immediate parent. > > 4. A module may access any item from its immediate children. > > 5. Any local-crate path which goes outside the bounds of 3/4 will only > resolve > if each component of the path is `pub`. For example I could reach into a > child's private mod's pub items, but not the child's private mod's > non-pub > items. > > Those are the rules that at least make sense to me, I'm not sure if that's > what > is intended. Regardless, this would make for an awesome compile-fail test > to > showcase how resolve works. > > I also wanted to mention #8122 because if these rules are true I don't > think > that `priv` is needed at all for visibility except for enum variants and > struct > fields. If possible I'd like to make it a compile error to put `priv` on > an item > if these rules are true. > > Do others agree with these rules or are there missing ones? I'd be > more than willing to open an issue and curate related issues once > we've got these all written down. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bjzaba at yahoo.com.au Tue Jul 30 15:59:07 2013 From: bjzaba at yahoo.com.au (Brendan Zabarauskas) Date: Wed, 31 Jul 2013 08:59:07 +1000 Subject: [rust-dev] Function definition syntax In-Reply-To: <51F83046.1010003@mozilla.com> References: <51F76C0D.20802@mozilla.com> <84B1C957-0038-4514-80DF-E906EE6553A6@mpi-sws.org> <51F7F268.8060701@mozilla.com> <66765CB4-6AE3-45A5-980B-0A6FD04E683A@mpi-sws.org> <51F83046.1010003@mozilla.com> Message-ID: <37281313-D300-4BC6-B784-CE3C61536C15@yahoo.com.au> On 31/07/2013, at 7:29 AM, Graydon Hoare wrote: > we used to use [T,U,V] like Scala, but user feedback decisively rejected it. My kingdom > for a few extra bracket characters! > > Maybe I should be more dictatorial and less democratic when it comes to > such things; I'm a bit of a pushover. Damn, that's a shame. Feel free to use your Benevolent Dictator For Life role in future! The users will thank you in the end :) *shudders at the issues caused by <> delimeters* ~Brendan From julius.pfrommer at web.de Wed Jul 31 00:46:31 2013 From: julius.pfrommer at web.de (Julius Pfrommer) Date: Wed, 31 Jul 2013 09:46:31 +0200 Subject: [rust-dev] sys::size_of() gives an unresolved name error In-Reply-To: References: <51F7B7FF.7050207@web.de> Message-ID: <51F8C0D7.6020009@web.de> Thanks a lot. I believe to have a reasonable solution now. trait BinaryStorage { fn to_binary(&self) -> ~[u8] { let size = std::sys::size_of_val(self); unsafe { let src = std::ptr::to_unsafe_ptr(self) as *u8; std::vec::from_buf(src,size) } } fn from_binary(bin: ~[u8], index: uint) -> Option { let size = std::sys::size_of::(); if bin.len() >= index+size { unsafe { let ptr = std::ptr::offset(std::vec::raw::to_ptr(bin), index); Some(std::ptr::read_ptr(ptr as *mut Self)) } } else { None } } } The trait is generic for all non-vector types. impl BinaryStorage for bool; impl BinaryStorage for i32; impl BinaryStorage for f64; If there still is a more "proper" way, feel free to tell me about the rust-idiomatic approach. Best, Julius On 30.07.2013 14:58, Corey Richardson wrote: > On Tue, Jul 30, 2013 at 8:56 AM, Julius Pfrommer wrote: >> The compiler aborts with the following message: >> datatypes.rs:10:37: 10:41 error: unresolved name `Self`. Did you mean `bin`? >> datatypes.rs:10 let size = std::sys::size_of()/8; >> >> Is it currently possible to access the size (in bits/bytes) of the >> "Self"-type? > std::sys::size_of::() > > (there might be a better way to do what you'r achieving but I don't > have time for a "proper" email) From corey at octayn.net Wed Jul 31 02:33:05 2013 From: corey at octayn.net (Corey Richardson) Date: Wed, 31 Jul 2013 05:33:05 -0400 Subject: [rust-dev] sys::size_of() gives an unresolved name error In-Reply-To: <51F8C0D7.6020009@web.de> References: <51F7B7FF.7050207@web.de> <51F8C0D7.6020009@web.de> Message-ID: On Wed, Jul 31, 2013 at 3:46 AM, Julius Pfrommer wrote: > Thanks a lot. > > I believe to have a reasonable solution now. > > trait BinaryStorage { > fn to_binary(&self) -> ~[u8] { > let size = std::sys::size_of_val(self); > unsafe { > let src = std::ptr::to_unsafe_ptr(self) as *u8; > std::vec::from_buf(src,size) > > } > } > fn from_binary(bin: ~[u8], index: uint) -> Option { > let size = std::sys::size_of::(); > if bin.len() >= index+size { > unsafe { > let ptr = std::ptr::offset(std::vec::raw::to_ptr(bin), > index); > Some(std::ptr::read_ptr(ptr as *mut Self)) > } > } else { None } > } > } > This should take a &[u8], it doesn't need to own the vector. > The trait is generic for all non-vector types. > > impl BinaryStorage for bool; > impl BinaryStorage for i32; > impl BinaryStorage for f64; > > If there still is a more "proper" way, feel free to tell me about the > rust-idiomatic approach. > This seems reasonable to me (and you could have a `impl BinaryStorage for T` I think), but see also http://static.rust-lang.org/doc/extra/serialize.html. Encodable and Decodable can be derived (with a #[deriving(Encodable)] attribute). From steve at steveklabnik.com Wed Jul 31 06:19:39 2013 From: steve at steveklabnik.com (Steve Klabnik) Date: Wed, 31 Jul 2013 09:19:39 -0400 Subject: [rust-dev] Exercism.io and Rust Message-ID: Hey Rustics, One of my collegues started http://exercism.io, a site for people to work on little code examples and discuss them with other people. It started out with Ruby, then went to JavaScript, Clojure, Elixir, and Go. I started porting them over to HEAD Rust, as well. If anyone else wants to help with this effort, or make suggestions about how to make it better, I'd love the help/feedback. Here's the first set of tests for the first example: https://github.com/kytrinyx/exercism.io/pull/277/files And here's the list of examples https://github.com/kytrinyx/exercism.io/issues/297 - Steve From niko at alum.mit.edu Wed Jul 31 22:59:16 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Thu, 1 Aug 2013 01:59:16 -0400 Subject: [rust-dev] Function definition syntax In-Reply-To: References: Message-ID: <20130801055916.GH2529@Mr-Bennet> +1 On Mon, Jul 29, 2013 at 10:40:37PM -0700, Lindsey Kuper wrote: > On Mon, Jul 29, 2013 at 4:29 PM, Wojciech Mi?kowski wrote: > > That said I wonder why the function definition has form: > > fn name(var: type, ...) -> return_type {...} > > instead of more unified: > > fn name(var: type, ...): return_type {...} > > > > Is it constructed to mimic mathematical form f(x)->y or is there other > > reason i.e. syntax ambiguity? > > There's long precedent for `->` in function type signatures in, among > other languages, Haskell, ML, and OCaml. > > In Rust, I like it better than `:` for reasons of readability -- it > visually splits up the argument and return types nicely. If it came > to a vote, my vote would be to keep it. > > Lindsey > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From niko at alum.mit.edu Wed Jul 31 23:03:22 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Thu, 1 Aug 2013 02:03:22 -0400 Subject: [rust-dev] Function definition syntax In-Reply-To: <37281313-D300-4BC6-B784-CE3C61536C15@yahoo.com.au> References: <51F76C0D.20802@mozilla.com> <84B1C957-0038-4514-80DF-E906EE6553A6@mpi-sws.org> <51F7F268.8060701@mozilla.com> <66765CB4-6AE3-45A5-980B-0A6FD04E683A@mpi-sws.org> <51F83046.1010003@mozilla.com> <37281313-D300-4BC6-B784-CE3C61536C15@yahoo.com.au> Message-ID: <20130801060322.GI2529@Mr-Bennet> On Wed, Jul 31, 2013 at 08:59:07AM +1000, Brendan Zabarauskas wrote: > On 31/07/2013, at 7:29 AM, Graydon Hoare wrote: > > > we used to use [T,U,V] like Scala, but user feedback decisively rejected it. My kingdom > > for a few extra bracket characters! > > > > Maybe I should be more dictatorial and less democratic when it comes to > > such things; I'm a bit of a pushover. > > Damn, that's a shame. Feel free to use your Benevolent Dictator For Life role in future! The users will thank you in the end :) > > *shudders at the issues caused by <> delimeters* While I tend to prefer `[]` visually, I don't see how it solves any of the ambiguities that arise in parsing, if that's what you're referring to. At least not in our case. Niko From kballard at gmail.com Wed Jul 31 23:40:40 2013 From: kballard at gmail.com (Kevin Ballard) Date: Wed, 31 Jul 2013 23:40:40 -0700 Subject: [rust-dev] RFC: Overloadable dereference operator In-Reply-To: <51F74F10.5060808@mozilla.com> References: <51F74F10.5060808@mozilla.com> Message-ID: In general, I like this. Although trying to use this feature as a way to simulate Go's struct embedding seems a bit misguided. Besides the fact that this would allow you to say *bar to get the embedded struct, which seems unintentional, it also won't work if you want to embed two separate structs and allow for delegating methods to both of them. I don't have a solution off-hand for simulating embedding of two separate structs w/method lookup though. -Kevin On Mon, Jul 29, 2013 at 10:28 PM, Patrick Walton wrote: > Hi everyone, > > I've recently started thinking that a number of use cases that we've wanted > to solve at some point could be solved if the dereference operator could be > overloaded much like the other operators. Most importantly, this addresses a > missing part of the puzzle for custom smart pointers, but it also fixes > issues relating to autoderef on newtypes and "common fields". > > # Mechanics > > We introduce a new lang item trait: > > #[lang="deref"] > pub trait Deref { > fn deref(&'self self) -> &'self Result; > } > > This `deref` method is invoked by the compiler in two cases: > > 1. When the unary `*` operator is used on a value. In this case, the result > pointer type is automatically dereferenced and becomes an lvalue (albeit an > immutable one). > > 2. When method lookup or field projection fails. In this case, the method > lookup or field projection is tried again with the `Result` type. > > It would be nice if `Result` were a functional dependency of `Self` above > (e.g. simultaneous `impl Result for Foo` and `impl Result for > Foo` would be forbidden). Unfortunately we don't have the trait machinery to > enforce this yet, as this is associated types. We could just enforce this in > an ad hoc way, or we could not enforce it. I don't care too much either way. > > # Use cases > > There are several use cases that this enables: > > ## Custom smart pointers > > For custom smart pointers it is highly desirable to support autoderef and to > have the `*` operator enable access to fields. For example, suppose `@T` > becomes `Gc`. We would like to avoid something like: > > let p: Gc = ...; > do p.read |x| { > printfln!("Your lucky number is %d", *x) > } > > With overloadable deref it would look like: > > let p: Gc = ...; > printfln!("Your lucky number is %d", *p) > > I *believe* that this does not cause liveness issues for GC and RC because > the lifetime of the resulting reference is tied to the lifetime of the GC/RC > box itself, so the reference piggybacks off the pointer's reference count > and everything is OK. However, I could be mistaken here; here I'd like > others to check my reasoning. In particular I'm also interested in > legitimate use cases that this might forbid. > > ## Controllable newtype autoderef > > Currently, newtype structs automatically dereference to the value they > contain; for example: > > struct MyInt(int); > fn main() { > let x = MyInt(3); > printfln("1 + 2 = " + x.to_str()); // prints "1 + 2 = 3" > } > > This behavior is sometimes undesirable, as Brian often points out. Haskell > allows behavior similar to this to be controlled on an opt-in basis with > `GeneralizedNewtypeDeriving`. We could support something similar by turning > off autoderef for newtype structs and leaning on overloadable dereferencing > when it is desirable. In this new world, to get the behavior above one would > write: > > struct MyInt(int); > impl Deref for MyInt { > fn deref(&'self self) -> &'self int { > let MyInt(ref inner) = *self; > inner > } > } > > We could imagine something like this to make it simpler: > > #[deriving(Deref)] > struct MyInt(int); > > ## Anonymous fields > > In Go (and in C with Plan 9 extensions) it is possible to place one struct > inside another struct and inherit its fields: > > type Foo struct { > X int > Y int > } > > type Bar struct { > Foo > Z int > } > > x = Bar { > Foo { > X: 1, > Y: 2, > } > Z: 3, > } > fmt.Println("%d", x.Y) // prints 2 > > This is almost multiple inheritance, except that the type of the `this` > pointer will be different when invoking `Foo` methods on a `Bar` instance. > > With overloadable deref this would be possible in Rust as well: > > struct Bar { > base: Foo, > z: int, > } > > impl Deref for Bar { > fn deref(&'self self) -> &'self Foo { > &self.base > } > } > > One could imagine macro sugar for this use case, for example: > > #[deriving(Deref(base))] > struct Bar { > base: Foo, > z: int, > } > > ## Common fields > > It is a common pattern, for example in Servo, to simulate inheritance in > Rust with something like: > > struct Bar { > base: FooCommon, > ... > } > > struct Baz { > base: FooCommon, > ... > } > > struct Boo { > base: FooCommon, > ... > } > > enum Foo { > BarClass(~Bar), > BazClass(~Baz), > BooClass(~Boo), > } > > The problem here is that if you have a `Foo` instance there is no convenient > way to access the common fields short of a `match`. Again, overloadable > deref comes to the rescue here. We could imagine an overloaded `Deref` as > follows: > > impl Deref for Foo { > fn deref(&'self self) -> &'self FooCommon { > match *self { > BarClass(ref bar) => &bar.base, > BazClass(ref baz) => &baz.base, > BooClass(ref boo) => &boo.base, > } > } > } > > And once again we could come up with some sort of syntactic sugar for this. > > # Conclusion > > This one small feature seems to encompass a lot of use cases which we had > previously thought we might have to solve using multiple disparate features. > That cleanliness is attractive to me, assuming that this scheme works. I'd > be interested to hear everyone's thoughts. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev