View mode: basic / threaded / horizontal-split · Log in · Help
April 14, 2009
Re: The new, new phobos sneak preview
Andrei Alexandrescu wrote:
> Daniel Keep wrote:
>> ...
> 
> So essentially we're looking at a symbolic approach - a resumable range
> would need to advertise that. I've used that for isSorted too, and it
> works pretty well.
> 
> The remaining question is one of defaults - are most ranges resumable or
> not? I.e., should a range advertise explicitly when it's resumable or
> when it's *not* resumable? I think the safe approach is to go as you
> say: a range ain't resumable unless it explicitly claims to. So if you
> forget stuff, the compiler will remind you.
> 
> I'd love to hear more opinions on the topic.
> 
> 
> Andrei

Actually, I stuffed up the test; I wanted the default to be resumable.
:P  That'll teach me to not double-check my logic.  A quick truth table
later, and the correct test is this:

> template isResumableRange(R)
> {
>     enum bool isResumableRange = isInputRange!(R)
>         && (!is(typeof(R.isResumableRange))
>             || (is(typeof(R.isResumableRange)) && R.isResumableRange))
>         && is(typeof(
>         {
>             R r1;
>             R r2 = r1;
>         }()));
> }

... I think.  :P

Actually, I've been thinking and I realised that in 95% of cases, you
can assume a range is resumable if it has no references.  If it has no
references, the only way the range can be non-resumable is if the
advance member uses the range's state as an argument to some global
method.  An example might be a Range that statically accesses Stdout
instead of taking it as an argument.

It's a real shame the range interface doesn't support this:

> struct R
> {
>     ...
>     pure R advance();
> }

If it did, we could prove a range was resumable if advance was pure and
R has no mutable or const references.

Honestly, I think the safest option is to *require* resuming to be
explicitly stated by the programmer.  It'd be nice if we could
automatically account for some cases, but I can't think of any you
couldn't escape from.

Maybe we should default to non-resumable for now, then re-visit the
issue when we have an idea of how people are using ranges.

 -- Daniel
April 14, 2009
Re: The new, new phobos sneak preview
Daniel Keep wrote:
> Actually, I've been thinking and I realised that in 95% of cases, you
> can assume a range is resumable if it has no references.

Well I'm not so sure. How about a range around an integral file handle 
or socket?

> If it has no
> references, the only way the range can be non-resumable is if the
> advance member uses the range's state as an argument to some global
> method.  An example might be a Range that statically accesses Stdout
> instead of taking it as an argument.
> 
> It's a real shame the range interface doesn't support this:
> 
>> struct R
>> {
>>     ...
>>     pure R advance();
>> }
> 
> If it did, we could prove a range was resumable if advance was pure and
> R has no mutable or const references.

Hmmmm... well, pure changes "this". We'd need to say that it only 
changes state owned by "this", but we have no notion of "almost pure".

> Honestly, I think the safest option is to *require* resuming to be
> explicitly stated by the programmer.  It'd be nice if we could
> automatically account for some cases, but I can't think of any you
> couldn't escape from.
> 
> Maybe we should default to non-resumable for now, then re-visit the
> issue when we have an idea of how people are using ranges.

I agree. Probably I'll do that, thanks.

By the way, Walter and I both changed the names of the members to what 
everybody seemed to liked best: front, back, popFront, popBack. No more 
heads and toes.


Andrei
April 14, 2009
Re: The new, new phobos sneak preview
Andrei Alexandrescu wrote:
> Daniel Keep wrote:
>> Actually, I've been thinking and I realised that in 95% of cases, you
>> can assume a range is resumable if it has no references.
> 
> Well I'm not so sure. How about a range around an integral file handle 
> or socket?

If ranges can advertise their resumability, it wouldn't be hard to write 
a simple template wrapper that provides resumability to an underlying 
non-resumable range.

--benji
April 14, 2009
Re: The new, new phobos sneak preview
Andrei Alexandrescu wrote:
> Daniel Keep wrote:
>> Actually, I've been thinking and I realised that in 95% of cases, you
>> can assume a range is resumable if it has no references.
> 
> Well I'm not so sure. How about a range around an integral file handle
> or socket?

Most of the time, I'd expect people to be accessing those via the
standard library.  And that wraps them in objects.  :)

>> If it has no
>> references, the only way the range can be non-resumable is if the
>> advance member uses the range's state as an argument to some global
>> method.  An example might be a Range that statically accesses Stdout
>> instead of taking it as an argument.
>>
>> It's a real shame the range interface doesn't support this:
>>
>>> struct R
>>> {
>>>     ...
>>>     pure R advance();
>>> }
>>
>> If it did, we could prove a range was resumable if advance was pure and
>> R has no mutable or const references.
> 
> Hmmmm... well, pure changes "this". We'd need to say that it only
> changes state owned by "this", but we have no notion of "almost pure".

Hence why I made R a return value.  If you have a member function that's
pure in every way EXCEPT that it changes "this", you can rewrite it like so:

> R range = getRange();
> range = range.advance;

Ta-da, advance can be pure since the changes are pushed out via the
return value.  In other words,

> struct R(T)
> {
>     pure bool empty();
>     pure T head();
>     pure R!(T) advance();
> }

is a pure, guaranteed safe-to-resume version of this:

> struct R(T)
> {
>     bool empty();
>     T head();
>     void advance();
> }

The only difference is that instead of writing this:

> for( auto v = r.head; !r.empty; r.advance ) ...

You'd write this:

> for( auto v = r.head; !r.empty; r = r.advance ) ...

>> Honestly, I think the safest option is to *require* resuming to be
>> explicitly stated by the programmer.  It'd be nice if we could
>> automatically account for some cases, but I can't think of any you
>> couldn't escape from.
>>
>> Maybe we should default to non-resumable for now, then re-visit the
>> issue when we have an idea of how people are using ranges.
> 
> I agree. Probably I'll do that, thanks.
> 
> By the way, Walter and I both changed the names of the members to what
> everybody seemed to liked best: front, back, popFront, popBack. No more
> heads and toes.
> 
> 
> Andrei

Cool.  I really can't wait to dive into this stuff.  There are a few
things I've been wanting to write in D2 that I'm holding off until the
range stuff is done so I can give it a workout.

 -- Daniel
April 14, 2009
Re: The new, new phobos sneak preview
On 2009-04-13 22:28:33 -0400, Benji Smith <dlanguage@benjismith.net> said:

> Andrei Alexandrescu wrote:
>> Daniel Keep wrote:
>>> Actually, I've been thinking and I realised that in 95% of cases, you
>>> can assume a range is resumable if it has no references.
>> 
>> Well I'm not so sure. How about a range around an integral file handle 
>> or socket?
> 
> If ranges can advertise their resumability, it wouldn't be hard to 
> write a simple template wrapper that provides resumability to an 
> underlying non-resumable range.

If the language supported making an struct non-copyable, you could use this.

Actually, using a class for a non-resumable range would already acheive 
this (you'd only be copying references). So perhaps you could consider 
a class used as a range as non-resumable, and use classes for 
non-resumable ranges.

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/
Next ›   Last »
6 7 8 9 10
Top | Discussion index | About this forum | D home