View mode: basic / threaded / horizontal-split · Log in · Help
July 10, 2012
Re: Why is std.algorithm so complicated to use?
"Christophe Travert" <travert@phare.normalesup.org> wrote in message 
news:jthmu8$2s5b$1@digitalmars.com...
> "Daniel Murphy" , dans le message (digitalmars.D:171720), a écrit :
>> Could it be extended to accept multiple values? (sort of like chain)
>> eg.
>> foreach(x; makeRange(23, 7, 1990)) // NO allocations!
>> {
>>     ....
>> }
>> I would use this in a lot of places I currently jump through hoops to get 
>> a
>> static array without allocating.
>
> That's a good idea. IMHO, the real solution would be to make an easy way
> to create static arrays, and slice them when you want a range.
>

It's not quite the same thing, static arrays are not ranges and once you 
slice them you no longer have a value type, and might be referring to stack 
allocated data.  With... this thing, the length/progress is not encoded in 
the type (making it rangeable) but the data _is_ contained in the type, 
making it safe to pass around.  The best of both worlds, in some situations.

An easy way to get static arrays would be great too.

>
> I it were just me, array litterals would be static, and people
> should use .dup when they want a a surviving slice.
>

It used to be like that.  Most of the time you don't really want a static 
array.
July 10, 2012
Re: Why is std.algorithm so complicated to use?
Jacob Carlborg , dans le message (digitalmars.D:171739), a écrit :
> On 2012-07-10 18:42, Daniel Murphy wrote:
>> "Jacob Carlborg" <doob@me.com> wrote in message
>> news:jthlpf$2pnb$1@digitalmars.com...
>>>
>>> Can't "map" and "filter" return a random-access range if that's what they
>>> receive?
>>>
>> map can, and does.
> 
> It doesn't seem to:
> 
> auto a = [3, 4].map!(x => x);
> auto b = a.sort;
> 
> Result in one of the original errors I started this thread with.

here, map is random-access. But random access is not enough to call 
sort: you need to have assignable (well, swapable) elements in the 
range, if you want to be able to sort it. values accessed via a map are 
not always assignable, since they are the result of a function.

It seems the map resulting from (x => x) is not assignable. This is 
debatable, but since (x => x) is just a stupid function to test. 
Otherwise, you could try the folowing:

auto a = [3, 4].map!(ref int (ref int x) { return x; })();
a.sort;
July 10, 2012
Re: Why is std.algorithm so complicated to use?
"Jacob Carlborg" <doob@me.com> wrote in message 
news:jthnlo$2tjg$1@digitalmars.com...
> On 2012-07-10 18:42, Daniel Murphy wrote:
>> "Jacob Carlborg" <doob@me.com> wrote in message
>> news:jthlpf$2pnb$1@digitalmars.com...
>>>
>>> Can't "map" and "filter" return a random-access range if that's what 
>>> they
>>> receive?
>>>
>> map can, and does.
>
> It doesn't seem to:
>
> auto a = [3, 4].map!(x => x);
> auto b = a.sort;
>
> Result in one of the original errors I started this thread with.
>
> -- 
> /Jacob Carlborg
>
>

writeln([1, 2, 3].map!"a"()[2]);

Sort is in place, and therefore requires more than random access, you need 
to be able to modify the data you're operating on.

Something like [3, 4].map!func().selectionSort() could work lazily without 
needing to modify the original range, but urrgh.
July 10, 2012
Re: Why is std.algorithm so complicated to use?
On Tuesday, July 10, 2012 18:57:25 Jacob Carlborg wrote:
> On 2012-07-10 16:36, Dmitry Olshansky wrote:
> > typeof to the rescue. In fact I'm not so proud of voldemort types. As
> > when you need to sotre range somewhere they stand in your way for no
> > benefit.
> 
> I'm not exactly sure how you mean but this is what I came up with:
> 
> import std.algorithm;
> import std.traits;
> import std.conv;
> 
> class Foo
> {
> auto bar ()
> {
> return [3, 4].map!(x => x.to!(string));
> }
> 
> ReturnType!(bar) x;
> }


typeof(bar()) x;

works. But regardless, given that you're dealing with a return type which is 
auto, there's really no other choice. Even if we weren't using voldemort types 
for stuff like map, the return type would still be templated and depend on the 
actual arguments to map, making writing the type a pain - especially if it's 
complicated; until (which _doesn't_ use a voldemort type) is a prime example 
of this. You end up with something like Until!("a == b",int[],int) for a basic 
call to until, and it gets really nasty if you start chaining function calls 
so that the range passed to Until is far more complicated than int[]. Using 
ReturnType and typeof becames the sane thing to do (and much more maintainable 
too, since you don't have to change it if/when you change the call to map 
enough that it's return type changes). It does take some getting used to, but 
it works very well. You just have to realize that if you're operating on 
ranges, you're generally _not_ caring what they exact type is, and you use 
auto and templates a lot. Sometimes converting the result to an array is 
exactly what you want to do, but the less you do that, the more efficient your 
code will be.

- Jonathan M Davis
July 10, 2012
Re: Why is std.algorithm so complicated to use?
On Tuesday, July 10, 2012 12:22:30 Andrei Alexandrescu wrote:
> On 7/10/12 12:01 PM, Christophe Travert wrote:
> > Andrei Alexandrescu , dans le message (digitalmars.D:171717), a écrit :
> >> auto singletonRange(E)(E value)
> >> {
> >> 
> >> return repeat(value).takeExactly(1);
> >> 
> >> }
> > 
> > It would be much better to use:
> > 
> > auto singletonRange(E)(E value)
> > {
> > 
> > return repeat(value).takeOne;
> > 
> > }
> > 
> > as well as:
> > 
> > auto emptyRange(E)(E value)
> > {
> > 
> > return repeat(value).takeNone;
> > 
> > }
> > 
> > to have the advantages of takeOne and takeNone over takeExactly.
> 
> Ah, such as them being random access. Cool!
> 
> That also seems to answer Jonathan's quest about defining emptyRange.
> Just use takeNone(R.init).

Actually, it doesn't, because find needs the ability to get an empty range of 
the exact same type as the original. It's a nice idea for cases where the 
resultant range doesn't matter though.

- Jonathan M Davis
July 10, 2012
Re: Why is std.algorithm so complicated to use?
On Tuesday, July 10, 2012 14:27:14 Simen Kjaeraas wrote:
> On Tue, 10 Jul 2012 09:04:31 +0200, Jonathan M Davis <jmdavisProg@gmx.com>
> 
> wrote:
> > The problem is that map is lazy, so it can't be a random access range,
> 
> Sure it can. If the underlying range is random-access or bidirectional,
> so can map be. What can't be (as easily) done is caching of elements.

Ah, you're right. I'm too used to thinking about filter, but map doesn't change 
the number of elements, so it works just fine as random access (though it risks 
being an efficient way of doing things if the function using it accessing its 
elements multiple times, since it's going to have to call the predicate every 
time that the element is accessed, whereas if you just iterate over the range, 
then odds are that you only access the element once).

- Jonathan M Davis
July 10, 2012
Re: Why is std.algorithm so complicated to use?
"Daniel Murphy" , dans le message (digitalmars.D:171741), a écrit :
> "Christophe Travert" <travert@phare.normalesup.org> wrote in message 
> news:jthmu8$2s5b$1@digitalmars.com...
>> "Daniel Murphy" , dans le message (digitalmars.D:171720), a écrit :
>>> Could it be extended to accept multiple values? (sort of like chain)
>>> eg.
>>> foreach(x; makeRange(23, 7, 1990)) // NO allocations!
>>> {
>>>     ....
>>> }
>>> I would use this in a lot of places I currently jump through hoops to get 
>>> a
>>> static array without allocating.
>>
>> That's a good idea. IMHO, the real solution would be to make an easy way
>> to create static arrays, and slice them when you want a range.
> 
> It's not quite the same thing, static arrays are not ranges and once you 
> slice them you no longer have a value type, and might be referring to stack 
> allocated data.  With... this thing, the length/progress is not encoded in 
> the type (making it rangeable) but the data _is_ contained in the type, 
> making it safe to pass around.  The best of both worlds, in some situations.

OK, I see. This goes against the principle that ranges are small and 
easy to copy arround, but it can be useful when you know what you are 
doing, or when the number of items is small.

I don't like makeRange much. Would you have a better name? smallRange? 
rangeOf?
July 10, 2012
Re: Why is std.algorithm so complicated to use?
"Christophe Travert" <travert@phare.normalesup.org> wrote in message 
news:jthp14$30em$1@digitalmars.com...
> "Daniel Murphy" , dans le message (digitalmars.D:171741), a écrit :
>> "Christophe Travert" <travert@phare.normalesup.org> wrote in message
>> news:jthmu8$2s5b$1@digitalmars.com...
>>> "Daniel Murphy" , dans le message (digitalmars.D:171720), a écrit :
>>>> Could it be extended to accept multiple values? (sort of like chain)
>>>> eg.
>>>> foreach(x; makeRange(23, 7, 1990)) // NO allocations!
>>>> {
>>>>     ....
>>>> }
>>>> I would use this in a lot of places I currently jump through hoops to 
>>>> get
>>>> a
>>>> static array without allocating.
>>>
>>> That's a good idea. IMHO, the real solution would be to make an easy way
>>> to create static arrays, and slice them when you want a range.
>>
>> It's not quite the same thing, static arrays are not ranges and once you
>> slice them you no longer have a value type, and might be referring to 
>> stack
>> allocated data.  With... this thing, the length/progress is not encoded 
>> in
>> the type (making it rangeable) but the data _is_ contained in the type,
>> making it safe to pass around.  The best of both worlds, in some 
>> situations.
>
> OK, I see. This goes against the principle that ranges are small and
> easy to copy arround, but it can be useful when you know what you are
> doing, or when the number of items is small.
>

Yeah, it works where you'd pass a tuple of elements of the same type, but 
want to iterate over it.

> I don't like makeRange much. Would you have a better name? smallRange?
> rangeOf?
>
>
rangeit
July 10, 2012
Re: Why is std.algorithm so complicated to use?
On Tue, 10 Jul 2012 16:15:09 +0200, Jacob Carlborg <doob@me.com> wrote:

> On 2012-07-10 14:53, Dmitry Olshansky wrote:
>
>> Too bad, as there is no need to make an array when you map something.
>
> How do you store your ranges in a struct or class? Most of them are  
> voldemort types.

Well, there is std.range.inputRangeObject, but as the name indicates, it's
only an input range.


>> "
>> Iterates unique consecutive elements of the given range (functionality
>> akin to the uniq system utility). Equivalence of elements is assessed by
>> using the predicate pred, by default "a == b". If the given range is
>> bidirectional, uniq also yields a bidirectional range.
>> "
>> Though it doesn't explicitly mentions it, the example is:
>
> Yes, exactly.
>
>> int[] arr = [ 1, 2, 2, 2, 2, 3, 4, 4, 4, 5 ];
>> assert(equal(uniq(arr), [ 1, 2, 3, 4, 5 ][]));
>
> How should I know that from the example?

You shouldn't. The description however, says 'unique consecutive elements',
which *does* explain it.

-- 
Simen
July 10, 2012
Re: Why is std.algorithm so complicated to use?
On 7/10/12 12:38 PM, Jacob Carlborg wrote:
> Can't "map" and "filter" return a random-access range if that's what
> they receive?

(replied to by others)

>> Now I understand if you come from a place where there's no concern over
>> hidden allocations and extra work for the benefit of convenience, you
>> may find std.algorithm less easy to work with. But drawing the
>> conclusion that std.algorithm is badly designed or gratuitously
>> difficult to use would be a mistake. I opine I can recognize a good vs.
>> bad design even when it's mine, and in my opinion std.algorithm is a
>> good design and that most of your opposing impressions derive from a
>> misunderstanding of its charter.
>
> I don't think I've struggled as much with any other API I've used. In
> many cases I had to resort to foreach-loops because that was more
> convenient than using std.algorithm.

That's fine. I don't see std.algorithm as a competitor against simple 
loops, but instead of work that would be very verbose and difficult to 
do with loops. I mean I clearly recall at a point I wanted to define a 
forAll algorithm, but then I was like, "people can use foreach for that".

Andrei
5 6 7 8 9 10 11 12 13
Top | Discussion index | About this forum | D home