Jump to page: 1 2 3
Thread overview
compile-time opIndex
Dec 18, 2014
Dicebot
Dec 18, 2014
Dicebot
Dec 18, 2014
Dicebot
Dec 30, 2014
Dicebot
Dec 31, 2014
Dicebot
Dec 18, 2014
H. S. Teoh
Dec 19, 2014
Dicebot
Dec 31, 2014
Artur Skawina
Dec 31, 2014
H. S. Teoh
Dec 31, 2014
Dicebot
Dec 31, 2014
H. S. Teoh
Dec 31, 2014
Dicebot
Dec 31, 2014
H. S. Teoh
Dec 31, 2014
Dicebot
Dec 31, 2014
H. S. Teoh
Dec 31, 2014
Dicebot
Jan 01, 2015
Artur Skawina
December 18, 2014
We currently have the ability to do opIndex for simulating an array or other type indexed at runtime.

But we have no way to simulate the ability of tuple indexing. Such an ability would unleash a huge amount of possibilities, including user-defined tuple types.

Let's designate a straw man name: opTupleIndex.

In essence, if you have foo[n], where n is a compile-time constant, then opTupleIndex would be instantiated (if defined) like:

opTupleIndex!n

Then you can have user-defined tuples that are simple to define:

struct KeyValuePair(K, V)
{
   K key;
   V value;
   enum length = 2;
   ref K opTupleIndex(int x) if(x == 0) { return key;}
   ref V opTupleIndex(int x) if(x == 1) { return value;}
}

auto x = KeyValuePair!(int, string)(1, "hi");

static assert(typeof(x[0]) == int);
static assert(typeof(x[1]) == string);
x[0] = 4;
x[1] = "hi";

Note here I have all the mechanisms that real tuples have, but I have control over what happens when accessing each element, and I do not need opIndex to change its return type based on a runtime parameter (one of the limitations of the current system).

I'm not huge on tuple usage, so I'm not sure if I'm missing something. Currently there is some debate as to whether to add a "byPair" range to builtin AAs, because the return value from 'front' is hard to define. This might go a long way in helping such a case.

Does this sound like something worth having? We likely would have to error if both opIndex and opTupleIndex are defined for a specific type.

-Steve
December 18, 2014
Have you seen my http://wiki.dlang.org/DIP63 ?
December 18, 2014
On 12/18/14 10:43 AM, Steven Schveighoffer wrote:

> struct KeyValuePair(K, V)
> {
>     K key;
>     V value;
>     enum length = 2;
>     ref K opTupleIndex(int x) if(x == 0) { return key;}
>     ref V opTupleIndex(int x) if(x == 1) { return value;}
> }
>

Or with more recent changes to the compiler:

template opTupleIndex(int x) if (x == 0) { alias opTupleIndex = key;}
template opTupleIndex(int x) if (x == 1) { alias opTupleIndex = value;}

-Steve
December 18, 2014
On 12/18/14 10:44 AM, Dicebot wrote:
> Have you seen my http://wiki.dlang.org/DIP63 ?

I admit this is somewhat over my head, but it seems to be more focused on types. I will note that your example:

struct Pack(T...)
{
   alias expand = T;
   alias expand this;
}

I don't think this would work, since you can't alias a value to a type?

But I don't use tuples regularly, so I am not sure where exactly expand is used. I thought it was to convert a concrete struct into a tuple of values, not a type tuple.

I don't disagree with the idea of having operators inside templates, I just don't know if it solves the problem I was looking at.

-Steve
December 18, 2014
On Thursday, 18 December 2014 at 16:15:09 UTC, Steven Schveighoffer wrote:
> On 12/18/14 10:44 AM, Dicebot wrote:
>> Have you seen my http://wiki.dlang.org/DIP63 ?
>
> I admit this is somewhat over my head, but it seems to be more focused on types.

In D there is no special built-in value tuple concept. It is all same thing but emulating this behavior for symbols and types is much more difficult compared to values. This is the reason for such focus - rest is not really a problem.

> I will note that your example:
>
> struct Pack(T...)
> {
>    alias expand = T;
>    alias expand this;
> }
>
> I don't think this would work, since you can't alias a value to a type?

Try this and be surprised :) `alias this` affects any symbol lookup and this pattern results in pretty interesting behavior. But it is still not good enough as described in the DIP.

> But I don't use tuples regularly, so I am not sure where exactly expand is used. I thought it was to convert a concrete struct into a tuple of values, not a type tuple.

You can ignore expansion for now, it was motivating use case but DIP itself defines tools of defining user types that act like built-in tuples - which fits the theme of your original proposal. It also briefly speculates why adding such features to structs does not seem a good idea.

Also there is no difference between tuple of values and type tuple, it is same entity.

> I don't disagree with the idea of having operators inside templates, I just don't know if it solves the problem I was looking at.

Your original snippet seems to implementable within proposed DIP if you replace struct with raw template. You will lose struct properties like having actual instance but those don't exist for built-in tuples either.
December 18, 2014
On 12/18/14 11:34 AM, Dicebot wrote:
> On Thursday, 18 December 2014 at 16:15:09 UTC, Steven Schveighoffer wrote:

>> I don't disagree with the idea of having operators inside templates, I
>> just don't know if it solves the problem I was looking at.
>
> Your original snippet seems to implementable within proposed DIP if you
> replace struct with raw template. You will lose struct properties like
> having actual instance but those don't exist for built-in tuples either.

So the discussion is here:

https://github.com/D-Programming-Language/druntime/pull/1070

Essentially, we want to implement a range which gives access to builtin-AA elements via a pair or tuple. The first element will be the key, the second the value.

But we also want to allow changing the value, and getting the key by reference (if, for instance, it's a huge struct).

The big issue here is that people are worried about putting in some 'hacky' type returned from 'front' for this range, when "builtin tuples are around the corner." We don't want to have people get used to having one API, and then have to switch to another API when real tuples are released.

So having an actual concrete instance is important here. 'front' doesn't return a type it returns a value tuple.

Oh, and we can't use std.typecons.Tuple because that's in Phobos, this is druntime.

(and my assertion is that front.key and front.value should work instead of having to use front[0] and front[1]!)

-Steve
December 18, 2014
I wasn't subscribed to druntime changes thus missed this discussion. Will chime in there soon.
December 18, 2014
On Thu, Dec 18, 2014 at 03:44:18PM +0000, Dicebot via Digitalmars-d wrote:
> Have you seen my http://wiki.dlang.org/DIP63 ?

Ahhh, finally I understand what this DIP is all about. :-D

I like it. +1.


T

-- 
If blunt statements had a point, they wouldn't be blunt...
December 19, 2014
On Thursday, 18 December 2014 at 18:04:10 UTC, H. S. Teoh via Digitalmars-d wrote:
> On Thu, Dec 18, 2014 at 03:44:18PM +0000, Dicebot via Digitalmars-d wrote:
>> Have you seen my http://wiki.dlang.org/DIP63 ?
>
> Ahhh, finally I understand what this DIP is all about. :-D
>
> I like it. +1.
>
>
> T

Unfortunately when trying to implement this in DMD I have encountered many difficulties with existing DMD tree structure - it simply does not allow to express such entities without serious restructuring. And I am no proficient enough in DMD to do such a major change on my own - thus it remains frozen :(
December 30, 2014
On 12/18/14 11:54 AM, Dicebot wrote:
> I wasn't subscribed to druntime changes thus missed this discussion.
> Will chime in there soon.

Ping, still waiting on this :)

-Steve
« First   ‹ Prev
1 2 3