Re: Is this a bug in std.typecons.Tuple.slice?
On Tuesday, 9 February 2016 at 09:05:58 UTC, Ola Fosheim Grøstad wrote: IMO one shouldn't be able to take the reference of a tuple, to ensure that it can be kept in registers. No need to restrict the language here, there's nothing stopping a decent compiler from storing tuples (actually _anything_) in registers, in some cases even if references are taken. I'm pretty sure LLVM can handle this.
Re: Is this a bug in std.typecons.Tuple.slice?
On Tuesday, 9 February 2016 at 08:35:21 UTC, tsbockman wrote: When faced with a judgment call like this, we really ought to err on the side of maintaining backwards compatibility - especially since this does not preclude adding a separate by-value version of `Tuple.slice`, as well. It was going to need a new name anyway. I suggest lobbying for proper builtin tuple support. IMO one shouldn't be able to take the reference of a tuple, to ensure that it can be kept in registers. Modern desktop CPUs have maybe 512 bytes of register space. In most cases a tuple will be within 8 bytes * 16 or something like that.
Re: Is this a bug in std.typecons.Tuple.slice?
On Tuesday, 9 February 2016 at 06:22:55 UTC, Marco Leise wrote: As mentioned I never used the feature myself and wont vote for one or the other. Three people with no source code to exemplify current use of .slice! is indeed not much to base decisions on... The mere fact that all I had to do to find people who use and care about the `ref`-ness of `Tuple.slice` was ask, and then wait a few hours, strongly suggests that there are other such people among the D user base. When faced with a judgment call like this, we really ought to err on the side of maintaining backwards compatibility - especially since this does not preclude adding a separate by-value version of `Tuple.slice`, as well. It was going to need a new name anyway.
Re: Is this a bug in std.typecons.Tuple.slice?
On Tuesday, 9 February 2016 at 13:43:16 UTC, Marc Schütz wrote: So what? Using that argument, you could just as well forbid taking the address of any variable. What's so special about tuples, in contrast to structs and arrays? Some key common qualities for a tuple: 1. They are primarily used for multiple return values from functions. 2. Tuples use structural typing, not nominal typing. 3. They are identity-less. If you can take reference and compare, they no longer are identity-less. Tuples should be considered immutable constants (think functional programming), not in-memory storage. Again, why? Because that is how a tuple is commonly defined, for performance and semantic reasons. Tuple's can serve as a good approximation to SIMD registers. What relation does that have to the above? You don't want to spill out SIMD registers to the stack if you can avoid it. You want to do the changes within the CPU pipeline, i.e. using copies (and register renaming).
Re: Is this a bug in std.typecons.Tuple.slice?
On Tuesday, 9 February 2016 at 10:54:42 UTC, Marc Schütz wrote: No need to restrict the language here, there's nothing stopping a decent compiler from storing tuples (actually _anything_) in registers, in some cases even if references are taken. I'm pretty sure LLVM can handle this. If you don't restrict the language people will write code that the optimizer will struggle with. LLVM can only handle what goes on within a compilation unit, and not if there are stores, because those are visible in other threads. Tuples should be considered immutable constants (think functional programming), not in-memory storage. Tuple's can serve as a good approximation to SIMD registers.
Re: Is this a bug in std.typecons.Tuple.slice?
On Tuesday, 9 February 2016 at 11:38:14 UTC, Ola Fosheim Grøstad wrote: On Tuesday, 9 February 2016 at 10:54:42 UTC, Marc Schütz wrote: No need to restrict the language here, there's nothing stopping a decent compiler from storing tuples (actually _anything_) in registers, in some cases even if references are taken. I'm pretty sure LLVM can handle this. If you don't restrict the language people will write code that the optimizer will struggle with. So what? Using that argument, you could just as well forbid taking the address of any variable. What's so special about tuples, in contrast to structs and arrays? LLVM can only handle what goes on within a compilation unit, and not if there are stores, because those are visible in other threads. Tuples should be considered immutable constants (think functional programming), not in-memory storage. Again, why? Tuple's can serve as a good approximation to SIMD registers. What relation does that have to the above?
Re: Is this a bug in std.typecons.Tuple.slice?
On Tuesday, 9 February 2016 at 14:28:35 UTC, Ola Fosheim Grøstad wrote: On Tuesday, 9 February 2016 at 13:43:16 UTC, Marc Schütz wrote: So what? Using that argument, you could just as well forbid taking the address of any variable. What's so special about tuples, in contrast to structs and arrays? Some key common qualities for a tuple: 1. They are primarily used for multiple return values from functions. As you said, primarily. There's no reason not to use them for something else. 2. Tuples use structural typing, not nominal typing. This has no relevance for the question at hand. 3. They are identity-less. If you can take reference and compare, they no longer are identity-less. Like value types in general, nothing special about tuples here. Tuples should be considered immutable constants (think functional programming), not in-memory storage. Again, why? Because that is how a tuple is commonly defined, for performance and semantic reasons. I believe it's more because the concept is more frequently used in functional programming languages, for which immutability is not surprising. Other languages do have mutable tuples, e.g. Swift and C++11 (std::tuple). Tuple's can serve as a good approximation to SIMD registers. What relation does that have to the above? You don't want to spill out SIMD registers to the stack if you can avoid it. You want to do the changes within the CPU pipeline, i.e. using copies (and register renaming). As said above, wanting to avoid spilling is not a reason to disallow spilling. Besides, fixed-size arrays seem more similar to SIMD registers, and they don't have the restrictions you tuples to have.
Re: Is this a bug in std.typecons.Tuple.slice?
On Tuesday, 9 February 2016 at 09:05:58 UTC, Ola Fosheim Grøstad wrote: I suggest lobbying for proper builtin tuple support. Built-in tuple support would be great (although to my mind, mostly because the current syntax is clunky). But that is a long-term goal, and `Tuple.slice` is corrupting data *right now*. Some sort of short-term fix should be merged in the next release of D.
Re: Is this a bug in std.typecons.Tuple.slice?
On Wednesday, 10 February 2016 at 00:24:56 UTC, tsbockman wrote: [...] `Tuple.slice` is corrupting data *right now*. Some sort of short-term fix should be merged in the next release of D. +1
Re: Is this a bug in std.typecons.Tuple.slice?
Am Tue, 09 Feb 2016 00:38:10 + schrieb tsbockman: > On Sunday, 7 February 2016 at 02:11:15 UTC, Marco Leise wrote: > > What I like most about your proposal is that it doesn't break > > any existing code that wasn't broken before. That can't be > > emphasized enough. > > Although I wish more than 3 people had voted in my poll, two of > them did claim to need the `ref`-ness of `Tuple.slice`, so I > don't think we can just ditch it. (I did not vote.) > > If you guys want to add a return-by-value version, it should be > treated as an enhancement, not a bug fix in my opinion. As mentioned I never used the feature myself and wont vote for one or the other. Three people with no source code to exemplify current use of .slice! is indeed not much to base decisions on and both fixes yield unexpected results in different contexts that warrant bug reports. -- Marco
Re: Is this a bug in std.typecons.Tuple.slice?
On Sunday, 7 February 2016 at 02:11:15 UTC, Marco Leise wrote: What I like most about your proposal is that it doesn't break any existing code that wasn't broken before. That can't be emphasized enough. Although I wish more than 3 people had voted in my poll, two of them did claim to need the `ref`-ness of `Tuple.slice`, so I don't think we can just ditch it. (I did not vote.) If you guys want to add a return-by-value version, it should be treated as an enhancement, not a bug fix in my opinion.
Re: Is this a bug in std.typecons.Tuple.slice?
Am Sat, 06 Feb 2016 11:02:37 + schrieb tsbockman: > On Saturday, 6 February 2016 at 08:47:01 UTC, Saurabh Das wrote: > > I think we should add a static assert to slice to ensure that > > the current implementation is not used in a case where the > > alignment doesn't match. This is better than failing without > > any warning. > > If we pursue the deprecation route, I agree that this is a > necessary step. That would hurt the least, yes. It's more like a .dup with start and end parameter then. > > We could add new (differently named) functions for slicing > > non-aligned tuples. > > > > I agree that my approach of removing the ref may break existing > > code, so if introduced, it should be named differently. > > > > I am not comfortable with tuple(42, true, "abc").slice(1, 3) > > being different in type from tuple(true, " abc"). > > Why? What practical problem does this cause? For me it is mostly a gut feeling. Historically types mimicking other types have often evoked trouble for example in generic functions or concretely - if you look at my other post - in D's AA implementation. -- Marco
Re: Is this a bug in std.typecons.Tuple.slice?
On Sunday, 7 February 2016 at 02:51:49 UTC, tsbockman wrote: We should start a new thread in "General" to ask whether people care about the `ref`-ness of `Tuple` slices is really the deciding factor. I made a poll: http://forum.dlang.org/post/inswmiscuqirkhfql...@forum.dlang.org
Re: Is this a bug in std.typecons.Tuple.slice?
On Sunday, 7 February 2016 at 02:11:15 UTC, Marco Leise wrote: I understand that. We just have a different perspective on the problem. Your priorities: - don't break what's not broken - .slice! lends on opSlice and should return by ref My priorities: - type of .slice! should be as if constructing with same values from scratch - keep code additions in Phobos to a minimum Why do I insist on the return type? Because surprisingly simple code breaks if it doesn't match. Not everything can be covered by runtime conversions in D. I think the key question is, do users care about being able to modify the original `Tuple` instance indirectly through `slice`? If yes, then the only workable solutions I can see are: 1) My current proposal (insert a hidden padding member at the beginning of the slice `Tuple`) 2) Don't return a `Tuple` at all - return a dedicated `TupleSlice` type that is implicitly convertible to `Tuple`. This approach would work with the example you came up with, but implementing `TupleSlice` well could be very complex, I think. If not, then I have no fundamental objection to Saurabh Das' approach, although I think the PR needs work. We should start a new thread in "General" to ask whether people care about the `ref`-ness of `Tuple` slices is really the deciding factor.
Re: Is this a bug in std.typecons.Tuple.slice?
On Sunday, 7 February 2016 at 02:11:15 UTC, Marco Leise wrote: Why do I insist on the return type? Because surprisingly simple code breaks if it doesn't match. Not everything can be covered by runtime conversions in D. It still took me a while to come up with something obvious: uint[Tuple!(uint, ulong)] hash; auto tup = tuple(1u, 2u, 3UL); hash[tup.slice!(1, 3)] = tup[0]; compiles? works? original Tuple : yesno Saurabh Das changes: yesyes your changes : no no Thank you for the example. If multiple alias this ever makes it into the language (see https://wiki.dlang.org/DIP66 and https://github.com/D-Programming-Language/dmd/pull/3998), this could be fixed quite easily. But, I do not see any way to fix it with the tools currently available.
Re: Is this a bug in std.typecons.Tuple.slice?
On Sunday, 7 February 2016 at 02:51:49 UTC, tsbockman wrote: On Sunday, 7 February 2016 at 02:11:15 UTC, Marco Leise wrote: I understand that. We just have a different perspective on the problem. Your priorities: - don't break what's not broken - .slice! lends on opSlice and should return by ref My priorities: - type of .slice! should be as if constructing with same values from scratch - keep code additions in Phobos to a minimum Why do I insist on the return type? Because surprisingly simple code breaks if it doesn't match. Not everything can be covered by runtime conversions in D. I think the key question is, do users care about being able to modify the original `Tuple` instance indirectly through `slice`? If yes, then the only workable solutions I can see are: 1) My current proposal (insert a hidden padding member at the beginning of the slice `Tuple`) 2) Don't return a `Tuple` at all - return a dedicated `TupleSlice` type that is implicitly convertible to `Tuple`. This approach would work with the example you came up with, but implementing `TupleSlice` well could be very complex, I think. If not, then I have no fundamental objection to Saurabh Das' approach, although I think the PR needs work. The PR definitely needs work - it was proposed to outline the direction. I haven't worked at all on Phobos and I am not yet knowledgeable on writing library-quality code in D. I'm hoping to contribute back to Phobos this year - so pointing out as many flaws will help learn faster :) In particular - the inout problem in the PR - I'm not sure yet on how to fix that. Thanks, Saurabh We should start a new thread in "General" to ask whether people care about the `ref`-ness of `Tuple` slices is really the deciding factor.
Re: Is this a bug in std.typecons.Tuple.slice?
Am Sat, 06 Feb 2016 07:57:08 + schrieb tsbockman: > On Saturday, 6 February 2016 at 06:34:05 UTC, Marco Leise wrote: > > I don't want to sound dismissive, but when that thought came > > to my mind I considered it unacceptable that the type of > > Tuple!(int, bool, string).slice(1, 3) would be something > > different than Tuple!(bool, string). In your case > > Tuple!(TuplePad!4LU, bool, string). That's just a matter of > > least surprise when comparing the types. > > > > I'll let others decide, since I never used tuple slices. > > I'm not sure which approach is ultimately better, but aside from > the performance implications, your "needed change" could break a > lot of valid code in the wild - or it might break none; it really > just depends on whether anyone actually *uses* the `ref`-ness of > the `Tuple.slice` return type. True. > (It appears that Phobos, at least, does not. But there is no > guarantee that the rest of the world is using `Tuple` only in the > ways that Phobos does.) > Leaving aside bizarre meta-programming stuff (because then > *anything* is a breaking change), my PR does not break any code, > except that which was already broken: the type of the slice is > only different in those cases where it *has* to be, for alignment > reasons; otherwise it remains the same as it was before. I understand that. We just have a different perspective on the problem. Your priorities: - don't break what's not broken - .slice! lends on opSlice and should return by ref My priorities: - type of .slice! should be as if constructing with same values from scratch - keep code additions in Phobos to a minimum Why do I insist on the return type? Because surprisingly simple code breaks if it doesn't match. Not everything can be covered by runtime conversions in D. It still took me a while to come up with something obvious: uint[Tuple!(uint, ulong)] hash; auto tup = tuple(1u, 2u, 3UL); hash[tup.slice!(1, 3)] = tup[0]; compiles? works? original Tuple : yesno Saurabh Das changes: yesyes your changes : no no What I like most about your proposal is that it doesn't break any existing code that wasn't broken before. That can't be emphasized enough. -- Marco
Re: Is this a bug in std.typecons.Tuple.slice?
On Saturday, 6 February 2016 at 06:34:05 UTC, Marco Leise wrote: [...] I should also point out that, since there is no way to actually find out whether anyone is using the `ref`-ness of the return type in the wild, the approach that you and Saurabh Das are taking really ought to include changing the symbol name and deprecating the old one. Otherwise you could introduce subtle bugs into previously valid code; not every significant effect of removing `ref` will cause an error message at compile time *or* run time - some will just silently change the behaviour of the program, which is awful.
Re: Is this a bug in std.typecons.Tuple.slice?
On Saturday, 6 February 2016 at 06:34:05 UTC, Marco Leise wrote: I don't want to sound dismissive, but when that thought came to my mind I considered it unacceptable that the type of Tuple!(int, bool, string).slice(1, 3) would be something different than Tuple!(bool, string). In your case Tuple!(TuplePad!4LU, bool, string). That's just a matter of least surprise when comparing the types. I'll let others decide, since I never used tuple slices. I'm not sure which approach is ultimately better, but aside from the performance implications, your "needed change" could break a lot of valid code in the wild - or it might break none; it really just depends on whether anyone actually *uses* the `ref`-ness of the `Tuple.slice` return type. (It appears that Phobos, at least, does not. But there is no guarantee that the rest of the world is using `Tuple` only in the ways that Phobos does.) Leaving aside bizarre meta-programming stuff (because then *anything* is a breaking change), my PR does not break any code, except that which was already broken: the type of the slice is only different in those cases where it *has* to be, for alignment reasons; otherwise it remains the same as it was before.
Re: Is this a bug in std.typecons.Tuple.slice?
On Saturday, 6 February 2016 at 08:47:01 UTC, Saurabh Das wrote: I think we should add a static assert to slice to ensure that the current implementation is not used in a case where the alignment doesn't match. This is better than failing without any warning. If we pursue the deprecation route, I agree that this is a necessary step. We could add new (differently named) functions for slicing non-aligned tuples. I agree that my approach of removing the ref may break existing code, so if introduced, it should be named differently. I am not comfortable with tuple(42, true, "abc").slice(1, 3) being different in type from tuple(true, " abc"). Why? What practical problem does this cause?
Re: Is this a bug in std.typecons.Tuple.slice?
On Saturday, 6 February 2016 at 08:01:20 UTC, tsbockman wrote: On Saturday, 6 February 2016 at 06:34:05 UTC, Marco Leise wrote: [...] I should also point out that, since there is no way to actually find out whether anyone is using the `ref`-ness of the return type in the wild, the approach that you and Saurabh Das are taking really ought to include changing the symbol name and deprecating the old one. Otherwise you could introduce subtle bugs into previously valid code; not every significant effect of removing `ref` will cause an error message at compile time *or* run time - some will just silently change the behaviour of the program, which is awful. I think we should add a static assert to slice to ensure that the current implementation is not used in a case where the alignment doesn't match. This is better than failing without any warning. We could add new (differently named) functions for slicing non-aligned tuples. I agree that my approach of removing the ref may break existing code, so if introduced, it should be named differently. I am not comfortable with tuple(42, true, "abc").slice(1, 3) being different in type from tuple(true, " abc").
Re: Is this a bug in std.typecons.Tuple.slice?
Am Sat, 06 Feb 2016 04:28:17 + schrieb tsbockman: > On Friday, 5 February 2016 at 19:16:11 UTC, Marco Leise wrote: > >> > 1. Removing 'ref' from the return type > > > > Must happen. 'ref' only worked because of the reinterpreting > > cast which doesn't work in general. This will change the > > semantics. Now the caller of 'slice' will deal with a whole new > > copy of everything in the returned slice instead of a narrower > > view into the original data. But that's a needed change to fix > > the bug. > > Actually, it's not: > https://github.com/D-Programming-Language/phobos/pull/3973 > > All that is required is to include a little padding at the > beginning of the slice struct to make the alignments match. I don't want to sound dismissive, but when that thought came to my mind I considered it unacceptable that the type of Tuple!(int, bool, string).slice(1, 3) would be something different than Tuple!(bool, string). In your case Tuple!(TuplePad!4LU, bool, string). That's just a matter of least surprise when comparing the types. I'll let others decide, since I never used tuple slices. -- Marco
Re: Is this a bug in std.typecons.Tuple.slice?
Am Fri, 05 Feb 2016 05:31:15 + schrieb Saurabh Das: > On Friday, 5 February 2016 at 05:18:01 UTC, Saurabh Das wrote: > [...] > > Apologies for spamming. This is an improved implementation: > > @property > Tuple!(sliceSpecs!(from, to)) slice(size_t from, size_t > to)() @safe const > if (from <= to && to <= Types.length) > { > return typeof(return)(field[from .. to]); > } > > /// > unittest > { > Tuple!(int, string, float, double) a; > a[1] = "abc"; > a[2] = 4.5; > auto s = a.slice!(1, 3); > static assert(is(typeof(s) == Tuple!(string, float))); > assert(s[0] == "abc" && s[1] == 4.5); > > Tuple!(int, int, long) b; > b[1] = 42; > b[2] = 101; > auto t = b.slice!(1, 3); > static assert(is(typeof(t) == Tuple!(int, long))); > assert(t[0] == 42 && t[1] == 101); > } That's quite concise. I like this. Though 'field' is now called 'expand': // backwards compatibility alias field = expand; > These questions still remain: > > 1. Removing 'ref' from the return type Must happen. 'ref' only worked because of the reinterpreting cast which doesn't work in general. This will change the semantics. Now the caller of 'slice' will deal with a whole new copy of everything in the returned slice instead of a narrower view into the original data. But that's a needed change to fix the bug. > > 2. Adding 'const' to the function signature Hmm. Since const is transitive this may add const to stuff that wasn't const, like in a Tuple!(Object). When you call const slice on that, you would get a Tuple!(const(Object)). I would use inout, making it so that the tuple's original constness is propagated to the result. I.e.: @property inout(Tuple!(sliceSpecs!(from, to))) slice(size_t from, size_t to)() @safe inout > > 3. Is the new implementation less efficient for correctly > > aligned tuples? Yes, the previous one just added a compile-time known offset to the "this"-pointer. That's _one_ assembly instruction after inlining and optimization. The new one makes a copy of every field. On struct fields this can call the copy constructor "this(this)" which is used for example in reference counting to preform an increment for the copy. On "plain old data" it would simply copy the bit patterns. But that's obviously still less efficient than adding an offset to the pointer. You need two methods if you want to offer the best of both worlds. As soon as your function does not return a pointer or has 'ref' on it, the compiler will provide memory on the stack to hold the result and a copy will occur. That said, sufficiently smart compilers can analyze what's happening and come to the conclusion that when after the copy, the original is no longer used, they can be merged. > 4. @trusted -> @safe? Sounds good, but be aware of the mentioned implications with "this(this)". Copy constructors often need to do unsafe things, so @safe here would disallow them in Tuples. On the other hand recent versions of the front-end should infer attributes for templates, so you can generally omit them and "let the Tuple decide". This mechanism also already adds @nogc, pure, nothrow as possible in both the original and your implementation. (The original code only had @trusted on it because the compiler would always infer the safety as @system due to the pointer casts and @system is close to intolerable for a "high-level" functional programming feature such as tuples. The other attributes should have been inferred correctly.) -- Marco
Re: Is this a bug in std.typecons.Tuple.slice?
On Friday, 5 February 2016 at 19:16:11 UTC, Marco Leise wrote: > 1. Removing 'ref' from the return type Must happen. 'ref' only worked because of the reinterpreting cast which doesn't work in general. This will change the semantics. Now the caller of 'slice' will deal with a whole new copy of everything in the returned slice instead of a narrower view into the original data. But that's a needed change to fix the bug. Actually, it's not: https://github.com/D-Programming-Language/phobos/pull/3973 All that is required is to include a little padding at the beginning of the slice struct to make the alignments match.
Re: Is this a bug in std.typecons.Tuple.slice?
On Friday, 5 February 2016 at 19:16:11 UTC, Marco Leise wrote: Am Fri, 05 Feb 2016 05:31:15 + schrieb Saurabh Das: [...] That is enlightening. I have updated the PR at https://github.com/D-Programming-Language/phobos/pull/3975 to incorporate these changes.
Re: Is this a bug in std.typecons.Tuple.slice?
On Thursday, 4 February 2016 at 17:52:16 UTC, Marco Leise wrote: https://issues.dlang.org/show_bug.cgi?id=15645 Thank you. I understood why this is happening from your explanation in the bug report.
Re: Is this a bug in std.typecons.Tuple.slice?
On Thursday, 4 February 2016 at 12:28:39 UTC, Saurabh Das wrote: This code: [...] Update: Simplified, this also doesn't work: void main() { import std.typecons; auto tp = tuple(10, false, "hello"); auto u0 = tp.slice!(0, tp.length); auto u1 = tp.slice!(1, tp.length); auto u2 = tp.slice!(2, tp.length); static assert(is(typeof(u0) == Tuple!(int, bool, string))); static assert(is(typeof(u1) == Tuple!(bool, string))); static assert(is(typeof(u2) == Tuple!(string))); assert(u2[0] == "hello"); assert(u0[2] == "hello"); assert(u1[1] == "hello");// This fails } rdmd erasetype.d core.exception.AssertError@erasetype.d(16): Assertion failure Any ideas?
Re: Is this a bug in std.typecons.Tuple.slice?
On Thursday, 4 February 2016 at 17:52:16 UTC, Marco Leise wrote: https://issues.dlang.org/show_bug.cgi?id=15645 Is this a possible fixed implementation? : @property Tuple!(sliceSpecs!(from, to)) slice(size_t from, size_t to)() @trusted const if (from <= to && to <= Types.length) { auto sliceMixinGenerator() { string rv; for(auto i=from; i
Re: Is this a bug in std.typecons.Tuple.slice?
On Friday, 5 February 2016 at 05:18:01 UTC, Saurabh Das wrote: [...] Apologies for spamming. This is an improved implementation: @property Tuple!(sliceSpecs!(from, to)) slice(size_t from, size_t to)() @safe const if (from <= to && to <= Types.length) { return typeof(return)(field[from .. to]); } /// unittest { Tuple!(int, string, float, double) a; a[1] = "abc"; a[2] = 4.5; auto s = a.slice!(1, 3); static assert(is(typeof(s) == Tuple!(string, float))); assert(s[0] == "abc" && s[1] == 4.5); Tuple!(int, int, long) b; b[1] = 42; b[2] = 101; auto t = b.slice!(1, 3); static assert(is(typeof(t) == Tuple!(int, long))); assert(t[0] == 42 && t[1] == 101); } These questions still remain: 1. Removing 'ref' from the return type 2. Adding 'const' to the function signature 3. Is the new implementation less efficient for correctly aligned tuples? 4. @trusted -> @safe?
Re: Is this a bug in std.typecons.Tuple.slice?
On Friday, 5 February 2016 at 05:18:01 UTC, Saurabh Das wrote: [...] PS: Additionally, '@trusted' can now be substituted with '@safe'.
Re: Is this a bug in std.typecons.Tuple.slice?
https://issues.dlang.org/show_bug.cgi?id=15645
Re: Is this a bug in std.typecons.Tuple.slice?
Am Thu, 04 Feb 2016 15:17:54 + schrieb Saurabh Das: > On Thursday, 4 February 2016 at 12:28:39 UTC, Saurabh Das wrote: > > This code: > > [...] > > Update: Simplified, this also doesn't work: > > void main() > { > import std.typecons; > auto tp = tuple(10, false, "hello"); > > auto u0 = tp.slice!(0, tp.length); > auto u1 = tp.slice!(1, tp.length); > auto u2 = tp.slice!(2, tp.length); > > static assert(is(typeof(u0) == Tuple!(int, bool, string))); > static assert(is(typeof(u1) == Tuple!(bool, string))); > static assert(is(typeof(u2) == Tuple!(string))); > > assert(u2[0] == "hello"); > assert(u0[2] == "hello"); > assert(u1[1] == "hello");// This fails > } > > rdmd erasetype.d > core.exception.AssertError@erasetype.d(16): Assertion failure > > Any ideas? Yes this is a clear bug, I'll report a bug and post the issue number later. -- Marco