First life-signs of type functions
Steven Schveighoffer
schveiguy at gmail.com
Tue May 12 13:24:44 UTC 2020
On 5/12/20 2:42 AM, Stefan Koch wrote:
> On Tuesday, 12 May 2020 at 01:44:45 UTC, Steven Schveighoffer wrote:
>> On 5/11/20 5:58 PM, Stefan Koch wrote:
>>>
>>> In a type function alias cannot bind to values at all.
>>> It can only bind to symbols or types.
>>
>> This seems like a problematic limitation. Aliases can bind to values
>> when they are part of a tuple. This means that type functions are
>> going to have to do weird template acrobatics to deal with mixed tuples.
>>
>> For a long time, alias parameters wouldn't bind to int because it was
>> a keyword, not a symbol, even though you could alias int as a
>> declaration. It wouldn't even bind them to aliases of int (even though
>> they are not keywords). That has since been fixed, and everything
>> works great. I think we should avoid arbitrary limitations like this,
>> even if it's harder to get it to work.
>>
>> -Steve
>
> The reason that happened is not so much a parser issue.
> But it's because Basic Types are not Symbols.
> Which is indeed a more or less arbitrary limitation.
>
> Let's go through the reasoning for type functions now.
> let's assume alias A would bind to a value, the string foo
> for example.
>
> string F(alias A)
> {
> pragma(msg, typeof(A).stringof); // prints alias
> pragma(__traits(identifier, A); // error a string has no identifer.
> pragma(msg, is(A == string)); // prints false, because A does not
> hold the type string
> pragma(msg, A) prints "foo";
> pragma(msg, A == "foo") // error can't compare alias and string
> pragma(msg, is(A, "foo") // doesn't parse. The string "foo" is not
> a valid identifier
> return A; // error alias does not implicitly convert to string.
> }
>
> You see there would not be a point in allowing that.
This is what happens now:
string F(A...)()
{
pragma(msg, typeof(A[0]).stringof); // prints string
//pragma(msg, __traits(identifier, A[0])); // [1] error a string
has no identifer.
pragma(msg, is(A[0] == string)); // prints false, because A does
not hold the type string
pragma(msg, A[0]); // prints "foo"
pragma(msg, A[0] == "foo"); // prints true
//pragma(msg, is(A[0], "foo")); // [2] doesn't parse. The string
"foo" is not a valid identifier
return A[0]; // works
}
enum x = F!"foo";
For [1], yeah, I get that it doesn't have an identifier. So what. Make
the identifier null if you need it. Or it's an error and we deal with
that. There should be mechanisms we can use to find common properties
about everything. We already do that quite a bit with template programming.
For [2], there was some kind of syntax error. I'm not sure what it was
you were trying to say there. The compiler complained that the comma
wasn't valid. I don't want to assume anything for is expressions, there
are so many forms.
If I have a function that sorts an alias[], I want it to sort
AliasSeq!(62, 56, 23, 77) just as well as it sorts AliasSeq!(int, long,
bool), just as well as it sorts AliasSeq!(int, 5, "hello").
The thing I want is a) mutable array instead of tuple, and b) everything
is compile-time, so there is no "You can't use this at compile time"
nonsense.
I was hoping that your type functions would fulfill this.
-Steve
More information about the Digitalmars-d
mailing list