www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Identifier right after a template Type

reply Puneet Goel <puneet coverify.com> writes:
Currently, D allows putting an identifier right after a string 
which may be part of a template instance. Should there not be a 
mandatory whitespace between the type and the identifier?

For example, the following code is valid:

```D
class Foo(string str) {
   enum STR = str;
}
class Bar {
   Foo!q{foo}bb;
   Foo!q{foo}cc;
}
void main() {
   Bar p;
   pragma(msg, p.tupleof[0].stringof);
   pragma(msg, p.tupleof[1].stringof);
}

// Output:
// p.bb
// p.c  // q{foo}c is taken as a string
```

https://issues.dlang.org/show_bug.cgi?id=23999
Jun 22 2023
next sibling parent Puneet Goel <puneet coverify.com> writes:
It becomes an issue when the string passed to the template is 
actually meant to be a pseudo-code (to be parsed at compile-time):

```D
class Foo {
   int bar;

   Predicate! q{
     bar < 42;
   }b_pred;

   Predicate! q{
     bar > 0;
   }c_pred;
}
```

This becomes confusing since the user's intention is to declare a 
predicate named c_pred. But the D compiler actually parses that 
as _pred;
Jun 22 2023
prev sibling next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 6/22/23 00:49, Puneet Goel wrote:

    Foo!q{foo}cc;
[...]
 // p.c  // q{foo}c is taken as a string
In case it's not clear to all: q{foo}c is the equivalent of "foo"c, which means a string consisting of chars (as usual). This issue is somewhat related to something I've struggled with just today. The following expression that sums up 10,000 values came up 0! What? import std; void main() { const result = iota(10,000).map!(i => foo(i)).sum; writeln(result); // Prints 0! WAT? } auto foo(int i) { // Trivial for this demonstration return i; } After struggling for too long to admit, I realized that 10,000 is not "ten thousand" but "10 and 0". Ouch! Ali
Jun 22 2023
parent Puneet Goel <puneet coverify.com> writes:
On Thursday, 22 June 2023 at 09:19:39 UTC, Ali Çehreli wrote:
 On 6/22/23 00:49, Puneet Goel wrote:

    Foo!q{foo}cc;
[...]
 // p.c  // q{foo}c is taken as a string
In case it's not clear to all: q{foo}c is the equivalent of "foo"c, which means a string consisting of chars (as usual).
I think it is a bug (or maybe I should call it unexpected compiler behavior) at a more fundamental level. Consider how both clang and gcc treat literal suffix errors differently compared to Dlang: ``` $ cat /tmp/test.d ``` ```D ulong test = 44LUNG; ``` ``` $ ldc2 /tmp/test.d /tmp/test.d(1): Error: semicolon expected following auto declaration, not `NG` /tmp/test.d(1): Error: no identifier for declarator `NG` ``` ``` $ cat /tmp/test.c ``` ```C int long unsigned test = 44LUNG; ``` ``` $ gcc /tmp/test.c /tmp/test.c:1:26: error: invalid suffix "LUNG" on integer constant 1 | int long unsigned test = 44LUNG; | ^~~~~~ $ clang /tmp/test.c /tmp/test.c:1:28: error: invalid suffix 'LUNG' on integer constant int long unsigned test = 44LUNG; ^ 1 error generated. ```
Jun 22 2023
prev sibling parent Nick Treleaven <nick geany.org> writes:
On Thursday, 22 June 2023 at 07:49:31 UTC, Puneet Goel wrote:
 ```D
 class Bar {
   Foo!q{foo}bb;
   Foo!q{foo}cc;
 }
 ```
From bugzilla: Foo!2LUNGS; // declare variable `NGS` The PR also catches: Foo!0xFeedme; // variable `me` 0xFeedObject var; // has type Object If we don't error on those, we can't add new type suffixes for literals in future without breaking code. I think that is a strong argument to do it.
Jun 22 2023