View mode: basic / threaded / horizontal-split · Log in · Help
December 04, 2012
Template return values?
A thought's been going through my head for a while now. I wonder 
about template return values. Function signatures are usually the 
inputs and NOT the return type. However for writing a variant 
type could be so very useful. So unless I've misunderstood, this 
doesn't work (but it would be cool if it did).

struct Variant {
  enum ValueType {Long, Float, Double}

  ValueType vt;
  union {
    long lng;
    float fl;
    double dbl;
  }

  T getValue(T)() @property
  if (T == long || T == float || T == double) { //allowable types
    static if (T == long) { //only long case written for brevity
      switch(vt) {
        //entries would likely be mixed in and not written 
manually...
        case Long: return lng;
        case Float:
          assert(lng >= float.min && lng <= float.max);
          return cast(float) lng;
        case Float:
          assert(lng >= double.min && lng <= double.max);
          return cast(double) lng;
      }
    }

    assert(0, "Fell through, should never get here");
  }
}


 So then in theory

 Variant v;
 int i = v.getValue; //calls getValue!int()
December 04, 2012
Re: Template return values?
On 2012-12-04 08:48, Era Scarecrow wrote:
>   A thought's been going through my head for a while now. I wonder about
> template return values. Function signatures are usually the inputs and
> NOT the return type. However for writing a variant type could be so very
> useful. So unless I've misunderstood, this doesn't work (but it would be
> cool if it did).
>
> struct Variant {
>    enum ValueType {Long, Float, Double}
>
>    ValueType vt;
>    union {
>      long lng;
>      float fl;
>      double dbl;
>    }
>
>    T getValue(T)() @property
>    if (T == long || T == float || T == double) { //allowable types
>      static if (T == long) { //only long case written for brevity
>        switch(vt) {
>          //entries would likely be mixed in and not written manually...
>          case Long: return lng;
>          case Float:
>            assert(lng >= float.min && lng <= float.max);
>            return cast(float) lng;
>          case Float:
>            assert(lng >= double.min && lng <= double.max);
>            return cast(double) lng;
>        }
>      }
>
>      assert(0, "Fell through, should never get here");
>    }
> }
>
>
>   So then in theory
>
>   Variant v;
>   int i = v.getValue; //calls getValue!int()

You can use "alias this", but that only works for one type.

http://dlang.org/class.html#AliasThis

-- 
/Jacob Carlborg
December 04, 2012
Re: Template return values?
Era Scarecrow:

>  So then in theory
>
>  Variant v;
>  int i = v.getValue; //calls getValue!int()

I think this is not possible in D.

This seems possible:
auto i = v.getValue!int;

Bye,
bearophile
December 04, 2012
Re: Template return values?
On Tuesday, 4 December 2012 at 12:48:57 UTC, bearophile wrote:
> Era Scarecrow:
>
>> So then in theory
>>
>> Variant v;
>> int i = v.getValue; //calls getValue!int()

 Meant it to be long i, but the idea is the same.

>
> I think this is not possible in D.
>
> This seems possible:
> auto i = v.getValue!int;

 Indeed... it was just a thought, with that you could remove 
certain requirements for overriding opCast, and might handle 
implicit casting... actually that makes sense, allowing for a 
limited number of types you want it to automatically change to 
rather than using 'alias this' to subtype it.

 It also doesn't seem like it would be difficult to add, only 
'auto' would cause any real errors (as it's not a known type it 
can return).
December 04, 2012
Re: Template return values?
12/4/2012 4:08 PM, Jacob Carlborg пишет:
> On 2012-12-04 08:48, Era Scarecrow wrote:
>>   A thought's been going through my head for a while now. I wonder about
>> template return values. Function signatures are usually the inputs and
>> NOT the return type. However for writing a variant type could be so very
>> useful. So unless I've misunderstood, this doesn't work (but it would be
>> cool if it did).
>>
>> struct Variant {
>>    enum ValueType {Long, Float, Double}
>>
>>    ValueType vt;
>>    union {
>>      long lng;
>>      float fl;
>>      double dbl;
>>    }
>>
>>    T getValue(T)() @property
>>    if (T == long || T == float || T == double) { //allowable types
>>      static if (T == long) { //only long case written for brevity
>>        switch(vt) {
>>          //entries would likely be mixed in and not written manually...
>>          case Long: return lng;
>>          case Float:
>>            assert(lng >= float.min && lng <= float.max);
>>            return cast(float) lng;
>>          case Float:
>>            assert(lng >= double.min && lng <= double.max);
>>            return cast(double) lng;
>>        }
>>      }
>>
>>      assert(0, "Fell through, should never get here");
>>    }
>> }
>>
>>
>>   So then in theory
>>
>>   Variant v;
>>   int i = v.getValue; //calls getValue!int()
>
> You can use "alias this", but that only works for one type.
>
> http://dlang.org/class.html#AliasThis
>

Well TDPL claims multiple alias this is allowed so in some distant 
future it maybe possible for Varaint to alias this to all built-in types.

-- 
Dmitry Olshansky
December 04, 2012
Re: Template return values?
On 2012-12-04 13:59, Era Scarecrow wrote:

>   It also doesn't seem like it would be difficult to add, only 'auto'
> would cause any real errors (as it's not a known type it can return).

It has been suggested before, overriding on the return type. I has more 
problems that one might think first.

-- 
/Jacob Carlborg
December 04, 2012
Re: Template return values?
On Tuesday, December 04, 2012 21:43:09 Dmitry Olshansky wrote:
> Well TDPL claims multiple alias this is allowed so in some distant
> future it maybe possible for Varaint to alias this to all built-in types.

That would be pretty hideous IMHO. There's a reason that D eschews implicit 
conversions in general. And in this case, you'd very quickly end up with 
accidental conversions which resulted in exceptions being thrown by Variant. I 
think that it's _much_ better to require explicit conversions from Variant.

- Jonathan M Davis
December 04, 2012
Re: Template return values?
12/4/2012 10:40 PM, Jonathan M Davis пишет:
> On Tuesday, December 04, 2012 21:43:09 Dmitry Olshansky wrote:
>> Well TDPL claims multiple alias this is allowed so in some distant
>> future it maybe possible for Varaint to alias this to all built-in types.
>
> That would be pretty hideous IMHO. There's a reason that D eschews implicit
> conversions in general. And in this case, you'd very quickly end up with
> accidental conversions which resulted in exceptions being thrown by Variant.

Examples?

> I think that it's _much_ better to require explicit conversions from Variant.

Nope. The point of Variant is to feel natural.
Keep in mind that alias this is highly customizable. I'd expect it to do 
safe narrowing conversions and being only r-value so it will work just fine.

auto x = someVaraint; //NP: x is Varaint
ushort a = x; // implicit conversion that throws on narrowing
x = 32; //is fine x is int
ubyte b = x; //ok, narrowed
x = -1;
b = x; //ConvException

As for exceptions VS compile-time errors - well, there got to be a 
reason to use Varaint, namely having dynamic script-like typing. And 
once there the only way to signal problem is to throw an error, so it is 
a typical situation in dynamic typing world.

-- 
Dmitry Olshansky
December 04, 2012
Re: Template return values?
On Tuesday, 4 December 2012 at 17:43:21 UTC, Dmitry Olshansky 
wrote:
> Well TDPL claims multiple alias this is allowed so in some 
> distant future it maybe possible for Varaint to alias this to 
> all built-in types.

 Maybe....

 I remember back when i was originally reading about C++ and 
overloading how the signature would let you overload a function 
multiple times (C++ Primer 5th I think); I was going to try 
making a few classes to get a good understanding only to find it.

class Something {
  long value;

  long operator+(Something& rhs) {
    return value + rhs.value;
  }

  Something operator+(Something& rhs) {
    value += rhs.value;
    return this;
  }
}

 The above would refuse to compile (and likely still does) 
although it has a minorly different signature; Then I came to 
realize the return type wasn't part of the signature, and never 
was part of the identifying/overload-able part of OO. It makes 
sense to some limited degree but it's annoying...

 In certain unique cases I wonder if having a template return 
type would be an answer to certain problems... We know that 
sometimes the compiler can rewrite 'a.func(b,c)' to 'func(a,b,c)' 
, it's just syntactical sugar. Why couldn't it also try (when 
appropriately identifiable in the signature) 't = a.func(b,c)' to 
't = a.func!(typeof(t))(b, c)'?

 Mind you full template functions (where ! is required) this 
wouldn't apply for or even work for.
December 04, 2012
Re: Template return values?
On Tuesday, 4 December 2012 at 17:43:21 UTC, Dmitry Olshansky 
wrote:
> Well TDPL claims multiple alias this is allowed so in some 
> distant future it maybe possible for Varaint to alias this to 
> all built-in types.

 Maybe....

 I remember back when I was originally reading about C++ and 
overloading how the signature would let you overload a function 
multiple times (C++ Primer 5th I think); I was going to try 
making a few classes to get a good understanding only to find it.

class Something {
  long value;

  long operator+(Something& rhs) {
    return value + rhs.value;
  }

  Something operator+(Something& rhs) {
    value += rhs.value;
    return this;
  }
}

 The above would refuse to compile (and likely still does) 
although it has a minorly different signature; Then I came to 
realize the return type wasn't part of the signature, and never 
was part of the identifying/overload-able part of OO. It makes 
sense to some limited degree but it's annoying...

 In certain unique cases I wonder if having a template return 
type would be an answer to certain problems... We know that 
sometimes the compiler can rewrite 'a.func(b,c)' to 'func(a,b,c)' 
, it's just syntactical sugar. Why couldn't it also try (when 
appropriately identifiable in the signature) 't = a.func(b,c)' to 
't = a.func!(typeof(t))(b, c)'?

 Mind you full template functions (where ! is required) this 
wouldn't apply for or even work for.
« First   ‹ Prev
1 2 3
Top | Discussion index | About this forum | D home