Re: Trait for "can be instantiated"?

2022-05-11 Thread Ben Jones via Digitalmars-d-learn

On Wednesday, 11 May 2022 at 12:29:05 UTC, Basile B. wrote:

How about being more explicit in the UDA ?
The idea would be to associate the enum value to a type or not:


I think that could work but would require some major changes to 
my existing code.  Also, I think I'd prefer:


```
@Token{

 enum lparen = '(';
 enum rparen = ')';
 enum if_token;
}
```

to what you suggested as a user of the library.


Re: Trait for "can be instantiated"?

2022-05-11 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 10 May 2022 at 16:10:26 UTC, Ben Jones wrote:

On Tuesday, 10 May 2022 at 16:05:15 UTC, H. S. Teoh wrote:
Using wrapper structs, etc., for this is IMO total overkill. 
Just use an enum for your token types.  Something like this 
would suffice:


That's basically what sumtype is going to do for me, but 
(hopefully) more safely. Also, the token types are "user 
defined,"  my lexer just grabs everything annotated with @Token 
and passes those types/wrapped enums to sumtype.


How about being more explicit in the UDA ?
The idea would be to associate the enum value to a type or not:

```d
import std.traits;
import std.stdio;

struct Token(T);

struct Token(T...)
if (T.length == 0) { }

@Token!(string) enum str_tok;
@Token!(float)  enum float_tok;
@Token!()   enum lparen_tok;

void main()
{
alias toks = getSymbolsByUDA!(mixin(__MODULE__), Token);

static foreach (t; toks)
{{
alias U = getUDAs!(t, Token);
alias A = TemplateArgsOf!(U);
static if (A.length)
pragma(msg, "add a `" ~ A[0].stringof ~ "`for `" ~ 
t.stringof ~ "`");

else
pragma(msg, "no SumType data needed for `" ~ 
t.stringof ~ "`");

}}
}
```


Re: Trait for "can be instantiated"?

2022-05-10 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, May 10, 2022 at 04:10:26PM +, Ben Jones via Digitalmars-d-learn 
wrote:
> On Tuesday, 10 May 2022 at 16:05:15 UTC, H. S. Teoh wrote:
> > Using wrapper structs, etc., for this is IMO total overkill. Just
> > use an enum for your token types.  Something like this would
> > suffice:
> 
> That's basically what sumtype is going to do for me, but (hopefully)
> more safely. Also, the token types are "user defined,"  my lexer just
> grabs everything annotated with @Token and passes those types/wrapped
> enums to sumtype.

Ah, I see what you're trying to do.


T

-- 
Why are you blatanly misspelling "blatant"? -- Branden Robinson


Re: Trait for "can be instantiated"?

2022-05-10 Thread Ben Jones via Digitalmars-d-learn

On Tuesday, 10 May 2022 at 16:05:15 UTC, H. S. Teoh wrote:
Using wrapper structs, etc., for this is IMO total overkill. 
Just use an enum for your token types.  Something like this 
would suffice:


That's basically what sumtype is going to do for me, but 
(hopefully) more safely. Also, the token types are "user 
defined,"  my lexer just grabs everything annotated with @Token 
and passes those types/wrapped enums to sumtype.


Re: Trait for "can be instantiated"?

2022-05-10 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, May 10, 2022 at 03:26:28PM +, Ben Jones via Digitalmars-d-learn 
wrote:
[...]
> I'm writing a lexer and I'm using sumtype to store any of the token types.
> Some have values associated with them (like brackets and parens which are
> defined as `enum lparen = '('` or whatever) and some are just markers
> (keywords like 'if', which I'm trying to represent with just `enum if_token`
> ). The wrapper struct is there because I need a type for each one to use
> them as part of a sumtype and I only want to store the enum's value when it
> makes sense to.

A sum type in the case of token types is essentially the same thing as
an enum value, implementation-wise. Sum types are implemented
essentially as a discriminated union, which consists of a tag and a
variant payload.  The tag essentially behaves like an enum (and is in
fact often implemented as such), which determines the interpretation of
the payload.

Using wrapper structs, etc., for this is IMO total overkill. Just use an
enum for your token types.  Something like this would suffice:

enum TokenType {
lparen,
rparen,
if_token,
...
string_literal,
}

struct Token {
TokenType type;
union {
string stringval;
float floatval;
... // etc.
}
}


T

-- 
Two wrongs don't make a right; but three rights do make a left...


Re: Trait for "can be instantiated"?

2022-05-10 Thread Ben Jones via Digitalmars-d-learn

On Tuesday, 10 May 2022 at 05:45:25 UTC, ag0aep6g wrote:


`x` is a type, period.

You can use void initialization to declare values of types that 
don't have an `init` value: `x value = void;`


As for an alternative to the brute force `__traits(compiles, 
...)`, you can check if `T.init` is a thing:


static if (is(typeof(T.init))) { T value; }

I'm not sure if that's really better, though.

By the way, what is your `Wrap` supposed to do with `x`? 
Treating it like `y` will likely fail, too, because `x` is not 
a value.


I'm writing a lexer and I'm using sumtype to store any of the 
token types.  Some have values associated with them (like 
brackets and parens which are defined as `enum lparen = '('` or 
whatever) and some are just markers (keywords like 'if', which 
I'm trying to represent with just `enum if_token` ). The wrapper 
struct is there because I need a type for each one to use them as 
part of a sumtype and I only want to store the enum's value when 
it makes sense to.


Re: Trait for "can be instantiated"?

2022-05-10 Thread Salih Dincer via Digitalmars-d-learn

On Tuesday, 10 May 2022 at 07:18:53 UTC, Salih Dincer wrote:

But I still have a little more patience :)


It gives an error when the exclamation mark is removed, I have no 
objections. But typing long instead of char also gives an error!

```d
void main()
{
  alias T =  char;

  import std.traits;
  foreach(useableType; AllImplicitConversionTargets!(ulong))
  {  /* Except for four: long, float, double, real.
The approval.//*/
assert(!is(T == useableType));
  }
   // No errors!
}
```
**Reference:** 
https://dlang.org/phobos/std_traits.html#AllImplicitConversionTargets


SDB@79


Re: Trait for "can be instantiated"?

2022-05-10 Thread Salih Dincer via Digitalmars-d-learn

On Tuesday, 10 May 2022 at 04:30:28 UTC, Ali Çehreli wrote:
I just found something that looked like a workaround. I don't 
know whether it is by design or by accident or whether this 
exercise exposes a compiler or language bug. Sorry... :)


I can't exactly use the is(T == char) or is(T : char) check. It 
isn't happening! But I still have a little more patience :)


SDB@79


Re: Trait for "can be instantiated"?

2022-05-09 Thread ag0aep6g via Digitalmars-d-learn

On 09.05.22 23:24, Ben Jones wrote:

enum x;
enum y = 5;

struct Wrap(alias T) {
     static if(isType!T){
  T value; //When t == x this doesn't work because `x` is opaque 
and has no default initializer

     }
}

[...]


x is a "type" as far as isType is concerned (which makes sense to me), 
but I don't think you can ever declare a variable of that type since 
there's no way to initialize it... Is there a trait that can tell if you 
can initialize a variable of a certain type?  The best I can think of is 
__traits(compiles, "T x;"), but it seems like it should be possible to 
do better?


`x` is a type, period.

You can use void initialization to declare values of types that don't 
have an `init` value: `x value = void;`


As for an alternative to the brute force `__traits(compiles, ...)`, you 
can check if `T.init` is a thing:


static if (is(typeof(T.init))) { T value; }

I'm not sure if that's really better, though.

By the way, what is your `Wrap` supposed to do with `x`? Treating it 
like `y` will likely fail, too, because `x` is not a value.


Re: Trait for "can be instantiated"?

2022-05-09 Thread Ali Çehreli via Digitalmars-d-learn

On 5/9/22 20:52, Ben Jones wrote:

> Using is(T) instead of isType!T also appears to be true for the
> un-instantiate-able enum.  Was your point just that I could replace
> isType!T with is(T)?

I just found something that looked like a workaround. I don't know 
whether it is by design or by accident or whether this exercise exposes 
a compiler or language bug. Sorry... :)


Ali



Re: Trait for "can be instantiated"?

2022-05-09 Thread Ben Jones via Digitalmars-d-learn

On Monday, 9 May 2022 at 21:58:59 UTC, Ali Çehreli wrote:

On 5/9/22 14:24, Ben Jones wrote:

> Is there a trait that can tell if you
> can initialize a variable of a certain type?

Not answering that question but the 'is' expression seems to 
work in this case:


static if(is (T)) {
 T value;
}

  https://dlang.org/spec/expression.html#IsExpression

Ali


Using is(T) instead of isType!T also appears to be true for the 
un-instantiate-able enum.  Was your point just that I could 
replace isType!T with is(T)?


Re: Trait for "can be instantiated"?

2022-05-09 Thread Ali Çehreli via Digitalmars-d-learn

On 5/9/22 14:24, Ben Jones wrote:

> Is there a trait that can tell if you
> can initialize a variable of a certain type?

Not answering that question but the 'is' expression seems to work in 
this case:


static if(is (T)) {
 T value;
}

  https://dlang.org/spec/expression.html#IsExpression

Ali



Trait for "can be instantiated"?

2022-05-09 Thread Ben Jones via Digitalmars-d-learn
I have a struct template that takes an alias parameter and I'm 
trying to distinguish between type parameters and enum values.  
std.traits.isType works for this except for one edge case:


```
import std.traits;
import std.stdio;

struct S{}
enum x;
enum y = 5;

struct Wrap(alias T) {
static if(isType!T){
 T value; //When t == x this doesn't work because `x` is 
opaque and has no default initializer

}
}

void main()
{
pragma(msg, isType!x); //true
pragma(msg, isType!y); //false

Wrap!S ws; //OK
Wrap!x wx; //error instantiating
Wrap!y wy; //OK, because we the static if condition is false
}
```

x is a "type" as far as isType is concerned (which makes sense to 
me), but I don't think you can ever declare a variable of that 
type since there's no way to initialize it... Is there a trait 
that can tell if you can initialize a variable of a certain type? 
 The best I can think of is __traits(compiles, "T x;"), but it 
seems like it should be possible to do better?