Re: pragma msg field name?

2023-06-26 Thread Chris Katko via Digitalmars-d-learn

On Tuesday, 27 June 2023 at 04:56:19 UTC, Ali Çehreli wrote:

On 6/26/23 21:25, Chris Katko wrote:

> How do I get just the field name?

I know .tupleof, which you can typeof() as well:

class myObject{
int field1, field2, field3;

static foreach(field; typeof(this).tupleof)
{
pragma(msg, field.stringof);
}

static foreach(MemberType; typeof(typeof(this).tupleof)) {
pragma(msg, MemberType);
}
}

The output:

field1
field2
field3
int
int
int

I had to consult what I wrote years ago:

  http://ddili.org/ders/d.en/tuples.html#ix_tuples..tupleof

Ali


That seems to do the trick, I was really not expecting so much 
text just to get something so simple!


At the moment I'm trying to take variables with an attribute 
(rep) and then make a duplicate of them inside the struct. It 
seems to work. If I had duplicate names, it fails. However, the 
new fields don't appear to be showing up on a second enumeration:



enum rep;
struct multiplayerObject2
{
@rep ushort type;
@("rep2") ushort type2;
float x, y;

static foreach(t; typeof(this).tupleof)
{
// no if rep/rep2 here, i'm just testing:
pragma(msg, t.stringof); // does not see any new fields!
		mixin("bool " ~ t.stringof ~ "25;"); // copy the fieldname 
with a suffix

}

pragma(msg, "-separator-");

static foreach(t; typeof (this).tupleof) // again
{
pragma(msg, t.stringof); // does not see any new fields!
}
}


output
```
type
type2
x
y
-separator-
type
type2
x
y
```

However, if I do try to force the names to duplicate (say 
"type2") I get an error involving some sort of __anonymous 
subobject.

```
source/app.d-mixin-123(123,6): Error: variable 
`app.multiplayerObject2.__anonymous.type2` conflicts with 
variable `app.multiplayerObject2.type2` at source/app.d(116,19)

```

I also never realized you could put a static/static foreach 
inside the body of a struct (and not a function) so I'm still 
having trouble wrapping my head around that. Is it processing 
top-down?


Jonathan M Davis: Yeah, it does what I listed if you add the UDA 
to it.


Re: pragma msg field name?

2023-06-26 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, June 26, 2023 10:25:13 PM MDT Chris Katko via Digitalmars-d-learn 
wrote:
> inside a static foreach I can do
>
> ```
> enum rep;
>
> class myObject{
> int field1, field2, field3;
>
> static foreach(field; getSymbolsByUDA!(typeof(this), rep))
> {
>   pragma(msg, field);  // fails
>   pragma(msg, fullyQualifiedName!field); // works
> }
> }
> ```
>
> error for pragma(msg, field)
> ```
> source/app.d(33,16): Error: value of `this` is not known at
> compile time
> source/app.d(33,4):while evaluating `pragma(msg, field)`
>
> [repeating for every variable in the class]
> ```
>
> How do I get just the field name? And why does it think this is a
> run-time value? I need to wrap it in some sort of template?
>
> All I see in std.traits docs are: fullyQualifiedName mangledName
> moduleName packageName

Well, on my machine, once the import for std.traits is added, that code
compiles but prints nothing, so I suspect that you paired it down too much
(likely related to the fact that none of the fields in question actually
have UDAs on them).

However, I would point out that getSymbolsByUDA gives you symbols, not
strings, whereas pragma(msg, ...) wants a string. fullyQualifiedName works,
because it results in a string. You can see what field is by using typeof on
it, but presumably, it's complaining about being a runtime value, because
when you use it, it's trying to evaluate the symbol (e.g. get the value of
field1). Using .stringof on field will give you a string, though I don't
know if it'll give you what you're looking for. In general, FieldNameTuple
would probably be what you would want for getting the names of the fields in
a struct or class, though obviously, that wouldn't be just getting the ones
with a specific UDA.

- Jonathan M Davis





Re: pragma msg field name?

2023-06-26 Thread Ali Çehreli via Digitalmars-d-learn

On 6/26/23 21:25, Chris Katko wrote:

> How do I get just the field name?

I know .tupleof, which you can typeof() as well:

class myObject{
int field1, field2, field3;

static foreach(field; typeof(this).tupleof)
{
pragma(msg, field.stringof);
}

static foreach(MemberType; typeof(typeof(this).tupleof)) {
pragma(msg, MemberType);
}
}

The output:

field1
field2
field3
int
int
int

I had to consult what I wrote years ago:

  http://ddili.org/ders/d.en/tuples.html#ix_tuples..tupleof

Ali



pragma msg field name?

2023-06-26 Thread Chris Katko via Digitalmars-d-learn

inside a static foreach I can do

```
enum rep;

class myObject{
int field1, field2, field3;

static foreach(field; getSymbolsByUDA!(typeof(this), rep))
{
pragma(msg, field);  // fails
pragma(msg, fullyQualifiedName!field); // works
}
}
```

error for pragma(msg, field)
```
source/app.d(33,16): Error: value of `this` is not known at 
compile time

source/app.d(33,4):while evaluating `pragma(msg, field)`

[repeating for every variable in the class]
```

How do I get just the field name? And why does it think this is a 
run-time value? I need to wrap it in some sort of template?


All I see in std.traits docs are: fullyQualifiedName mangledName 
moduleName packageName


Re: Scope guards

2023-06-26 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/26/23 2:42 PM, Cecil Ward wrote:


==
{
size_t p = offset;
++p;
scope(exit) { writeOutput( 0, p );

++p
…
++p;

return;
}

==

The correctness of its behaviour depends on what the value of p is when 
it calls writeOutput(), and the value of p is being changed. To be 
correct, the final value of p needs to be passed to writeOutput( p ). 
That was what I was worrying about. I could have course introduce 
another variable to capture this final value and use that in the scope 
guard, but then I can’t make the scope guard general if I have more than 
one exit route. The compiler sounded as if it did not like the local 
variable p in the scope guard, but I need to try it again to get the 
error message.


That will print the final value of `p`. `p` lives at the same address 
for the entire function, and the scope exit prints the value from that 
address.


-Steve


Re: Counting an initialised array, and segments

2023-06-26 Thread Cecil Ward via Digitalmars-d-learn

On Monday, 26 June 2023 at 22:19:25 UTC, Jonathan M Davis wrote:
On Monday, June 26, 2023 1:09:24 PM MDT Cecil Ward via 
Digitalmars-d-learn wrote:

[...]


[...]


I completely agree with everything you said. I merely used 
aliases to give me the freedom to switch between having text in 
either UTF16 or UTF32 in memory, and see how the performance 
changes. That’s the only reason for me doing that. I also want to 
keep a clear distinction between words in me memory and code 
points in registers.


Re: Counting an initialised array, and segments

2023-06-26 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, June 26, 2023 1:09:24 PM MDT Cecil Ward via Digitalmars-d-learn 
wrote:
> No, point taken, a sloppy example. I don’t in fact do that in the
> real code. I use dchar everywhere appropriate instead of uint. In
> fact I have aliases for dstring and dchar and successfully did an
> alternative build with the aliases renamed to use 16-bits wchar /
> w string instead of 32-bits and rebuilt and all was well, just to
> test that it is code word size-independent. I would need to do
> something different though if I ever decided to change to use
> 16-bit code words in memory because I would still be wanting to
> manipulate 32-bit values for char code points when they are being
> handled in registers, for efficiency too as well as code
> correctness, as 16-bit ‘partial words’ are bad news for
> performance on x86-64. I perhaps ought to introduce a new alias
> called codepoint, which is always 32-bits, to distinguish dchar
> in registers from words in memory. It turns out that I can get
> away with not caring about utf16, as I’m merely _scanning_ a
> string. I couldn’t ever get away with changing the in-memory code
> word type to be 8-bit chars, and then using utf8 though, as I do
> occasionally deal with non-ASCII characters, and I would have to
> either preconvert the Utf8 to do the decoding, or parse 8-bit
> code words and handle the decoding myself on the fly which would
> be madness. If I have to handle utf8 data I will just preconvert
> it.

Well, I can't really comment on the details of what you're doing, since I
don't know them, but I would point out that a dchar is a code point by
definition. That is its purpose. char is a UTF-8 code unit, wchar is a
UTF-16 code unit, and dchar is both a UTF-32 code unit and a code point,
since UTF-32 code units are code points by definition. It is possible for a
dchar to be an invalid code point if you give it bad data, but code points
are 32-bit, and dchar is intended to represent that. Actual characters, of
course, can be multiple code points, annoyingly enough, so all of that
Unicode stuff is of course an annoyingly complicated mess, but D and Phobos
do have a pretty good set of primitives for handling code units and code
points without programmers needing to come up with their own types for
those. char is a UTF-8 code unit, wchar is a UTF-16 code unit, and dchar is
both a UTF-32 code unit and a code point, since UTF-32 code units are code
points by definition.

The primary mistake in what D has is that strings are all ranges of dchar
with the code units automatically being decoded to dchar by front, popFront,
etc. (at the time, Andrei thought that that would ensure correctness, since
he didn't understand that you could have characters that were multiple code
points). We'd like to get rid of that, but it's difficult to do so without
breaking code. std.utf.byCodeUnit helps work around that, and of course, you
can do so by simply operating on the strings as arrays without using the
range primitives, but the range primitives do decode to dchar,
unfortunately. However, in spite of that quirk, the tools are there to
operate on Unicode correctly in a way that don't exist out of the box with
many languages. So, in general, you shouldn't need to be creating new types
for Unicode primitives. The language already has that.

- Jonathan M Davis






Re: Counting an initialised array, and segments

2023-06-26 Thread Cecil Ward via Digitalmars-d-learn

On Monday, 26 June 2023 at 12:28:15 UTC, Jonathan M Davis wrote:
On Monday, June 26, 2023 5:08:06 AM MDT Cecil Ward via 
Digitalmars-d-learn wrote:
On Monday, 26 June 2023 at 08:26:31 UTC, Jonathan M Davis 
wrote:

> On Sunday, June 25, 2023 4:08:19 PM MDT Cecil Ward via
>
> Digitalmars-d-learn wrote:
>> I recently had some problems
>>
>> dchar[] arr = [ ‘ ‘, TAB, CR, LF … ];
>>
>> and I got errors from the compiler which led to me having to
>> count the elements in the initialiser and declare the array
>> with
>> an explicit size. I don’t want the array to be mutable so I
>> later
>> added immutable to it, but that didn’t help matters. At one
>> point, because the array was quite long, I got the arr[
>> n_elements ] number wrong, it was too small and the 
>> remainder

>> of
>> the array was full of 0xffs (or something), which was good,
>> helped me spot the bug.
>>
>> Is there any way to get the compiler to count the number of 
>> elements in the initialiser and set the array to that size 
>> ? And it’s immutable.

>
> Without seeing the errors, I can't really say what the 
> problem was, but most character literals are going to be 
> char, not dchar, so you may have had issues related to the 
> type that the compiler was inferring for the array literal. 
> I don't recall at the moment how exactly the compiler 
> decides the type of an array literal when it's given values 
> of differing types for the elements.

>
> Either way, if you want a static array, and you don't want 
> to have to count the number of elements, then 
> https://dlang.org/phobos/std_array.html#staticArray should 
> take care of that problem.

>
> - Jonathan M Davis

Where I used symbolic names, such as TAB, that was defined as 
an

int (or uint)
enum TAB = 9;
or
enum uint TAB = 9;
I forget which. So I had at least one item that was typed
something wider than a char.

I tried the usual sizeof( arr )/ sizeof dchar, compiler 
wouldn’t
have that for some reason, and yes I know it should be D 
syntax,

god how I long for C sizeof()!


sizeof is a property in D. So, you can do char.sizeof or 
varName.sizeof. But regardless, there really is no reason to 
use sizeof with D arrays under normal circumstances. And in the 
case of dynamic arrays, sizeof will give you the size of the 
dynamic array itself, not the slice of memory that it refers 
to. You're essentially using sizeof on


struct DynamicArray(T)
{
size_t length;
T* ptr;
}

which is not going to tell you anything about the memory it 
points to. The length property of an array already tells you 
the length of the array (be it static or dynamic), so using 
sizeof like you're talking about really does not apply to D.


And I wouldn't advise using uint for a character in D. That's 
what char, wchar, and dchar are for. Depending on the 
circumstances, you get implicit conversions between character 
and integer types, but they are distinct types, and mixing and 
matching them willy-nilly could result in compilation errors 
depending on what your code is doing.


- Jonathan M Davis


No, point taken, a sloppy example. I don’t in fact do that in the 
real code. I use dchar everywhere appropriate instead of uint. In 
fact I have aliases for dstring and dchar and successfully did an 
alternative build with the aliases renamed to use 16-bits wchar / 
w string instead of 32-bits and rebuilt and all was well, just to 
test that it is code word size-independent. I would need to do 
something different though if I ever decided to change to use 
16-bit code words in memory because I would still be wanting to 
manipulate 32-bit values for char code points when they are being 
handled in registers, for efficiency too as well as code 
correctness, as 16-bit ‘partial words’ are bad news for 
performance on x86-64. I perhaps ought to introduce a new alias 
called codepoint, which is always 32-bits, to distinguish dchar 
in registers from words in memory. It turns out that I can get 
away with not caring about utf16, as I’m merely _scanning_ a 
string. I couldn’t ever get away with changing the in-memory code 
word type to be 8-bit chars, and then using utf8 though, as I do 
occasionally deal with non-ASCII characters, and I would have to 
either preconvert the Utf8 to do the decoding, or parse 8-bit 
code words and handle the decoding myself on the fly which would 
be madness. If I have to handle utf8 data I will just preconvert 
it.


Re: Scope guards

2023-06-26 Thread Cecil Ward via Digitalmars-d-learn

On Monday, 26 June 2023 at 17:41:16 UTC, Paul Backus wrote:

On Saturday, 24 June 2023 at 17:00:36 UTC, Cecil Ward wrote:
I would like to use scope guards but in the guard I need to 
get access to some local variables at the end of the routine. 
This doesn’t really seem to make sense as to how it would 
work, because their values depend on the exact point where the 
scope guard is called at in the last, exiting line(s) of the 
routine. Am I misunderstanding?


Scope guards are syntax sugar for try/catch/finally. For 
example, when you write


auto f = open("foo");
scope(exit) close(f);
doSomethingWith(f);

...it gets transformed by the compiler into

auto f = open("foo");
try {
doSomethingWith(f);
} finally {
close(f);
}

I do not understand exactly what the problem is you are having, 
but hopefully this lets you figure out how to solve it.


Sorry for being stupid, but say you have something like this

==
{
size_t p = offset;
++p;
scope(exit) { writeOutput( 0, p );

++p
…
++p;

return;
}

==

The correctness of its behaviour depends on what the value of p 
is when it calls writeOutput(), and the value of p is being 
changed. To be correct, the final value of p needs to be passed 
to writeOutput( p ). That was what I was worrying about. I could 
have course introduce another variable to capture this final 
value and use that in the scope guard, but then I can’t make the 
scope guard general if I have more than one exit route. The 
compiler sounded as if it did not like the local variable p in 
the scope guard, but I need to try it again to get the error 
message.


Re: Scope guards

2023-06-26 Thread Paul Backus via Digitalmars-d-learn

On Saturday, 24 June 2023 at 17:00:36 UTC, Cecil Ward wrote:
I would like to use scope guards but in the guard I need to get 
access to some local variables at the end of the routine. This 
doesn’t really seem to make sense as to how it would work, 
because their values depend on the exact point where the scope 
guard is called at in the last, exiting line(s) of the routine. 
Am I misunderstanding?


Scope guards are syntax sugar for try/catch/finally. For example, 
when you write


auto f = open("foo");
scope(exit) close(f);
doSomethingWith(f);

...it gets transformed by the compiler into

auto f = open("foo");
try {
doSomethingWith(f);
} finally {
close(f);
}

I do not understand exactly what the problem is you are having, 
but hopefully this lets you figure out how to solve it.


Re: Counting an initialised array, and segments

2023-06-26 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, June 26, 2023 5:08:06 AM MDT Cecil Ward via Digitalmars-d-learn 
wrote:
> On Monday, 26 June 2023 at 08:26:31 UTC, Jonathan M Davis wrote:
> > On Sunday, June 25, 2023 4:08:19 PM MDT Cecil Ward via
> >
> > Digitalmars-d-learn wrote:
> >> I recently had some problems
> >>
> >> dchar[] arr = [ ‘ ‘, TAB, CR, LF … ];
> >>
> >> and I got errors from the compiler which led to me having to
> >> count the elements in the initialiser and declare the array
> >> with
> >> an explicit size. I don’t want the array to be mutable so I
> >> later
> >> added immutable to it, but that didn’t help matters. At one
> >> point, because the array was quite long, I got the arr[
> >> n_elements ] number wrong, it was too small and the remainder
> >> of
> >> the array was full of 0xffs (or something), which was good,
> >> helped me spot the bug.
> >>
> >> Is there any way to get the compiler to count the number of
> >> elements in the initialiser and set the array to that size ?
> >> And it’s immutable.
> >
> > Without seeing the errors, I can't really say what the problem
> > was, but most character literals are going to be char, not
> > dchar, so you may have had issues related to the type that the
> > compiler was inferring for the array literal. I don't recall at
> > the moment how exactly the compiler decides the type of an
> > array literal when it's given values of differing types for the
> > elements.
> >
> > Either way, if you want a static array, and you don't want to
> > have to count the number of elements, then
> > https://dlang.org/phobos/std_array.html#staticArray should take
> > care of that problem.
> >
> > - Jonathan M Davis
>
> Where I used symbolic names, such as TAB, that was defined as an
> int (or uint)
> enum TAB = 9;
> or
> enum uint TAB = 9;
> I forget which. So I had at least one item that was typed
> something wider than a char.
>
> I tried the usual sizeof( arr )/ sizeof dchar, compiler wouldn’t
> have that for some reason, and yes I know it should be D syntax,
> god how I long for C sizeof()!

sizeof is a property in D. So, you can do char.sizeof or varName.sizeof. But
regardless, there really is no reason to use sizeof with D arrays under
normal circumstances. And in the case of dynamic arrays, sizeof will give
you the size of the dynamic array itself, not the slice of memory that it
refers to. You're essentially using sizeof on

struct DynamicArray(T)
{
size_t length;
T* ptr;
}

which is not going to tell you anything about the memory it points to. The
length property of an array already tells you the length of the array (be it
static or dynamic), so using sizeof like you're talking about really does
not apply to D.

And I wouldn't advise using uint for a character in D. That's what char,
wchar, and dchar are for. Depending on the circumstances, you get implicit
conversions between character and integer types, but they are distinct
types, and mixing and matching them willy-nilly could result in compilation
errors depending on what your code is doing.

- Jonathan M Davis






Re: Counting an initialised array, and segments

2023-06-26 Thread Cecil Ward via Digitalmars-d-learn

On Monday, 26 June 2023 at 08:26:31 UTC, Jonathan M Davis wrote:
On Sunday, June 25, 2023 4:08:19 PM MDT Cecil Ward via 
Digitalmars-d-learn wrote:

I recently had some problems

dchar[] arr = [ ‘ ‘, TAB, CR, LF … ];

and I got errors from the compiler which led to me having to
count the elements in the initialiser and declare the array 
with
an explicit size. I don’t want the array to be mutable so I 
later

added immutable to it, but that didn’t help matters. At one
point, because the array was quite long, I got the arr[
n_elements ] number wrong, it was too small and the remainder 
of

the array was full of 0xffs (or something), which was good,
helped me spot the bug.

Is there any way to get the compiler to count the number of 
elements in the initialiser and set the array to that size ? 
And it’s immutable.


Without seeing the errors, I can't really say what the problem 
was, but most character literals are going to be char, not 
dchar, so you may have had issues related to the type that the 
compiler was inferring for the array literal. I don't recall at 
the moment how exactly the compiler decides the type of an 
array literal when it's given values of differing types for the 
elements.


Either way, if you want a static array, and you don't want to 
have to count the number of elements, then 
https://dlang.org/phobos/std_array.html#staticArray should take 
care of that problem.


- Jonathan M Davis


Where I used symbolic names, such as TAB, that was defined as an 
int (or uint)

enum TAB = 9;
or
enum uint TAB = 9;
I forget which. So I had at least one item that was typed 
something wider than a char.


I tried the usual sizeof( arr )/ sizeof dchar, compiler wouldn’t 
have that for some reason, and yes I know it should be D syntax, 
god how I long for C sizeof()!


Re: Counting an initialised array, and segments

2023-06-26 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, June 25, 2023 4:08:19 PM MDT Cecil Ward via Digitalmars-d-learn 
wrote:
> I recently had some problems
>
> dchar[] arr = [ ‘ ‘, TAB, CR, LF … ];
>
> and I got errors from the compiler which led to me having to
> count the elements in the initialiser and declare the array with
> an explicit size. I don’t want the array to be mutable so I later
> added immutable to it, but that didn’t help matters. At one
> point, because the array was quite long, I got the arr[
> n_elements ] number wrong, it was too small and the remainder of
> the array was full of 0xffs (or something), which was good,
> helped me spot the bug.
>
> Is there any way to get the compiler to count the number of
> elements in the initialiser and set the array to that size ? And
> it’s immutable.

Without seeing the errors, I can't really say what the problem was, but most
character literals are going to be char, not dchar, so you may have had
issues related to the type that the compiler was inferring for the array
literal. I don't recall at the moment how exactly the compiler decides the
type of an array literal when it's given values of differing types for the
elements.

Either way, if you want a static array, and you don't want to have to count
the number of elements, then
https://dlang.org/phobos/std_array.html#staticArray should take care of that
problem.

- Jonathan M Davis