Jump to page: 1 2
Thread overview
shared and getParameterStorageClasses bug?
Aug 22, 2020
Jean-Louis Leroy
Aug 23, 2020
Meta
Aug 23, 2020
Jean-Louis Leroy
Aug 23, 2020
Jean-Louis Leroy
Aug 23, 2020
Paul Backus
Aug 24, 2020
Timon Gehr
Aug 24, 2020
Jean-Louis Leroy
Aug 25, 2020
Jean-Louis Leroy
August 22, 2020
void foo(lazy shared Object);
pragma(msg, __traits(getParameterStorageClasses, foo, 0)); // tuple("lazy")

Shouldn't this return a tuple("lazy", "shared)? Given that `shared` is documented as a parameter storage class?


August 23, 2020
On Saturday, 22 August 2020 at 18:34:21 UTC, Jean-Louis Leroy wrote:
> void foo(lazy shared Object);
> pragma(msg, __traits(getParameterStorageClasses, foo, 0)); // tuple("lazy")
>
> Shouldn't this return a tuple("lazy", "shared)? Given that `shared` is documented as a parameter storage class?

I'm not sure why the documentation says that, but I believe shared is considered a "type constructor", not a storage class. It's in the same class as const, immutable, etc.
August 23, 2020
On Saturday, 22 August 2020 at 18:34:21 UTC, Jean-Louis Leroy wrote:
> void foo(lazy shared Object);
> pragma(msg, __traits(getParameterStorageClasses, foo, 0)); // tuple("lazy")
>
> Shouldn't this return a tuple("lazy", "shared)? Given that `shared` is documented as a parameter storage class?

From a grammar point of view, type qualifiers (`const`, `immutable`, `inout` and `shared`) can appear as 4 different entities:
1. Type constructors [0]
2. Variable storage classes [1]
3. Parameter attributes [2]
4. Member function attributes [3]

Parameter attributes grammatically include both UDAs and parameter storage classes (confusingly named `InOut` in the spec), so we can actually collapse the grammatical entities
related to variables (which include parameters) to just 2 kinds: type constructors and storage classes.

Semantically:

   Q T x;  // A) storage class syntax
   Q(T) x; // B) type constructor syntax

A) and B) are equivalent (where `Q` is some type qualifier and `T` is some type).
During semantic processing the compiler erases the difference between two by converting qualifiers appearing as storage classes to type constructors (IIRC described via `mtype.d`).

Which leaves `lazy`, `in`, `out`, `ref`, `return` and `scope` as the only actual parameter storage classes that you can query. (`auto ref` is resolved to either `ref` or no storage class during IFTI semantic processing).

[0]: https://dlang.org/spec/grammar.html#TypeCtor
[1]: https://dlang.org/spec/grammar.html#StorageClass
[2]: https://dlang.org/spec/grammar.html#Parameters
[3]: https://dlang.org/spec/grammar.html#MemberFunctionAttributes
August 23, 2020
On Sunday, 23 August 2020 at 06:42:02 UTC, Petar Kirov [ZombineDev] wrote:

> From a grammar point of view, type qualifiers (`const`, `immutable`, `inout` and `shared`) can appear as 4 different entities:
> 1. Type constructors [0]
> 2. Variable storage classes [1]
> 3. Parameter attributes [2]
> 4. Member function attributes [3]
>
> Parameter attributes grammatically include both UDAs and parameter storage classes (confusingly named `InOut` in the spec), so we can actually collapse the grammatical entities
> related to variables (which include parameters) to just 2 kinds: type constructors and storage classes.
>
> Semantically:
>
>    Q T x;  // A) storage class syntax
>    Q(T) x; // B) type constructor syntax
>
> A) and B) are equivalent (where `Q` is some type qualifier and `T` is some type).

Thanks. Then my follow-up question is: how do I retrieve the parameter type constructors? Without resorting on scanning the stringified parameter like here:

enum isSharedParameter(alias fun, uint param) =
  Parameters!fun[param..param+1].stringof.indexOf("shared") != -1;

(of course this is not robust: it would give false positives with types that contain the substring "shared").

My actual goal is to extract them in the same fashion as the storage classes, e.g.:

void foo(lazy const shared Object);
static assert(parameterTypeConstructors!foo == tuple("const", "shared"));

Do I really have to parse a string like "(lazy shared(const(Object)))"? And, how reliable would this solution be?





August 23, 2020
On Sunday, 23 August 2020 at 13:44:30 UTC, Jean-Louis Leroy wrote:
> On Sunday, 23 August 2020 at 06:42:02 UTC, Petar Kirov [ZombineDev] wrote:
>
>> [...]
>
> Thanks. Then my follow-up question is: how do I retrieve the parameter type constructors? Without resorting on scanning the stringified parameter like here:
>
> enum isSharedParameter(alias fun, uint param) =
>   Parameters!fun[param..param+1].stringof.indexOf("shared") != -1;
>
> (of course this is not robust: it would give false positives with types that contain the substring "shared").
>
> My actual goal is to extract them in the same fashion as the storage classes, e.g.:
>
> void foo(lazy const shared Object);
> static assert(parameterTypeConstructors!foo == tuple("const", "shared"));
>
> Do I really have to parse a string like "(lazy shared(const(Object)))"? And, how reliable would this solution be?

OK since the `shared` has migrated to the type, isSharedParameter can be written like this:

enum isSharedParameter(alias fun, uint param) =
  is(Parameters!fun[param] == SharedOf!(Parameters!fun[param]));

August 23, 2020
On Sunday, 23 August 2020 at 14:11:21 UTC, Jean-Louis Leroy wrote:
>
> OK since the `shared` has migrated to the type, isSharedParameter can be written like this:
>
> enum isSharedParameter(alias fun, uint param) =
>   is(Parameters!fun[param] == SharedOf!(Parameters!fun[param]));

An even simpler way is to use the pattern-matching feature of `is(...)`:

enum isSharedParameter(alias fun, size_t param) =
    is(Parameters!fun[param] == shared(T), T);

You can read this as, "there exists some T such that Parameters!fun[param] is shared(T)".
August 23, 2020
On 8/23/20 10:21 AM, Paul Backus wrote:
> On Sunday, 23 August 2020 at 14:11:21 UTC, Jean-Louis Leroy wrote:
>>
>> OK since the `shared` has migrated to the type, isSharedParameter can be written like this:
>>
>> enum isSharedParameter(alias fun, uint param) =
>>   is(Parameters!fun[param] == SharedOf!(Parameters!fun[param]));
> 
> An even simpler way is to use the pattern-matching feature of `is(...)`:
> 
> enum isSharedParameter(alias fun, size_t param) =
>      is(Parameters!fun[param] == shared(T), T);
> 
> You can read this as, "there exists some T such that Parameters!fun[param] is shared(T)".

is(Parameters!fun[param] == shared);

This works for all type constructors.

I think there's no way to get this as a nice string list though like a __traits might do (though it could be done).

-Steve
August 23, 2020
On 8/23/20 10:21 AM, Paul Backus wrote:
> On Sunday, 23 August 2020 at 14:11:21 UTC, Jean-Louis Leroy wrote:
>>
>> OK since the `shared` has migrated to the type, isSharedParameter can be written like this:
>>
>> enum isSharedParameter(alias fun, uint param) =
>>   is(Parameters!fun[param] == SharedOf!(Parameters!fun[param]));
> 
> An even simpler way is to use the pattern-matching feature of `is(...)`:
> 
> enum isSharedParameter(alias fun, size_t param) =
>      is(Parameters!fun[param] == shared(T), T);
> 
> You can read this as, "there exists some T such that Parameters!fun[param] is shared(T)".

This would have problems if shared is combined with other qualifiers (const and my nemesis inout).
August 23, 2020
On Sunday, 23 August 2020 at 13:44:30 UTC, Jean-Louis Leroy wrote:
> On Sunday, 23 August 2020 at 06:42:02 UTC, Petar Kirov [ZombineDev] wrote:
>
>> From a grammar point of view, type qualifiers (`const`, `immutable`, `inout` and `shared`) can appear as 4 different entities:
>> 1. Type constructors [0]
>> 2. Variable storage classes [1]
>> 3. Parameter attributes [2]
>> 4. Member function attributes [3]
>>
>> Parameter attributes grammatically include both UDAs and parameter storage classes (confusingly named `InOut` in the spec), so we can actually collapse the grammatical entities
>> related to variables (which include parameters) to just 2 kinds: type constructors and storage classes.
>>
>> Semantically:
>>
>>    Q T x;  // A) storage class syntax
>>    Q(T) x; // B) type constructor syntax
>>
>> A) and B) are equivalent (where `Q` is some type qualifier and `T` is some type).
>
> Thanks. Then my follow-up question is: how do I retrieve the parameter type constructors? Without resorting on scanning the stringified parameter like here:
>
> enum isSharedParameter(alias fun, uint param) =
>   Parameters!fun[param..param+1].stringof.indexOf("shared") != -1;
>
> (of course this is not robust: it would give false positives with types that contain the substring "shared").
>
> My actual goal is to extract them in the same fashion as the storage classes, e.g.:
>
> void foo(lazy const shared Object);
> static assert(parameterTypeConstructors!foo == tuple("const", "shared"));
>
> Do I really have to parse a string like "(lazy shared(const(Object)))"? And, how reliable would this solution be?

Hmm, why do you need to extract them in the same fashion? For use in string mixins? If you just want to create a proxy function then simply using std.traits.Parameters should do the trick.

If you're writing a meta programming library, then perhaps you can consider representing function types as:
1. AliasSeq of the types
2. AliasSeq of the types
3. AliasSeq of the default values
4. AliasSeq of ints, each representing a bitset of the parameter storage classes that we're set. Or alternatively string[][].

Another way would be to create a Parameter struct template that contains the relevant information and then have an AliasSeq of Parameter types for each function type.

August 24, 2020
On Sunday, 23 August 2020 at 21:14:38 UTC, Petar Kirov [ZombineDev] wrote:
> Hmm, why do you need to extract them in the same fashion? For use in string mixins?

Yeah, it is related to my attempt to support all the language in my openmethods library.

> If you just want to create a proxy function then simply using std.traits.Parameters should do the trick.

That's a whole can of worms ;-) I am trying to handle that as well as possible in a part of openmethods that I spun off and donated to bolts (see here https://github.com/aliak00/bolts/blob/master/source/bolts/experimental/refraction.d).

« First   ‹ Prev
1 2