| Thread overview | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 29, 2009 What's the deal with __buck? | ||||
|---|---|---|---|---|
| ||||
I stumbled upon a very interesting problem. Consider an infinite range that generates the numbers 1, 2, 3, ...
That range doesn't have a "length" member. However, it is a random access range, which makes things rather interesting. Now consider I want to advance 10 steps in that range. Being an obedient D programmer I'd write:
auto r = iota(1);
// skip 10 steps
r = r[10 .. $];
Now this is very cool. If a range is infinite, I can use the $ symbol in the right position, but nothing else. So I tried to effect that and got the following to compile:
struct DollarType {}
enum DollarType __dollar = DollarType();
struct S
{
void opSlice(uint, DollarType)
{
}
}
void main()
{
S s;
s[0 .. $];
}
This is cool because it allows detection of passing $. Now the problem is, I can't seem to get rid of the __dollar definition! Has anyone found a general-enough trick? I'd want a[...$...] to morph the $ into a.length *iff* a defines length, and go with the __dollar otherwise.
Thanks,
Andrei
| ||||
January 29, 2009 Re: What's the deal with __buck? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Thu, Jan 29, 2009 at 1:37 PM, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote: > I stumbled upon a very interesting problem. Consider an infinite range that generates the numbers 1, 2, 3, ... > > That range doesn't have a "length" member. However, it is a random access range, which makes things rather interesting. Now consider I want to advance 10 steps in that range. Being an obedient D programmer I'd write: > > auto r = iota(1); > // skip 10 steps > r = r[10 .. $]; > > Now this is very cool. If a range is infinite, I can use the $ symbol in the right position, but nothing else. So I tried to effect that and got the following to compile: > > struct DollarType {} > enum DollarType __dollar = DollarType(); > > struct S > { > void opSlice(uint, DollarType) > { > } > } > > void main() > { > S s; > s[0 .. $]; > } > > This is cool because it allows detection of passing $. Now the problem is, I can't seem to get rid of the __dollar definition! Has anyone found a general-enough trick? I'd want a[...$...] to morph the $ into a.length *iff* a defines length, and go with the __dollar otherwise. You need to give your DollarType an int and some arithmetic operators and have it represent an /offset/ from the end rather than signifying the end itself. Otherwise a[$-1] can't work. Once you do that, then you can do things like struct S { T opSlice(uint a, DollarType b) { return opSlice(a, length+b.offset); } T opSlice(uint a, uint b) { .... } ... } --bb | |||
January 29, 2009 Re: What's the deal with __buck? | ||||
|---|---|---|---|---|
| ||||
On Thu, Jan 29, 2009 at 1:48 PM, Bill Baxter <wbaxter@gmail.com> wrote:
> On Thu, Jan 29, 2009 at 1:37 PM, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
>> I stumbled upon a very interesting problem. Consider an infinite range that generates the numbers 1, 2, 3, ...
>>
>> That range doesn't have a "length" member. However, it is a random access range, which makes things rather interesting. Now consider I want to advance 10 steps in that range. Being an obedient D programmer I'd write:
>>
>> auto r = iota(1);
>> // skip 10 steps
>> r = r[10 .. $];
>>
>> Now this is very cool. If a range is infinite, I can use the $ symbol in the right position, but nothing else. So I tried to effect that and got the following to compile:
>>
>> struct DollarType {}
>> enum DollarType __dollar = DollarType();
>>
>> struct S
>> {
>> void opSlice(uint, DollarType)
>> {
>> }
>> }
>>
>> void main()
>> {
>> S s;
>> s[0 .. $];
>> }
>>
>> This is cool because it allows detection of passing $. Now the problem is, I can't seem to get rid of the __dollar definition! Has anyone found a general-enough trick? I'd want a[...$...] to morph the $ into a.length *iff* a defines length, and go with the __dollar otherwise.
>
> You need to give your DollarType an int and some arithmetic operators
> and have it represent an /offset/ from the end rather than signifying
> the end itself.
> Otherwise a[$-1] can't work.
>
> Once you do that, then you can do things like
> struct S
> {
> T opSlice(uint a, DollarType b) {
> return opSlice(a, length+b.offset);
> }
> T opSlice(uint a, uint b) {
> ....
> }
> ...
> }
Nevermind, it just sunk in what you meant.
I think it's only a problem when you want to have some things in a
module with special __dollar and some with not?
Or I suppose you're probably trying to make template things which may or may not be infinite?
I guess what's required is the ability to define the __dollar in the scope of a class/struct/template.
--bb
| ||||
January 29, 2009 Re: What's the deal with __buck? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | Hello Bill, > > I guess what's required is the ability to define the __dollar in the > scope of a class/struct/template. I think that is the correct solution. > > --bb > | |||
January 29, 2009 Re: What's the deal with __buck? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to BCS | BCS wrote:
> Hello Bill,
>>
>> I guess what's required is the ability to define the __dollar in the
>> scope of a class/struct/template.
>
> I think that is the correct solution.
Ok, thanks to all. So __dollar is looked up at module scope for anything
that's not a built-in array.
I thought some more about it and I think there's no need for __dollar.
It's enough that:
a) In slice expressions and index expressions with one argument, $ expands to value.length, where value is the object being indexed/sliced (if an unnamed temporary, the value is of course only evaluated once)
b) In index expressions with multiple arguments, $ expand to value.length(i), where i is the zero-based argument position.
This is exactly enough what's needed to make it all work. Infinite
ranges may define a symbolic infinite length and overload slicing on it.
Andrei
Andrei
| |||
January 29, 2009 Re: What's the deal with __buck? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Thu, Jan 29, 2009 at 12:48 PM, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote: > BCS wrote: >> >> Hello Bill, >>> >>> I guess what's required is the ability to define the __dollar in the scope of a class/struct/template. >> >> I think that is the correct solution. > > Ok, thanks to all. So __dollar is looked up at module scope for anything that's not a built-in array. > > I thought some more about it and I think there's no need for __dollar. It's enough that: > > a) In slice expressions and index expressions with one argument, $ expands to value.length, where value is the object being indexed/sliced (if an unnamed temporary, the value is of course only evaluated once) > > b) In index expressions with multiple arguments, $ expand to > value.length(i), where i is the zero-based argument position. > > This is exactly enough what's needed to make it all work. Infinite ranges may define a symbolic infinite length and overload slicing on it. Sounds good. Question - since length will work for multiple indices, will it ever be possible to have .. multiple slices? a[x1 .. x2, y1 .. y2] = b; | |||
January 29, 2009 Re: What's the deal with __buck? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Jarrett Billingsley wrote:
> On Thu, Jan 29, 2009 at 12:48 PM, Andrei Alexandrescu
> <SeeWebsiteForEmail@erdani.org> wrote:
>> BCS wrote:
>>> Hello Bill,
>>>> I guess what's required is the ability to define the __dollar in the
>>>> scope of a class/struct/template.
>>> I think that is the correct solution.
>> Ok, thanks to all. So __dollar is looked up at module scope for anything
>> that's not a built-in array.
>>
>> I thought some more about it and I think there's no need for __dollar.
>> It's enough that:
>>
>> a) In slice expressions and index expressions with one argument, $ expands
>> to value.length, where value is the object being indexed/sliced (if an
>> unnamed temporary, the value is of course only evaluated once)
>>
>> b) In index expressions with multiple arguments, $ expand to
>> value.length(i), where i is the zero-based argument position.
>>
>> This is exactly enough what's needed to make it all work. Infinite
>> ranges may define a symbolic infinite length and overload slicing on it.
>
> Sounds good. Question - since length will work for multiple indices,
> will it ever be possible to have .. multiple slices?
>
> a[x1 .. x2, y1 .. y2] = b;
You can do that with opIndex already.
| |||
January 29, 2009 Re: What's the deal with __buck? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Don | On Fri, Jan 30, 2009 at 5:58 AM, Don <nospam@nospam.com> wrote:
> Jarrett Billingsley wrote:
>>
>> On Thu, Jan 29, 2009 at 12:48 PM, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
>>>
>>> BCS wrote:
>>>>
>>>> Hello Bill,
>>>>>
>>>>> I guess what's required is the ability to define the __dollar in the scope of a class/struct/template.
>>>>
>>>> I think that is the correct solution.
>>>
>>> Ok, thanks to all. So __dollar is looked up at module scope for anything that's not a built-in array.
>>>
>>> I thought some more about it and I think there's no need for __dollar. It's enough that:
>>>
>>> a) In slice expressions and index expressions with one argument, $
>>> expands
>>> to value.length, where value is the object being indexed/sliced (if an
>>> unnamed temporary, the value is of course only evaluated once)
>>>
>>> b) In index expressions with multiple arguments, $ expand to
>>> value.length(i), where i is the zero-based argument position.
>>>
>>> This is exactly enough what's needed to make it all work. Infinite ranges may define a symbolic infinite length and overload slicing on it.
>>
>> Sounds good. Question - since length will work for multiple indices, will it ever be possible to have .. multiple slices?
>>
>> a[x1 .. x2, y1 .. y2] = b;
>
> You can do that with opIndex already.
Can you? How? As far as I know any index expression with more than one .. in it automatically generates a compiler error.
--bb
| |||
January 29, 2009 Re: What's the deal with __buck? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | Bill Baxter wrote:
> On Fri, Jan 30, 2009 at 5:58 AM, Don <nospam@nospam.com> wrote:
>> Jarrett Billingsley wrote:
>>> On Thu, Jan 29, 2009 at 12:48 PM, Andrei Alexandrescu
>>> <SeeWebsiteForEmail@erdani.org> wrote:
>>>> BCS wrote:
>>>>> Hello Bill,
>>>>>> I guess what's required is the ability to define the __dollar in the
>>>>>> scope of a class/struct/template.
>>>>> I think that is the correct solution.
>>>> Ok, thanks to all. So __dollar is looked up at module scope for anything
>>>> that's not a built-in array.
>>>>
>>>> I thought some more about it and I think there's no need for __dollar.
>>>> It's enough that:
>>>>
>>>> a) In slice expressions and index expressions with one argument, $
>>>> expands
>>>> to value.length, where value is the object being indexed/sliced (if an
>>>> unnamed temporary, the value is of course only evaluated once)
>>>>
>>>> b) In index expressions with multiple arguments, $ expand to
>>>> value.length(i), where i is the zero-based argument position.
>>>>
>>>> This is exactly enough what's needed to make it all work. Infinite
>>>> ranges may define a symbolic infinite length and overload slicing on it.
>>> Sounds good. Question - since length will work for multiple indices,
>>> will it ever be possible to have .. multiple slices?
>>>
>>> a[x1 .. x2, y1 .. y2] = b;
>> You can do that with opIndex already.
>
> Can you? How? As far as I know any index expression with more than
> one .. in it automatically generates a compiler error.
Aargh, you're right. I remembered that I'd got it to generate an AST for me, but I forgot that I had put in a hack for ..
| |||
January 29, 2009 Re: What's the deal with __buck? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Jarrett Billingsley wrote:
> On Thu, Jan 29, 2009 at 12:48 PM, Andrei Alexandrescu
> <SeeWebsiteForEmail@erdani.org> wrote:
>> BCS wrote:
>>> Hello Bill,
>>>> I guess what's required is the ability to define the __dollar in the
>>>> scope of a class/struct/template.
>>> I think that is the correct solution.
>> Ok, thanks to all. So __dollar is looked up at module scope for anything
>> that's not a built-in array.
>>
>> I thought some more about it and I think there's no need for __dollar.
>> It's enough that:
>>
>> a) In slice expressions and index expressions with one argument, $ expands
>> to value.length, where value is the object being indexed/sliced (if an
>> unnamed temporary, the value is of course only evaluated once)
>>
>> b) In index expressions with multiple arguments, $ expand to
>> value.length(i), where i is the zero-based argument position.
>>
>> This is exactly enough what's needed to make it all work. Infinite
>> ranges may define a symbolic infinite length and overload slicing on it.
>
> Sounds good. Question - since length will work for multiple indices,
> will it ever be possible to have .. multiple slices?
>
> a[x1 .. x2, y1 .. y2] = b;
That's rather exotic. After that the road is opened for free-form combinations of a .. b and a. But I can definitely see some good uses for it.
Andrei
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply