www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - opDollar and infinite slices on infinite ranges

reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
Hi,

I'm trying to find a way to have infinite slices for some infinite ranges.
Like this:

MyInfiniteRange ir;
auto slice1 = ir[2..5]; // standard slice, just define opSlice(i,j) in
MyInfiniteRange. It's a finite range.
auto slice2 = ir[2..$];
'$' means: up to the end. So, it's a semi-infinite slice: I want slice2 to be
an infinite range.
In fact, it should be equivalent to drop(ir, 2) where drop(range, n) drops the
first n elements of range and returns the shortened range.

And also:
auto slice3 = ir[2..$/100-1_000_000]; // the very same, a semi-infinite slice.

My google-fu is weak, I cannot find any indication on opDollar and how to
define it, for D2. So, maybe someone here can help me? Can someone points me
to some documentation?

Right now, here is where I am. Let say I defined opDollar for MyInfiniteRange.
What I want is this:

- the returned value must be some kind of 'integral infinity': ie, it must be
bigger than any other possible index: opCmp should return a positive amount,
whatever integral I throw at it.
- the returned value must allow simple arithmetic operations with integral
types, to allow for '$/2-100'-like expressions. So operations like +,-,*,/ and
% (maybe even ^^) must work. But the result must be also 'infinite' most of
the time. So it's a value that will gobble most operations and most operands
and returns itself unchanged.
- adding or removing any (finite) integral amount must give back this integral
infinity.
- multiplying or dividing by most amounts also.
- multiplying it by 0 should give... an Exception, I suppose? Also, I'm not
clear on ir[0 .. $-$]. Is '$-$' even defined? What about $/$? My gut feeling
is not to authorize such operations, as they are mathematically dodgy. So $+$
is OK, $*$ also, but not the negative operations.
- multiplying it by a negative amount should make it a negative infinity, I
guess... Though I'm not interested there, for indexing.
- in MyIntegralRange, opSlice should be an overload: opSlice(size_t i1, size_t
i2) and opSlice(size_t i1, IntegralInfinity i2), the latter just returns
drop(this, i1).

So, I'm about to define a struct called IntegralInfinity to extend operations
on integral types, with just a boolean flag isPositive, and then lots of
operator overloading. Is that the right way to do it?

As an afterthought, this does not allow slices like ir[$/2..$] or
ir[$-100..$], but I think these should not exist: if ir is truly infinite, I
don't know what ir[$/2..$] is...


Philippe
Jul 17 2010
parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Sat, Jul 17, 2010 at 22:01, Philippe Sigaud <philippe.sigaud gmail.com>wrote:

 My google-fu is weak, I cannot find any indication on opDollar and how to
 define it, for D2. So, maybe someone here can help me? Can someone points
 me
 to some documentation?
No, no one knows something about opDollar and how to define it? Pretty please? Philippe
Jul 18 2010
next sibling parent reply "Robert Jacques" <sandford jhu.edu> writes:
On Sun, 18 Jul 2010 17:48:56 -0400, Philippe Sigaud  
<philippe.sigaud gmail.com> wrote:

 On Sat, Jul 17, 2010 at 22:01, Philippe Sigaud  
 <philippe.sigaud gmail.com>wrote:

 My google-fu is weak, I cannot find any indication on opDollar and how  
 to
 define it, for D2. So, maybe someone here can help me? Can someone  
 points
 me
 to some documentation?
No, no one knows something about opDollar and how to define it? Pretty please? Philippe
A well designed opDollar is still an enhancement request: http://d.puremagic.com/issues/show_bug.cgi?id=3474. However, there is a hack to get $ to return a value. Unfortunately, I've lost that newsgroup post. Memory got me this code snippet: struct Bar { int opIndex(int i) { writeln(i); return i; } } int __dollar() { return 5;} void main(string[] args) { Bar b; b[$]; }
Jul 18 2010
parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Mon, Jul 19, 2010 at 03:03, Robert Jacques <sandford jhu.edu> wrote:


 A well designed opDollar is still an enhancement request:
 http://d.puremagic.com/issues/show_bug.cgi?id=3474.
Ah, OK.
 However, there is a hack to get $ to return a value. Unfortunately, I've
 lost that newsgroup post.

 I got some May discussion about ^ and $ and a thread about opDollar for
multidimensional arrays, but couldn't find any concrete things on opDollar. Strange, I thought that was part of DMD for a dozen releases. I guess, I'm wrong, then :)
 Memory got me this code snippet:


 struct Bar {
    int opIndex(int i) { writeln(i); return i; }

 }
 int __dollar() { return 5;}


 void main(string[] args) {
    Bar b;
    b[$];
 }
It works, but in this case $ is global symbol, defined outside Bar. If I put it inside the struct, the compiler complains about __dollar being undefined. Oh well, I'll push slices away from now, and use drop. Too bad, that would have make some parts more elegant. Thanks Robert, Philippe
Jul 19 2010
parent reply Don <nospam nospam.com> writes:
Philippe Sigaud wrote:
 On Mon, Jul 19, 2010 at 03:03, Robert Jacques <sandford jhu.edu 
 <mailto:sandford jhu.edu>> wrote:
  
 
     A well designed opDollar is still an enhancement request:
     http://d.puremagic.com/issues/show_bug.cgi?id=3474. 
 
 
 Ah, OK.
  
 
     However, there is a hack to get $ to return a value. Unfortunately,
     I've lost that newsgroup post.
 
 I got some May discussion about ^ and $ and a thread about opDollar for 
 multidimensional arrays, but couldn't find any concrete things on 
 opDollar. Strange, I thought that was part of DMD for a dozen releases. 
 I guess, I'm wrong, then :)
It's still planned to be implemented. The patch I made didn't have enough description for Walter to be comfortable with including it yet.
 
 
  
 
     Memory got me this code snippet:
 
 
     struct Bar {
        int opIndex(int i) { writeln(i); return i; }
 
     }
     int __dollar() { return 5;}
 
 
     void main(string[] args) {
        Bar b;
        b[$];
     }
 
 
 It works, but in this case $ is global symbol, defined outside Bar. If I 
 put it inside the struct, the compiler complains about  __dollar being 
 undefined.
 
 Oh well, I'll push slices away from now, and use drop. Too bad, that 
 would have make some parts more elegant.
 
 Thanks Robert,
 
 
   Philippe
 
 
 
Jul 19 2010
parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Mon, Jul 19, 2010 at 20:58, Don <nospam nospam.com> wrote:

 It's still planned to be implemented. The patch I made didn't have enough
 description for Walter to be comfortable with including it yet.
And what if I buy Walter some chocolate cookies, while telling him what a nice guy you are?
Jul 19 2010
prev sibling parent reply "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Philippe Sigaud <philippe.sigaud gmail.com> wrote:

 On Sat, Jul 17, 2010 at 22:01, Philippe Sigaud  
 <philippe.sigaud gmail.com>wrote:

 My google-fu is weak, I cannot find any indication on opDollar and how  
 to
 define it, for D2. So, maybe someone here can help me? Can someone  
 points
 me
 to some documentation?
No, no one knows something about opDollar and how to define it? Pretty please?
I wrote this indexing struct. Clearly not perfect, but it sorta does the right things: struct Index { long delegate( long ) dg; long opCall( long value ) { return dg( value ); } Index opUnary( string op )( ) { dg = ( long value ) { mixin( " auto tmp = dg( value ); tmp" ~ op ~ "; return tmp;" ); }; return this; } Index opBinary( string op )( long n ) const { Index result; result.dg = ( long value ) { mixin( "return dg( value ) " ~ op ~ " n;" ); }; return result; } Index opOpAssign( string op )( long n ) { dg = ( long value ) { mixin( "return dg( value ) " ~ op ~ " n;" ); }; return this; } } Index __dollar( ) { Index result; result.dg = ( long value ){ return value; }; return result; } To use, make opSlice take an Index parameter, and call its opCall with the length of the container. Wish there was a way to make late-bound templates in D, as that could allow for different value types depending on usage. Hm, maybe there is a way, now that I think of it. I shall have to check in the future. -- Simen
Jul 21 2010
parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Wed, Jul 21, 2010 at 21:47, Simen kjaeraas <simen.kjaras gmail.com>wrote:

 I wrote this indexing struct. Clearly not perfect, but it sorta does the
 right things:

 To use, make opSlice take an Index parameter, and call its opCall with the
 length
 of the container.
OK, it take the length and compute the result index, as in $/2+5, etc. OK, I defined an opSlice(size_t i1, Index i2) {...} and it worked! Thanks Simen ! In my case, I guess the Index is just there to be a sentinel value, generated by __opdollar, as I for an infinite range, I do not have a length to give it, I just want arithmetic operations on Index to always return an Index. Except... I cannot do that: c[2..$+$] ... Ah, I get it: maybe like this: Index opBinary( string op )( Index i ) const { Index result; result.dg = ( long value ) { mixin( "return dg( value ) " ~ op ~ " i(value);" ); }; return result; } I don't understand you opUnary code: Index opUnary( string op )( ) { dg = ( long value ) { mixin( " auto tmp = dg( value ); tmp" ~ op ~ "; return tmp;" ); }; return this; } Shouldn't that be ;" ~ op ~ "tmp; return tmp;" ? So, cool, that works. I'll just have to check if operations on 'infinite' Index work as they should.
 Wish there was a way to make late-bound templates in D, as that
 could allow for different value types depending on usage.
 Hm, maybe there is a way, now that I think of it. I shall have to check in
 the future.
What do you mean? Philippe
Jul 22 2010