Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 04, 2011 Re: So how exactly does one make a persistent range object? | ||||
---|---|---|---|---|
| ||||
Ok, this works: shared Cycle!(int[]) range; So, problem solved? Sometimes I feel like I should just e-mail myself and then give myself the answer instead of posting here. LOL. |
June 05, 2011 Re: So how exactly does one make a persistent range object? | ||||
---|---|---|---|---|
| ||||
Problem not so much solved. What if I want to keep a stride range? There's no Stride struct defined in std.range, stride() is defined as an auto function and hides the type inside the function itself. How I can store such an object in module scope? This won't work: auto var = stride([1, 2, 3], 2); This prints out a couple of hundred lines of text as an error message followed by "not implemented yet in CTFE". |
June 05, 2011 Re: So how exactly does one make a persistent range object? | ||||
---|---|---|---|---|
| ||||
On 2011-06-04 18:01, Andrej Mitrovic wrote:
> Problem not so much solved.
>
> What if I want to keep a stride range? There's no Stride struct defined in std.range, stride() is defined as an auto function and hides the type inside the function itself.
>
> How I can store such an object in module scope? This won't work:
>
> auto var = stride([1, 2, 3], 2);
>
> This prints out a couple of hundred lines of text as an error message followed by "not implemented yet in CTFE".
The problem here is likely because var _must_ be known at compile time when you initialize it directly, and stride apparently doesn't work with CTFE. I believe that it's the case that _most_ range-based functions don't work with CTFE yet. So, you'll need to initialize it in a module constructor. So, to get the type, you'll probably need to do something like
typeof(stride([1, 2, 3], 2)) var;
- Jonathan M Davis
|
June 05, 2011 Re: So how exactly does one make a persistent range object? | ||||
---|---|---|---|---|
| ||||
Ah the good old typeof. It's nice to have language sugar like this that save the day. :) |
June 05, 2011 Re: So how exactly does one make a persistent range object? | ||||
---|---|---|---|---|
| ||||
On 2011-06-05 09:43, Andrej Mitrovic wrote:
> Ah the good old typeof. It's nice to have language sugar like this that save the day. :)
I really don't think that Andrei was thinking that people would need to save ranges when he started internalizing all of the range types in std.range and std.algorithm. So, it _is_ a bit annoying for this particular use case. But for everything else, it's a definite improvement. There are fewer names in the namespace and it completely hides the type, highlighting that no one should care about what the return type really is (which is one of the things that seems to definitely scare newbie to std.algorithm - thank goodness for auto). So, as long as it's possible to still save ranges with typeof and whatnot, I'd expect that Andrei is going to want to make it so that _all_ functions which have their own range type just for returning have that type be internal to the function and effectively nameless.
- Jonathan M Davis
|
June 06, 2011 Re: So how exactly does one make a persistent range object? | ||||
---|---|---|---|---|
| ||||
On 6/6/11, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> I really don't think that Andrei was thinking that people would need to save ranges when he started internalizing all of the range types in std.range and std.algorithm.
There are some classes like InputRangeObject defined in std.range that might be used to store a general-purpose range, but they're annotated with some comments about various bugs they have. I gave that a try a while ago, but it's a pain to make it work at all.
Well.. D is a very compile-time-oriented language, as opposed to one that's focused more on runtime features. Nothing bad about that, but flexibility at runtime can be nice to have. Ranges seem to be focused on the programmer's needs, and not something you can let the user play with at runtime too much.
|
June 06, 2011 Re: So how exactly does one make a persistent range object? | ||||
---|---|---|---|---|
| ||||
On 2011-06-05 17:19, Andrej Mitrovic wrote:
> On 6/6/11, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> > I really don't think that Andrei was thinking that people would need to save ranges when he started internalizing all of the range types in std.range and std.algorithm.
>
> There are some classes like InputRangeObject defined in std.range that might be used to store a general-purpose range, but they're annotated with some comments about various bugs they have. I gave that a try a while ago, but it's a pain to make it work at all.
>
> Well.. D is a very compile-time-oriented language, as opposed to one that's focused more on runtime features. Nothing bad about that, but flexibility at runtime can be nice to have. Ranges seem to be focused on the programmer's needs, and not something you can let the user play with at runtime too much.
??? I'm afraid that I don't follow. Ranges are generally templated rather than polymorphic, so their types tend to need to be dealt with explicitly unless using auto. Is that what you mean by runtime features? Most everything about types in a statically-typed is a compile time issue. Polymorphism and runtime reflections are just about the only stuff which isn't. And do you mean the users of Phobos or the users of programs written in D? I'm afraid that I'm totally missing your train of thought here, so I'm not quite sure what you're trying to say.
- Jonathan M Davis
|
June 06, 2011 Re: So how exactly does one make a persistent range object? | ||||
---|---|---|---|---|
| ||||
Yeah I'm referring to polymorphism. If I want to provide some sort of interface for my users that let them build any type of range at runtime, or even a range of ranges, then there's polymorphism involved. Other than polymorphism there's no other way a function can take or return a generic range type at runtime without know its exact type at compile-time. Of course a polymorphic range of ranges is going to be a performance bottleneck due to virtual function calls, so it doesn't make sense for ranges to be polymorphic in the first place. I don't have a real use-case for these kinds of runtime-manipulated range types yet. I'd have to build something before I could make some kind of a case for them. So I'm really just speculating on what I need, and I'm experimenting with what ranges have to offer. I'll see how far I can go with the typeof() trick. :) |
June 06, 2011 Re: So how exactly does one make a persistent range object? | ||||
---|---|---|---|---|
| ||||
On 2011-06-05 17:47, Andrej Mitrovic wrote:
> Yeah I'm referring to polymorphism.
>
> If I want to provide some sort of interface for my users that let them build any type of range at runtime, or even a range of ranges, then there's polymorphism involved. Other than polymorphism there's no other way a function can take or return a generic range type at runtime without know its exact type at compile-time.
>
> Of course a polymorphic range of ranges is going to be a performance bottleneck due to virtual function calls, so it doesn't make sense for ranges to be polymorphic in the first place.
>
> I don't have a real use-case for these kinds of runtime-manipulated range types yet. I'd have to build something before I could make some kind of a case for them. So I'm really just speculating on what I need, and I'm experimenting with what ranges have to offer. I'll see how far I can go with the typeof() trick. :)
Well, iterators aren't generally polymorphic beyond perhaps dealing with the fact that the container that they iterate over is polymorphic (which happens in Java and C#, but not standard C++). However, ranges can obviously be used for rather more than iterators, so that complicates things.
Ranges _can_ be polymorphic (forward ranges' save function makes it possible to deal with ranges which are class types), but Phobos' ranges aren't polymorphic. So, anything you do on your own could be polymorphic, but as soon as you get ranges from Phobos, you lose the polymorphism. But in the vast majority of cases, I don't expect that that will be an issue at all. What you'll likely be forced to do in some cases is copy a range's values into a new container, but that's exactly what you generally have to do in C++, Java, and C# anyway. So, it's not really much of a loss.
On the whole, I believe that ranges were generally intended to be processed and then tossed, which is usually what happens with iterators, so the sorts of issues that you're talking about are a bit out of the norm. People do keep iterators and ranges around some of the time, but generally, if they want to keep that data long term, they put it in a new container - particularly when you consider the fact that so many iterators and ranges can change out from under you.
- Jonathan M Davis
|
June 06, 2011 Re: So how exactly does one make a persistent range object? | ||||
---|---|---|---|---|
| ||||
On 6/6/11, Jonathan M Davis <jmdavisProg@gmx.com> wrote: > On the whole, I believe that ranges were generally intended to be processed and then tossed, which is usually what happens with iterators.. That's what I thought but wasn't sure if that was really the case. I don't really have a solid C++ background (I've only had a brief experiment with C++ years ago), and so I've never used iterators. But I did read Andrei's paper on ranges, and the documentation in std.range, plus there are some NG posts which show the inception of the range implementation for D, which I haven't fully read yet. I'm referring to these: http://www.digitalmars.com/d/archives/digitalmars/D/announce/RFC_on_range_design_for_D2_12922.html http://www.digitalmars.com/d/archives/digitalmars/D/announce/Revised_RFC_on_range_design_for_D2_13211.html They seem like a nice bit of history that could be linked from the main site, in some sort of 'trivia' section. :) On 6/6/11, Jonathan M Davis <jmdavisProg@gmx.com> wrote: > So, anything you do on your own could be polymorphic, but as soon as you get ranges from Phobos, you lose the polymorphism. Yeah, I've noticed that. I wouldn't want to loose the ability to call into std.algorithm/std.range or even Philippe's dranges library, which looks really neat. I guess I can use take() on a range and then array() to get the underlying type which I could easily pass to other functions. I'll see what I can come up with as I experiment with these features. |
Copyright © 1999-2021 by the D Language Foundation