Re: How can we view source code that has been generated (say via "static foreach") ?

2021-09-15 Thread james.p.leblanc via Digitalmars-d-learn

On Thursday, 16 September 2021 at 03:26:46 UTC, Tejas wrote:
On Wednesday, 15 September 2021 at 19:59:43 UTC, 
james.p.leblanc wrote:

s


Use the `mixin` compiler flag

`dmd -mixin= file.d`

Beware, this will also include **all** the mixin code from 
standard library and runtime.


But it's manageable, reflecting on my experience.


Tejas,

Thank you for your kind response.  Wow, at first the large output 
file
from a small test program was a bit surprising .., but actually 
it is

manageable to dig through to find the interesting bits.

So, this is quite useful!  Thanks again, now I am off to do some 
digging...


Best Regards,
James




Re: How can we view source code that has been generated (say via "static foreach") ?

2021-09-15 Thread Tejas via Digitalmars-d-learn
On Wednesday, 15 September 2021 at 19:59:43 UTC, james.p.leblanc 
wrote:

Dear All,

In attempting to learn and use code generation, it
would be useful to be able to view the source code
that gets generated.

However, with various combinations of templates, UDAs, and
mixins it has not been easy.

Is there some standard way this is done?

Optimal would be to print out the entire generated source
code to allow inspection.

Best Regards,
James


Use the `mixin` compiler flag

`dmd -mixin= file.d`

Beware, this will also include **all** the mixin code from 
standard library and runtime.


But it's manageable, reflecting on my experience.


Re: Program crash: GC destroys an object unexpectedly

2021-09-15 Thread jfondren via Digitalmars-d-learn

On Tuesday, 14 September 2021 at 20:59:14 UTC, Ali Çehreli wrote:

On 9/14/21 9:56 AM, eugene wrote:

> On Tuesday, 14 September 2021 at 16:43:50 UTC, jfondren wrote:

>> The misaligned pointer and the
>> reference-containing struct that vanishes on the return of
your
>> corresponding function are both problems for this.
>
> where did you find 'misaligned pointer'?...

I think it's the align(1) for EpollEvent.

I was able to reproduce the segmentation fault and was 
seemingly able to fix it by making the EventSource class 
references alive by adding a constructor:


align (1) struct EpollEvent {
align(1):
uint event_mask;
EventSource es;

  this(uint event_mask, EventSource es) {
this.event_mask = event_mask;
this.es = es;
living ~= es;  // <-- Introduced this constructor for this 
line

  }
/* just do not want to use that union, epoll_data_t */
}

// Here is the array that keeps EventSource alive:
EventSource[] living;

If that really is the fix, of course the references must be 
taken out of that container when possible.


Ali


Yep. This patch is sufficient to prevent the segfault:

```
diff --git a/engine/ecap.d b/engine/ecap.d
index 71cb646..d57829c 100644
--- a/engine/ecap.d
+++ b/engine/ecap.d
@@ -32,6 +32,7 @@ final class EventQueue {
 private int id;
 private bool done;
 private MessageQueue mq;
+private EventSource[] sources;

 private this() {
 id = epoll_create1(0);
@@ -52,6 +53,7 @@ final class EventQueue {

 void registerEventSource(EventSource es) {
 auto e = EpollEvent(0, es);
+sources ~= es;
 int r = epoll_ctl(id, EPOLL_CTL_ADD, es.id, );
 assert(r == 0, "epoll_ctl(ADD) failed");
 }
@@ -63,7 +65,10 @@ final class EventQueue {
 }

 void deregisterEventSource(EventSource es) {
+import std.algorithm : countUntil, remove;
+
 auto e = EpollEvent(0, es);
+sources = sources.remove(sources.countUntil(es));
 int r = epoll_ctl(id, EPOLL_CTL_DEL, es.id, );
 assert(r == 0, "epoll_ctl(DEL) failed");
 }
```

Going through the project and adding @safe: to the top of 
everything results in these errors: 
https://gist.github.com/jrfondren/c7f7b47be057273830d6a31372895895
some I/O, some @system functions, some weird C APIs ... and 
misaligned assignments to EpollEvent.es. So debugging with @safe 
isn't bad, but I'd still like rustc-style error codes:


```
engine/ecap.d(89): Error E415: field `EpollEvent.es` cannot 
assign to misaligned pointers in `@safe` code


$ dmd --explain E415

Yeah see, the garbage collector only looks for pointers at 
pointer-aligned addresses.

```


Re: Return complete multi-dimensional array after appending

2021-09-15 Thread eXodiquas via Digitalmars-d-learn
On Wednesday, 15 September 2021 at 21:02:29 UTC, Paul Backus 
wrote:
On Wednesday, 15 September 2021 at 20:32:12 UTC, eXodiquas 
wrote:

```d
[1,0,3,4,0,5]
.fold!((a, e) => e != 0 ? a[0] ~ e : a[1] ~ e)(cast(int[][]) 
[[],[]])

.flatten
.writeln
```
This should sort all non 0s into the `a[0]` array and all 0s 
into the `a[1]` array. But it won't work because the `~` does 
not return the whole array (which is probably better for most 
of the cases). So the question, is there a way to do this kind 
of append, but getting the whole array back as a result in std?


You need to use `~=` instead of `~` to mutate an existing array:

```d
import std;

void main()
{
[1, 0, 3, 4, 0, 5]
.fold!((a, e) {
e != 0 ? (a[0] ~= e) : (a[1] ~= e);
return a;
})(cast(int[][]) [[], []])
.joiner
.writeln;
}
```

Of course, a more idiomatic solution would be to use 
`std.algorithm.partition`:


```d
import std;

void main()
{
auto arr = [1, 0, 3, 4, 0, 5];
arr.partition!(e => e != 0); // in-place
arr.writeln;
}
```


Oooh, I totally forgot you can open blocks like this in anonymous 
functions. Now I look a bit stupid. Thanks. :) `partition` is 
also very nice. D std is so huge, I should sketch out a roadmap 
or something. That's why I asked the question in the first place 
because deep inside I knew there is a function in std that solves 
the problem.


Thanks for the answer. :)


Re: Return complete multi-dimensional array after appending

2021-09-15 Thread Paul Backus via Digitalmars-d-learn

On Wednesday, 15 September 2021 at 20:32:12 UTC, eXodiquas wrote:

```d
[1,0,3,4,0,5]
.fold!((a, e) => e != 0 ? a[0] ~ e : a[1] ~ e)(cast(int[][]) 
[[],[]])

.flatten
.writeln
```
This should sort all non 0s into the `a[0]` array and all 0s 
into the `a[1]` array. But it won't work because the `~` does 
not return the whole array (which is probably better for most 
of the cases). So the question, is there a way to do this kind 
of append, but getting the whole array back as a result in std?


You need to use `~=` instead of `~` to mutate an existing array:

```d
import std;

void main()
{
[1, 0, 3, 4, 0, 5]
.fold!((a, e) {
e != 0 ? (a[0] ~= e) : (a[1] ~= e);
return a;
})(cast(int[][]) [[], []])
.joiner
.writeln;
}
```

Of course, a more idiomatic solution would be to use 
`std.algorithm.partition`:


```d
import std;

void main()
{
auto arr = [1, 0, 3, 4, 0, 5];
arr.partition!(e => e != 0); // in-place
arr.writeln;
}
```


Return complete multi-dimensional array after appending

2021-09-15 Thread eXodiquas via Digitalmars-d-learn

Howdy everyone. :)

Today I came across a small problem (I mean, I could solve it by 
writing a function that solves my problem, but maybe there is 
something in std that can help me here). Let's say we have the 
following code:


```d
void main() {
  int[][] a = [[],[]];
  (a[0] ~ 5).writeln; // => [5]
}
```

it's quite obvious that `[5]` is printed. Because I am a fan of 
one-liners (we do small code challenges, and I want to show 
what's possible with fold) and ridiculous stuff I tried to do 
something like this:


```d
[1,0,3,4,0,5]
.fold!((a, e) => e != 0 ? a[0] ~ e : a[1] ~ e)(cast(int[][]) 
[[],[]])

.flatten
.writeln
```
This should sort all non 0s into the `a[0]` array and all 0s into 
the `a[1]` array. But it won't work because the `~` does not 
return the whole array (which is probably better for most of the 
cases). So the question, is there a way to do this kind of 
append, but getting the whole array back as a result in std?
And another question, is there a way to tell `fold` about the 
initial value of an empty list without having to cast a `void[]` 
into the list of the desired type?


Thanks in advance. :)

eXodiquas


How can we view source code that has been generated (say via "static foreach") ?

2021-09-15 Thread james.p.leblanc via Digitalmars-d-learn

Dear All,

In attempting to learn and use code generation, it
would be useful to be able to view the source code
that gets generated.

However, with various combinations of templates, UDAs, and
mixins it has not been easy.

Is there some standard way this is done?

Optimal would be to print out the entire generated source
code to allow inspection.

Best Regards,
James







Re: Was this supposed to be allowed?

2021-09-15 Thread Petar via Digitalmars-d-learn

On Wednesday, 15 September 2021 at 13:52:40 UTC, z wrote:

```D
float[2] somevalue = somefloat3value[] + cast(Unqual!float[2]) 
[somesharedfloatarray1[i],somesharedfloatarray2[ii]];

```
Older LDC/DMD releases never complained but now that i upgraded 
DMD, DMD-compiled builds suffer from runtime assert error 
`core.internal.array.operations.arrayOp!(float[], float[], 
float[], "+", "=").arrayOp at 
.\src\druntime\import\core\internal\array\operations.d(45) 
: Mismatched array lengths for vector operation `


Explicitly specifying `somefloat3value[0..2]` now works, and it 
seems that this assert check is an addition to a recent DMD 
version's `druntime`, does it means that this was a recent 
change in the language+runtime or just a retroactive 
enforcement of language rules that didn't use to be enforced?

Big thanks.


The history is roughly as follows:

* between dmd 2.065 and 2.076 (including), this used to fail at 
runtime with message "Array lengths don't match for vector 
operation: 2 != 3"
* dmd 2.077 included [druntime PR 1891][1] which was a ground-up 
re-implementation of the way array operations are implemented and 
in general a very welcome improvement. Unfortunately that PR 
didn't include checks to ensure that all arrays have equal length 
(or perhaps it had insufficient checks, I didn't dig into the 
details).
* 2020-08-04 The issue was reported: 
https://issues.dlang.org/show_bug.cgi?id=21110
* 2021-08-09 A PR that fixes the issue was merged: 
https://github.com/dlang/druntime/pull/3267

* 2021-08-09 The fix was released in 2.097.2

In summary, the validation was always supposed to be there, but 
between 2.077.0 and 2.097.1 it wasn't.


[1]: https://github.com/dlang/druntime/pull/1891


Re: uint overflow behaviour

2021-09-15 Thread DLearner via Digitalmars-d-learn

Thanks for the responses.


Was this supposed to be allowed?

2021-09-15 Thread z via Digitalmars-d-learn

```D
float[2] somevalue = somefloat3value[] + cast(Unqual!float[2]) 
[somesharedfloatarray1[i],somesharedfloatarray2[ii]];

```
Older LDC/DMD releases never complained but now that i upgraded 
DMD, DMD-compiled builds suffer from runtime assert error 
`core.internal.array.operations.arrayOp!(float[], float[], 
float[], "+", "=").arrayOp at 
.\src\druntime\import\core\internal\array\operations.d(45) : 
Mismatched array lengths for vector operation `


Explicitly specifying `somefloat3value[0..2]` now works, and it 
seems that this assert check is an addition to a recent DMD 
version's `druntime`, does it means that this was a recent change 
in the language+runtime or just a retroactive enforcement of 
language rules that didn't use to be enforced?

Big thanks.


Re: uint overflow behaviour

2021-09-15 Thread Steven Schveighoffer via Digitalmars-d-learn

On Wednesday, 15 September 2021 at 10:08:13 UTC, DLearner wrote:
Please confirm that if the addition of two uint variables 
produces a result larger than can be held in a uint:
1.  This is a D-legal operation (however inadvisable!), with 
the D-defined result of wraparound;


Definition under point 7 here : 
https://dlang.org/spec/expression.html#add_expressions


And I wouldn’t say inadvisable. It’s defined and if you have a 
good reason to allow that, then you can do that.


2.  Emphasing 1. above: the result is not undefined, or an 
error (by the rules of D), or simply implementation-dependant 
(whether by compiler or chip).


Yes

-Steve




Re: uint overflow behaviour

2021-09-15 Thread rikki cattermole via Digitalmars-d-learn

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

"7. If both operands are of integral types and an overflow or underflow 
occurs in the computation, wrapping will happen. For example, uint.max + 
1 == uint.min, uint.min - 1 == uint.max, int.max + 1 == int.min, and 
int.min - 1 == int.max."


uint overflow behaviour

2021-09-15 Thread DLearner via Digitalmars-d-learn
Please confirm that if the addition of two uint variables 
produces a result larger than can be held in a uint:
1.  This is a D-legal operation (however inadvisable!), with the 
D-defined result of wraparound;
2.  Emphasing 1. above: the result is not undefined, or an error 
(by the rules of D), or simply implementation-dependant (whether 
by compiler or chip).


Best regards