Re: Setting field of struct object

2024-05-14 Thread Menjanahary R. R. via Digitalmars-d-learn

On Monday, 22 January 2024 at 08:54:21 UTC, Danilo wrote:

On Monday, 22 January 2024 at 08:35:01 UTC, Joel wrote:

[...]


Nonetheless, this usually used with Objects (new class/struct 
instances), like so:

```d
import std;

[...]


Fluent Interface 


Re: FIFO

2024-05-14 Thread Salih Dincer via Digitalmars-d-learn

On Monday, 13 May 2024 at 15:07:39 UTC, Andy Valencia wrote:

On Sunday, 12 May 2024 at 22:03:21 UTC, Ferhat Kurtulmuş wrote:

https://dlang.org/phobos/std_container_slist.html

This is a stack, isn't it?  LIFO?

Ahh yes. Then use dlist


Thank you.  I read its source, and was curious so I wrote a 
small performance measurement: put 10,000 things in a FIFO, 
pull them back out, and loop around that 10,000 times.  My FIFO 
resulted in:


Also try the code I gave in this thread:
https://forum.dlang.org/post/fgzvdhkdyevtzznya...@forum.dlang.org

In fact, please use this facility in the standard library: 
https://dlang.org/phobos/std_datetime_stopwatch.html#benchmark


SDB@79


Re: FIFO

2024-05-13 Thread Ferhat Kurtulmuş via Digitalmars-d-learn

On Monday, 13 May 2024 at 15:07:39 UTC, Andy Valencia wrote:

On Sunday, 12 May 2024 at 22:03:21 UTC, Ferhat Kurtulmuş wrote:

https://dlang.org/phobos/std_container_slist.html

This is a stack, isn't it?  LIFO?

Ahh yes. Then use dlist


Thank you.  I read its source, and was curious so I wrote a 
small performance measurement: put 10,000 things in a FIFO, 
pull them back out, and loop around that 10,000 times.  My FIFO 
resulted in:


real0m1.589s
user0m1.585s
sys 0m0.004s

And the dlist based one:

real0m4.731s
user0m5.211s
sys 0m0.308s

Representing the FIFO as a linked list clearly has its cost, 
but I found the increased system time interesting.  OS memory 
allocations maybe?


The code is spaghetti, fifo/dlist, but it seemed the easiest 
way to see the two API's being used side by side:


version(fifo) {
import tiny.fifo : FIFO;
} else {
import std.container.dlist : DList;
}

const uint ITERS = 10_000;
const uint DEPTH = 10_000;

void
main()
{
version(fifo) {
auto d = FIFO!uint();
} else {
auto d = DList!uint();
}
foreach(_; 0 .. ITERS) {
foreach(x; 0 .. DEPTH) {
version(fifo) {
d.add(x);
} else {
d.insertBack(x);
}
}
foreach(x; 0 .. DEPTH) {
version(fifo) {
assert(x == d.next());
} else {
assert(x == d.front());
d.removeFront();
}
}
}
}


thank you for sharing the results. Everything I read about queues 
recommends doublylinked lists. With your array based 
implementatio if you are consuming the elements faster than 
pushing new elements, your array buffer never resize which is 
costly. This should explain why your array based queue is more 
performant.


Re: FIFO

2024-05-13 Thread Salih Dincer via Digitalmars-d-learn

On Monday, 13 May 2024 at 15:07:39 UTC, Andy Valencia wrote:


Representing the FIFO as a linked list clearly has its cost, 
but I found the increased system time interesting.  OS memory 
allocations maybe?


I know you want FIFO, I usually keep this on hand for fixed size 
LIFO; It can easily convert to FIFO and doesn't use LinkedList:


```d
class LIFO(T)
{
  T * element;
  size_t length, size;
  this(size_t s) {
element = cast(T*)new T[s];
length = s;
  }
  auto rewind() => size = length;

  bool empty() => !size;
  auto front() => element[size - 1];
  auto popFront() => --size;

  auto pop() => empty ? T(0) : element[--size];
  alias push = insertFront;
  auto insertFront(T value)
  in(size < length, "Stack is overflow!")
=> element[size++] = value;

  auto ref opDollar() => length;
  auto ref opIndex(size_t i) => element[i];
  auto ref opSlice(size_t first, size_t last)
=> element[first..last];

} unittest {

  enum test = 7;
  auto stack = new LIFO!size_t(test);

  assert(!stack.size);
  foreach (prime; 1..test + 1)
  {
stack.insertFront(prime);
  }
  assert(stack.size == test); // == 7

  stack.writeln(": ", stack.length); // [7, 6, 5, 4, 3, 2, 1]: 7
  stack[$/2].writeln("-", stack[0]); // 4-1


  stack.rewind();
  stack.size.write(": ["); // 10:
  while (auto next = stack.pop)
  {
if (next == 1) next.writeln("]");
else next.write(", ");
  }
  stack.size.writeln; // 0
  stack.rewind();
  assert(stack.size == test);
}

SDB@79



Re: FIFO

2024-05-13 Thread Andy Valencia via Digitalmars-d-learn

On Sunday, 12 May 2024 at 22:03:21 UTC, Ferhat Kurtulmuş wrote:

https://dlang.org/phobos/std_container_slist.html

This is a stack, isn't it?  LIFO?

Ahh yes. Then use dlist


Thank you.  I read its source, and was curious so I wrote a small 
performance measurement: put 10,000 things in a FIFO, pull them 
back out, and loop around that 10,000 times.  My FIFO resulted in:


real0m1.589s
user0m1.585s
sys 0m0.004s

And the dlist based one:

real0m4.731s
user0m5.211s
sys 0m0.308s

Representing the FIFO as a linked list clearly has its cost, but 
I found the increased system time interesting.  OS memory 
allocations maybe?


The code is spaghetti, fifo/dlist, but it seemed the easiest way 
to see the two API's being used side by side:


version(fifo) {
import tiny.fifo : FIFO;
} else {
import std.container.dlist : DList;
}

const uint ITERS = 10_000;
const uint DEPTH = 10_000;

void
main()
{
version(fifo) {
auto d = FIFO!uint();
} else {
auto d = DList!uint();
}
foreach(_; 0 .. ITERS) {
foreach(x; 0 .. DEPTH) {
version(fifo) {
d.add(x);
} else {
d.insertBack(x);
}
}
foreach(x; 0 .. DEPTH) {
version(fifo) {
assert(x == d.next());
} else {
assert(x == d.front());
d.removeFront();
}
}
}
}


Re: What prevents ImportC from using .h directly?

2024-05-13 Thread Nick Treleaven via Digitalmars-d-learn

On Sunday, 12 May 2024 at 21:34:30 UTC, Chris Piker wrote:
So, why does ImportC need *.c files exclusively?  I'm sure it 
solves a problem, but I don't know what that problem is.


Support for headers has been worked on, but had to be reverted:
https://issues.dlang.org/show_bug.cgi?id=23479


Re: Find homography in D?

2024-05-13 Thread Ferhat Kurtulmuş via Digitalmars-d-learn

On Sunday, 21 April 2024 at 14:57:33 UTC, Paolo Invernizzi wrote:

Hi,

Someone can point me to a D implementation of the classical 
OpenCV find homography matrix?


Thank you,
Paolo


Now, we can do image stitching using DCV. It needs improvements 
though.


https://github.com/libmir/dcv/tree/master/examples/imagestitchinghomography


Re: FIFO

2024-05-13 Thread Ferhat Kurtulmuş via Digitalmars-d-learn

On Saturday, 11 May 2024 at 23:44:28 UTC, Andy Valencia wrote:
I need a FIFO for a work scheduler, and nothing suitable jumped 
out at me.  I wrote the following, but as a newbie, would be 
happy to receive any suggestions or observations.  TIA!


[...]


I don't know your use case, maybe you have a similar problem I 
had to solve years ago.


https://forum.dlang.org/post/xktftztisodpngcow...@forum.dlang.org


Re: FIFO

2024-05-12 Thread Ferhat Kurtulmuş via Digitalmars-d-learn

On Sunday, 12 May 2024 at 21:08:24 UTC, Andy Valencia wrote:

On Sunday, 12 May 2024 at 19:45:44 UTC, Ferhat Kurtulmuş wrote:

On Saturday, 11 May 2024 at 23:44:28 UTC, Andy Valencia wrote:
I need a FIFO for a work scheduler, and nothing suitable 
jumped out at me.

...
https://dlang.org/phobos/std_container_slist.html


This is a stack, isn't it?  LIFO?

Andy


Ahh yes. Then use dlist


What prevents ImportC from using .h directly?

2024-05-12 Thread Chris Piker via Digitalmars-d-learn

Hi D

Import D is working quite well so far.  One limitation is that 
module definitions require a tiny *.c file which is often just:

```C
#include 
```

Creating this file is trivial and has almost no knock-on effects, 
except when dealing with single file programs. I have quite a few 
small utilities with dub headers. It would be handy if I could 
set an import path and use ImportC on the header file directly, 
skipping the small C file all together.  A specific example in my 
case follows.


Given a C-lib interface defined in the header file:
```
/usr/include/cspice/SpiceUsr.h
```

it would be neat if a dub header similar to the following worked:
```d
#!/usr/bin/env dub
/+ dub.sdl:
   name "some_app"
   cImportPaths "/usr/local/include/cspice"
+/

import SpiceUsr;

// ... source continues
```

So, why does ImportC need *.c files exclusively?  I'm sure it 
solves a problem, but I don't know what that problem is.








Re: FIFO

2024-05-12 Thread Andy Valencia via Digitalmars-d-learn

On Sunday, 12 May 2024 at 19:45:44 UTC, Ferhat Kurtulmuş wrote:

On Saturday, 11 May 2024 at 23:44:28 UTC, Andy Valencia wrote:
I need a FIFO for a work scheduler, and nothing suitable 
jumped out at me.

...
https://dlang.org/phobos/std_container_slist.html


This is a stack, isn't it?  LIFO?

Andy



Anybody know about SDL and particularly SDL_TTF initialization?

2024-05-12 Thread WhatMeWorry` via Digitalmars-d-learn

This should be trivial, right?
I've been looking at existing D repo code for hours. Can't figure 
why TTF_Init doesn't work?

It would help if I could figure out how to use SDL_GetError()

INFO: SDL loaded v2.30.2
INFO: SDL initialized: 0
INFO: TTF loaded: v2.0.14
Error Program exited with code -1073741819


  loadSDL();
  SDL_version v;
  SDL_GetVersion();
  toStdout("SDL loaded v%d.%d.%d", v.major, v.minor, v.patch);
  auto initSDL = SDL_Init(SDL_INIT_EVERYTHING);  // returns 0 on 
success

  toStdout("SDL initialized: %d", initSDL);

  auto loadTTF = loadSDLTTF();
  SDL_TTF_VERSION();
  toStdout("TTF loaded: v%d.%d.%d", v.major, v.minor, v.patch);
  auto initTTF = TTF_Init();  // SDL must be initialized before 
calls to this library


Re: FIFO

2024-05-12 Thread Ferhat Kurtulmuş via Digitalmars-d-learn

On Saturday, 11 May 2024 at 23:44:28 UTC, Andy Valencia wrote:
I need a FIFO for a work scheduler, and nothing suitable jumped 
out at me.  I wrote the following, but as a newbie, would be 
happy to receive any suggestions or observations.  TIA!


[...]


"next" is not a usual range primitive word in dlang. Why not just 
using slist.


Re: FIFO

2024-05-12 Thread Ferhat Kurtulmuş via Digitalmars-d-learn

On Saturday, 11 May 2024 at 23:44:28 UTC, Andy Valencia wrote:
I need a FIFO for a work scheduler, and nothing suitable jumped 
out at me.  I wrote the following, but as a newbie, would be 
happy to receive any suggestions or observations.  TIA!


[...]

https://dlang.org/phobos/std_container_slist.html


Re: Deprecation: foreach: loop index implicitly converted from size_t to int

2024-05-11 Thread BoQsc via Digitalmars-d-learn
A horrible alternative would be to use `alias` on `size_t` to 
make up a new pseudo-type that is more aligned with the code 
logic.


```
alias integer = size_t;
import std.stdio : writefln;

void main() {
auto arr = [
[5, 15],  // 20
[2, 3, 2, 3], // 10
[3, 6, 2, 9], // 20
];

foreach (integer i, row; arr)
{
double total = 0.0;
foreach (e; row)
total += e;

auto avg = total / row.length;
writefln("AVG [row=%d]: %.2f", i, avg);
}
}
```


FIFO

2024-05-11 Thread Andy Valencia via Digitalmars-d-learn
I need a FIFO for a work scheduler, and nothing suitable jumped 
out at me.  I wrote the following, but as a newbie, would be 
happy to receive any suggestions or observations.  TIA!


/*
 * fifo.d
 *  FIFO data structure
 */
module tiny.fifo;
import std.exception : enforce;

const uint GROWBY = 16;

/*
 * This is a FIFO, with "hd" walking forward and "tl" trailing
 *  behind:
 *tl  hd /Add here next
 *v   v
 *  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
 *
 * Mildly complicated by a module-size indexing.
 */
struct FIFO(T) {
T[] items;
ulong hd, tl, length;

void
add(T t) {
// Make more room when needed
if (this.items.length == this.length) {
assert(this.hd == this.tl);

// Add room and shuffle current contents
auto olen = this.items.length;
auto newlen = olen + GROWBY;
this.items.length = newlen;
this.tl = (this.tl + GROWBY) % newlen;

// Shuffle what we're butted up against to their
//  new position at the top of this.items[]
ulong moved = olen - this.hd;
this.items[$ - moved .. $] =
this.items[this.hd .. this.hd + moved];
}

// Add item at next position
this.items[hd] = t;
this.hd = (this.hd + 1) % this.items.length;
this.length += 1;
}

// Give back next
T
next() {
enforce(this.length > 0, "next() from empty FIFO");
this.length -= 1;
auto res = this.items[this.tl];
this.tl = (this.tl + 1) % this.items.length;
return res;
}
}

unittest {
auto f = FIFO!uint();
f.add(1);
f.add(2);
f.add(3);
assert(f.next() == 1);
assert(f.next() == 2);
assert(f.next() == 3);
assert(f.length == 0);

// Now overflow several times
f = FIFO!uint();
foreach(x; 0 .. GROWBY * 3 + GROWBY/2) {
f.add(x);
}
foreach(x; 0 .. GROWBY * 3 + GROWBY/2) {
assert(f.next() == x);
}
assert(f.length == 0);
}

version(unittest) {
void
main()
{
}
}


Re: How to load a DLL file in D?

2024-05-11 Thread Lance Bachmeier via Digitalmars-d-learn

On Saturday, 11 May 2024 at 20:04:38 UTC, Lance Bachmeier wrote:

On Saturday, 11 May 2024 at 19:33:03 UTC, solidstate1991 wrote:
I know that BindBC exists and otherwise would use it, but the 
bigger the library, the more extra hurdle it'll have. When I 
did a few bindings with it, I had to order the functions the 
right way, so I could do things much quicker with the 
Ctrl+Alt+Shift trick under VSCode, and even then having to 
write both a statically linked and dynamically linked version 
(the latter which required the functions to be loaded 
individually into function pointers).


Maybe I should write some automation tool...


You might find this package useful 
https://code.dlang.org/packages/dynamic


Also relevant if they're C functions: 
https://forum.dlang.org/post/qxctappnigkwvaqak...@forum.dlang.org


And this if you want to convert C headers to D code: 
https://forum.dlang.org/post/ugvc3o$5t3$1...@digitalmars.com


Re: How to load a DLL file in D?

2024-05-11 Thread Lance Bachmeier via Digitalmars-d-learn

On Saturday, 11 May 2024 at 19:33:03 UTC, solidstate1991 wrote:
I know that BindBC exists and otherwise would use it, but the 
bigger the library, the more extra hurdle it'll have. When I 
did a few bindings with it, I had to order the functions the 
right way, so I could do things much quicker with the 
Ctrl+Alt+Shift trick under VSCode, and even then having to 
write both a statically linked and dynamically linked version 
(the latter which required the functions to be loaded 
individually into function pointers).


Maybe I should write some automation tool...


You might find this package useful 
https://code.dlang.org/packages/dynamic


Re: Why is Phobos `Flag` so overthought ?

2024-05-11 Thread cc via Digitalmars-d-learn

On Thursday, 9 May 2024 at 18:48:12 UTC, Nick Treleaven wrote:
 We have a tool in our box already called `true` and that 
solves the problem.  If we had to type out the full name of 
every argument passed to every function ever written we may as 
well just adopt ObjC Cocoa style and call it 
StopWatchWithAutoStartBool().


Strawman.


Not at all.  I mean exactly that.  Why do you believe this 
function is so important it needs to have its argument type 
explicitly stated, when most functions don't?  Either that, or 
you believe all functions should.  It's arbitrary and pointless.


Re: "in" operator gives a pointer result from a test against an Associative Array?

2024-05-10 Thread Andy Valencia via Digitalmars-d-learn

On Friday, 10 May 2024 at 16:33:53 UTC, Nick Treleaven wrote:
Arrays evaluate to true in boolean conditions if their `.ptr` 
field is non-null. This is bug-prone and I hope we can remove 
this in the next edition.

...
A string literal's `.ptr` field is always non-null, because it 
is null-terminated.


Thank you!

Andy


Re: "in" operator gives a pointer result from a test against an Associative Array?

2024-05-10 Thread Nick Treleaven via Digitalmars-d-learn

On Friday, 10 May 2024 at 15:23:39 UTC, Andy Valencia wrote:
On Friday, 10 May 2024 at 03:07:43 UTC, Steven Schveighoffer 
wrote:
Yes, we say that a type has "truthiness" if it can be used in 
a condition (`while`, `if`, `assert`, etc).


So if I may ask for one more small clarification... WRT 
"truthiness", I've observed that empty arrays are treated as 
false, non-empty as true.


Arrays evaluate to true in boolean conditions if their `.ptr` 
field is non-null. This is bug-prone and I hope we can remove 
this in the next edition.


However, although I thought a string was basically an immutable 
array of characters, "" is treated as true, not false?


A string literal's `.ptr` field is always non-null, because it is 
null-terminated.


Re: "in" operator gives a pointer result from a test against an Associative Array?

2024-05-10 Thread Andy Valencia via Digitalmars-d-learn
On Friday, 10 May 2024 at 03:07:43 UTC, Steven Schveighoffer 
wrote:
Yes, we say that a type has "truthiness" if it can be used in a 
condition (`while`, `if`, `assert`, etc).


So if I may ask for one more small clarification... WRT 
"truthiness", I've observed that empty arrays are treated as 
false, non-empty as true.  However, although I thought a string 
was basically an immutable array of characters, "" is treated as 
true, not false?


Thanks again,
Andy



Re: D doesn't have weak references. So how can I make a associative array of objects without preventing their destruction?

2024-05-10 Thread evilrat via Digitalmars-d-learn

On Friday, 10 May 2024 at 13:27:40 UTC, Dukc wrote:

Steven Schveighoffer kirjoitti 10.5.2024 klo 16.01:

On Friday, 10 May 2024 at 11:05:28 UTC, Dukc wrote:
This also gets inferred as `pure` - meaning that if you use 
it twice for the same `WeakRef`, the compiler may reuse the 
result of the first dereference for the second call, without 
checking whether the referred value has changed!


This would be weak pure since the reference is mutable. This 
cannot be memoized.


The difference is the type. With a pointer parameter (both a 
bare one and one in a struct), the compiler can cache the 
result only when the pointed data is similar. However, here we 
have an integer parameter. It can be cached if it itself is 
similar to the one in the other function call. The compiler 
doesn't have to know, nor can know, when a `size_t` is a 
pointer in disguise.


This why I would just use ref counting if I were the topic 
author, trying to be smart will often comes back when one doesn't 
expect.


And as stated by previous author if the goal is to have 
self-clearable weak reference it will need some infrastructure 
anyway, so tbh this will greatly outweight any possible benefits 
of having weak refs.


Re: D doesn't have weak references. So how can I make a associative array of objects without preventing their destruction?

2024-05-10 Thread Dukc via Digitalmars-d-learn

Steven Schveighoffer kirjoitti 10.5.2024 klo 16.01:

On Friday, 10 May 2024 at 11:05:28 UTC, Dukc wrote:
This also gets inferred as `pure` - meaning that if you use it twice 
for the same `WeakRef`, the compiler may reuse the result of the first 
dereference for the second call, without checking whether the referred 
value has changed!


This would be weak pure since the reference is mutable. This cannot be 
memoized.


The difference is the type. With a pointer parameter (both a bare one 
and one in a struct), the compiler can cache the result only when the 
pointed data is similar. However, here we have an integer parameter. It 
can be cached if it itself is similar to the one in the other function 
call. The compiler doesn't have to know, nor can know, when a `size_t` 
is a pointer in disguise.


Re: D doesn't have weak references. So how can I make a associative array of objects without preventing their destruction?

2024-05-10 Thread Steven Schveighoffer via Digitalmars-d-learn

On Friday, 10 May 2024 at 11:05:28 UTC, Dukc wrote:



This also gets inferred as `pure` - meaning that if you use it 
twice for the same `WeakRef`, the compiler may reuse the result 
of the first dereference for the second call, without checking 
whether the referred value has changed!


This would be weak pure since the reference is mutable. This 
cannot be memoized.


-Steve


Re: D doesn't have weak references. So how can I make a associative array of objects without preventing their destruction?

2024-05-10 Thread Dukc via Digitalmars-d-learn

evilrat kirjoitti 9.5.2024 klo 18.19:

```d
struct WeakRef(T) {
     private size_t _handle; // same size as a pointer

     this(T* ptr) {
     _handle = cast(size_t) ptr;
     }

     T* getRef() {
     return cast(T*) _handle;
     }

     // do the rest ...
}
```

[1] https://code.dlang.org/packages/automem


There is a hidden danger with using this struct. Since `getRef` is a 
template, it will be inferred as `pure`. Now, consider a function using it:


```D
auto derefer(WeakrefT)(WeakrefT wr) => *wr.getRef;
```

This also gets inferred as `pure` - meaning that if you use it twice for 
the same `WeakRef`, the compiler may reuse the result of the first 
dereference for the second call, without checking whether the referred 
value has changed!


You probably should add some never-executed dummy operation to `getRef` 
that prevents it from becoming `pure` if you go with this design.


Re: moving from classical lex/yacc to pegged parser

2024-05-10 Thread Dukc via Digitalmars-d-learn

Dmitry Ponyatov kirjoitti 9.5.2024 klo 11.30:
> And I also can't figure out how to inherit `ParseTree` with all my 
script language objects to get AST right from pegged parser. Should I 
use some superloop with lot of matches to process parsed `pt` tree into 
something I need myself, to drop all unneeded parsing meta info and get 
clean semantic AST?


Pegged can help you with that filtering part, at least to some extent. 
Remember you can use : and ; prefix operators in the grammar spec, and 
Pegged will drop the needless nodes for you.


Or do the reverse, use ^ prefix operator (or write a new rule) to make a 
node out of Pegged builtins.


Re: "in" operator gives a pointer result from a test against an Associative Array?

2024-05-09 Thread Steven Schveighoffer via Digitalmars-d-learn

On Friday, 10 May 2024 at 01:00:09 UTC, Andy Valencia wrote:

On Friday, 10 May 2024 at 00:40:01 UTC, Meta wrote:
Yes. The reason for this is that it avoids having to 
essentially do the same check twice. If `in` returned a bool 
instead of a pointer, after checking for whether the element 
exists (which requires searching for the element in the 
associative array), you'd then have to actually *get* it from 
the array, which would require searching again. Returning a 
pointer to the element if it exists (or `null` if it doesn't) 
cuts this down to 1 operation.


Looking at Programming in D section 28.5, I'm guessing that 
pointer versus null is treated as the appropriate boolean value 
when consumed by an "if" test.  So that example is getting a 
pointer to a string, or null, but the example looks exactly as 
the same as if it had directly gotten a bool.


Yes, we say that a type has "truthiness" if it can be used in a 
condition (`while`, `if`, `assert`, etc).


For a pointer, `null` is considered "false", whereas any other 
value is considered "true". So you can use statements like 
`if(key in aa)` to test for membership. A very nice idiom is to 
check if a key is in an associative array, and if so, use the 
value that it maps to:


```d
if(auto v = key in aa) {
   // use *v as the value here
}
```

You can change your code to `return (e in this.members) !is null;`

-Steve


Re: "in" operator gives a pointer result from a test against an Associative Array?

2024-05-09 Thread Andy Valencia via Digitalmars-d-learn

On Friday, 10 May 2024 at 00:40:01 UTC, Meta wrote:
Yes. The reason for this is that it avoids having to 
essentially do the same check twice. If `in` returned a bool 
instead of a pointer, after checking for whether the element 
exists (which requires searching for the element in the 
associative array), you'd then have to actually *get* it from 
the array, which would require searching again. Returning a 
pointer to the element if it exists (or `null` if it doesn't) 
cuts this down to 1 operation.


Looking at Programming in D section 28.5, I'm guessing that 
pointer versus null is treated as the appropriate boolean value 
when consumed by an "if" test.  So that example is getting a 
pointer to a string, or null, but the example looks exactly as 
the same as if it had directly gotten a bool.


Thank you!
Andy



Re: "in" operator gives a pointer result from a test against an Associative Array?

2024-05-09 Thread Meta via Digitalmars-d-learn

On Friday, 10 May 2024 at 00:18:16 UTC, Andy Valencia wrote:
tst7.d(6): Error: cannot implicitly convert expression `e in 
this.members` of type `bool*` to `bool`
tst7.d(15): Error: template instance `tst7.Foo!uint` error 
instantiating


I'm getting this for this bit of source (trimmed from the 
bigger code).  I switched to this.members.get(e, false) and 
that works fine, but I'm still curious:


struct Foo(T) {
bool[T] members;

bool
has(T e) {
return (e in this.members);
}
}

void
main()
{
import std.stdio : writeln;

auto t = Foo!uint();
writeln(t.has(123));
}


Yes. The reason for this is that it avoids having to essentially 
do the same check twice. If `in` returned a bool instead of a 
pointer, after checking for whether the element exists (which 
requires searching for the element in the associative array), 
you'd then have to actually *get* it from the array, which would 
require searching again. Returning a pointer to the element if it 
exists (or `null` if it doesn't) cuts this down to 1 operation.


"in" operator gives a pointer result from a test against an Associative Array?

2024-05-09 Thread Andy Valencia via Digitalmars-d-learn
tst7.d(6): Error: cannot implicitly convert expression `e in 
this.members` of type `bool*` to `bool`
tst7.d(15): Error: template instance `tst7.Foo!uint` error 
instantiating


I'm getting this for this bit of source (trimmed from the bigger 
code).  I switched to this.members.get(e, false) and that works 
fine, but I'm still curious:


struct Foo(T) {
bool[T] members;

bool
has(T e) {
return (e in this.members);
}
}

void
main()
{
import std.stdio : writeln;

auto t = Foo!uint();
writeln(t.has(123));
}


Re: Why is Phobos `Flag` so overthought ?

2024-05-09 Thread Nick Treleaven via Digitalmars-d-learn

On Wednesday, 8 May 2024 at 10:24:07 UTC, Nick Treleaven wrote:
Named arguments are optional, so I don't see how they could 
make Flag redundant.


Actually, an external tool could detect when a bool is passed as 
an argument to a function and warn when not done with a named 
argument. This would free library APIs from having to use Flag 
when some users don't care about it. The cost would come in a bit 
more build system complexity/build time, which might mean a lot 
less enforcement due to inertia. Though maybe a reasonable 
trade-off.


Re: Why is Phobos `Flag` so overthought ?

2024-05-09 Thread Nick Treleaven via Digitalmars-d-learn

On Thursday, 9 May 2024 at 13:40:56 UTC, cc wrote:
It's pointless mandatory verbosity.  StopWatch ctor only takes 
one boolean argument.  It doesn't *need* to specify what it 
relates to.  You either already know, or you have to look it up 
anyway.  Flags made sense when you might get the order of 
multiple bools confused, but if there's only one, *or* if you 
can use named arguments to avoid ambiguity,


So you have justified Flag.

there's no point in demanding every parameter be a unique type. 
 It's easy to remember I can pass a bool to a StopWatch to 
autostart it.


But perhaps true means manual start? Remembering can also be used 
to justify dynamic typing outside of hot loops, I'd rather not 
rely on remembering with a big team of programmers working on a 
project.


It's less easy to remember that a specific unique type needs to 
be used, and remembering whether the name/casing of that type 
was Start, StartNow, StartAuto, Autostart, AutoStart, 
autostart, autoStart, etc.


So just pass it true, and run the compiler. The compiler will 
tell you what the correct type is.


 We have a tool in our box already called `true` and that 
solves the problem.  If we had to type out the full name of 
every argument passed to every function ever written we may as 
well just adopt ObjC Cocoa style and call it 
StopWatchWithAutoStartBool().


Strawman.


Re: D doesn't have weak references. So how can I make a associative array of objects without preventing their destruction?

2024-05-09 Thread evilrat via Digitalmars-d-learn

On Thursday, 9 May 2024 at 00:39:49 UTC, Liam McGillivray wrote:


What's a good way I can achieve what I'm trying to do, using 
either reference counting or a garbage-collected object?


There is libraries like `automem`[1] that implements refcounting 
and more.
Without showing your code for ref counted struct we can't help 
you.


As for weak references, maybe you could "trick" the GC by using 
the fact that simple types are not scanned, i.e. do something 
like this but I have no idea if this is going to work at all, 
alternatively you can also try using `ubyte[size_t.sizeof]`.


Keep in mind that classes is already references so you don't need 
that extra pointer for classes, can be versioned with template 
specialization.


```d
struct WeakRef(T) {
private size_t _handle; // same size as a pointer

this(T* ptr) {
_handle = cast(size_t) ptr;
}

T* getRef() {
return cast(T*) _handle;
}

// do the rest ...
}
```

[1] https://code.dlang.org/packages/automem


Re: Why is Phobos `Flag` so overthought ?

2024-05-09 Thread cc via Digitalmars-d-learn

On Wednesday, 8 May 2024 at 10:24:07 UTC, Nick Treleaven wrote:

On Wednesday, 8 May 2024 at 04:27:13 UTC, cc wrote:
It doesn't allow a simple boolean to be used as an argument, 
or any other Flag as they are different instantiations of a 
template rather than equivalent aliases.
It is however awful, cumbersome, annoying design and needs to 
be completely phased out now that we have named arguments.


Flag enforces that the argument says what it relates to. `true` 
does not say what it relates to. Named arguments are optional, 
so I don't see how they could make Flag redundant.


It's pointless mandatory verbosity.  StopWatch ctor only takes 
one boolean argument.  It doesn't *need* to specify what it 
relates to.  You either already know, or you have to look it up 
anyway.  Flags made sense when you might get the order of 
multiple bools confused, but if there's only one, *or* if you can 
use named arguments to avoid ambiguity, there's no point in 
demanding every parameter be a unique type.  It's easy to 
remember I can pass a bool to a StopWatch to autostart it.  It's 
less easy to remember that a specific unique type needs to be 
used, and remembering whether the name/casing of that type was 
Start, StartNow, StartAuto, Autostart, AutoStart, autostart, 
autoStart, etc.  We have a tool in our box already called `true` 
and that solves the problem.  If we had to type out the full name 
of every argument passed to every function ever written we may as 
well just adopt ObjC Cocoa style and call it 
StopWatchWithAutoStartBool().


moving from classical lex/yacc to pegged parser

2024-05-09 Thread Dmitry Ponyatov via Digitalmars-d-learn
Using lex/yacc I can do a more or less complex things in .yacc 
semantic actions, such complex as bytecode compilation or real 
CPU assembly.


Playing with `pegged`, I can't figure out how to move from 
`ParseTree` to such like semantic actions. I even can't parse 
numbers from strings in lexer-like rules because it looks like 
every rule runs on any token parse, or sumething like this.


Also, I use attribute object trees resemble attribute grammar 
both for parsing and internal code representation:


```C++
class Object {
  string   value; // or `int value` and `float value` 
for numbers

  map attr;
  vector  nested;
}
```

And I also can't figure out how to inherit `ParseTree` with all 
my script language objects to get AST right from pegged parser. 
Should I use some superloop with lot of matches to process parsed 
`pt` tree into something I need myself, to drop all unneeded 
parsing meta info and get clean semantic AST?


D doesn't have weak references. So how can I make a associative array of objects without preventing their destruction?

2024-05-08 Thread Liam McGillivray via Digitalmars-d-learn
A "weak reference" (in the sense that I'm referring to) is a 
feature in some programming languages for a reference to an 
object that doesn't prevent the GC from destroying that object.


My current understanding is that D doesn't have weak references, 
though I've found some posts in this forum from many years back 
that mention something called "weakref". So is weakref a real 
thing, or just a concept that never got implemented?


The functionality that I'm going to describe would be easy with 
weak references, but I don't know how I would implement it 
without it. If there is a way to implement it without it, I would 
like to know how. I am going to describe my specific example, but 
it may apply to any class that's initialized using contents of a 
file without any of that data being modified after.


In my particular case, the class I've created is a wrapper for 
the `Texture2D` struct in Raylib. This class holds an image that 
was loaded from a file.


```
Sprite[string] spritesByPath;

Sprite getSprite(string path) {
path = path.asAbsolutePath;

if (path !in spritesByPath) {
spritesByPath[path] = new Sprite(path);
}

return spritesByPath[path];
}

class Sprite
{
Texture2D texture;
alias this = texture;
string path;

this(string path) {
texture = LoadTexture(path.toStringz);
this.path = path;
}

~this() {
if (IsWindowReady) UnloadTexture(texture);
if (path in spritesByPath) spritesByName.remove(path);
}
}
```

Alternatively, `spritesByPath` and `getSprite` may be static 
members of `Sprite`.


If D had weak references, than `spritesByPath` would be made of 
weak references so that they don't prevent the destruction of 
`Sprite` objects, which should be destroyed whenever they don't 
have any references elsewhere.


I've considered making `Sprite` reference-counted, but I couldn't 
manage to figure out how to do it properly. I tried doing 
`SafeRefCounted!Sprite` but the compiler said it doesn't work on 
`Object` types. I then tried making my own struct for reference 
counting that would be placed in place of a direct reference to 
the `Sprite` object, but there was some bug in which sometimes it 
didn't increment the reference count, so it didn't work.


What's a good way I can achieve what I'm trying to do, using 
either reference counting or a garbage-collected object?


Re: How can I put the current value of a variable into a delegate?

2024-05-08 Thread Liam McGillivray via Digitalmars-d-learn

On Wednesday, 8 May 2024 at 12:29:05 UTC, Rene Zwanenburg wrote:
Interestingly enough C# used to have the same behaviour but MS 
decided to go for a breaking change in C# 5; now it behaves as 
most people expect.


Wow! I wonder if D would be willing to allow such a breaking 
change with the release of Phobos 3. My choice would be to have 
it use the current value by default for value types, but allow 
them to be linked to the same memory address using `*&` when the 
variable is placed in a delegate. I think that the distinction 
between value types and reference types should be consistent.


If such a breaking change isn't considered acceptable, I suppose 
a new operator can be introduced for dereferencing a variable 
when placed in a delegate. Maybe `#` or `$` if they don't 
conflict with any existing use of those symbols.


Re: How can I put the current value of a variable into a delegate?

2024-05-08 Thread Liam McGillivray via Digitalmars-d-learn

On Monday, 6 May 2024 at 16:41:38 UTC, Steven Schveighoffer wrote:

On Monday, 6 May 2024 at 06:29:49 UTC, Liam McGillivray wrote:
Delegates can be a pain, as they often have results different 
from what one would intuitively expect. This can easily result 
in bugs.


Here's a line that caused a bug that took me awhile to find:
```
foreach(card; unitCards) card.submitted = delegate() => 
selectUnit(card.unit);

```

Each `UnitInfoCard` object (which `card` is a member of) 
contains a `Unit` object called `unit`. The intention of this 
line was that each object in `unitCards` would call 
`selectUnit` with it's own `unit` every time it calls 
`submitted`. Instead, every card calls `submitted` with the 
*last* value of `card`.


Yes, this is because the foreach loop reuses the same memory 
slot for `card`.


Even though this is allocated as a closure, it still only 
allocates the frame stack of the *enclosing function*, and does 
not allocate a new slot for each loop iteration.


You can force this by using a lambda which allocates the 
closure:


```d
foreach(card; unitCards)
card.submitted = (c2) { return () => selectUnit(c2.unit); 
}(card);

```

This is a lambda which accepts `card` as a parameter, and 
returns an appropriate delegate. It is important to use a 
parameter, because if you just use card inside there, it's 
still using the single stack frame of the calling function!


...

I would love to see a solution, but the workaround at least 
exists!


-Steve


Well that's something. It's not a very good solution for a 
language that aims for readability. It took me awhile looking at 
it to figure out what it is about, as I'm not familiar with this 
syntax.


The solution that I did before seeing this was to add a function 
to `UnitInfoCard` to give it a delegate with a `Unit unit` 
parameter, and then that function would give that function with 
the `unit` parameter set to itself to it's own `submitted` 
member. I will probably keep it like this for readability.


```
void clickAction(void delegate(Unit) @safe clickAction) {
submitted = () => clickAction(unit);
}
```


Re: How can I put the current value of a variable into a delegate?

2024-05-08 Thread Rene Zwanenburg via Digitalmars-d-learn

On Monday, 6 May 2024 at 16:41:38 UTC, Steven Schveighoffer wrote:
This is a very old issue: 
https://issues.dlang.org/show_bug.cgi?id=2043 since "moved" to 
https://issues.dlang.org/show_bug.cgi?id=23136


I would love to see a solution, but the workaround at least 
exists!


-Steve


Interestingly enough C# used to have the same behaviour but MS 
decided to go for a breaking change in C# 5; now it behaves as 
most people expect.


Since it's an unsolved problem to keep links working for 10+ 
years I gave up looking for something official about the subject. 
Here's an SO question about it though:


https://stackoverflow.com/questions/14184515/action-delegate-uses-the-last-values-of-variables-declared-outside-foreach-loop




Re: Why is Phobos `Flag` so overthought ?

2024-05-08 Thread Dukc via Digitalmars-d-learn

Nick Treleaven kirjoitti 8.5.2024 klo 13.24:

On Wednesday, 8 May 2024 at 04:27:13 UTC, cc wrote:
It doesn't allow a simple boolean to be used as an argument, or any 
other Flag as they are different instantiations of a template rather 
than equivalent aliases.
It is however awful, cumbersome, annoying design and needs to be 
completely phased out now that we have named arguments.


Flag enforces that the argument says what it relates to. `true` does not 
say what it relates to. Named arguments are optional, so I don't see how 
they could make Flag redundant.


Well,

```D
private struct Undefinable{}

auto functionTakingFlags
(   int normalArg,
Undefinable = Undefinable.init,
bool Flag1,
Undefinable = Undefinable.init,
bool Flag2
){  // fun body...
}
```

As I understand it, this forces the client to use named arguments 
because they would be trying to pass an `Undefinable` otherwise. They 
probably could pass `Undefinable` if they really wanted and therefore 
avoid using named args but they wouldn't do that accidentally.


Whether that is any better than the library `Flag` type is up to taste.


Re: Why is Phobos `Flag` so overthought ?

2024-05-08 Thread Nick Treleaven via Digitalmars-d-learn

On Wednesday, 8 May 2024 at 04:27:13 UTC, cc wrote:
It doesn't allow a simple boolean to be used as an argument, or 
any other Flag as they are different instantiations of a 
template rather than equivalent aliases.
It is however awful, cumbersome, annoying design and needs to 
be completely phased out now that we have named arguments.


Flag enforces that the argument says what it relates to. `true` 
does not say what it relates to. Named arguments are optional, so 
I don't see how they could make Flag redundant.


Re: Why is Phobos `Flag` so overthought ?

2024-05-07 Thread cc via Digitalmars-d-learn

On Monday, 6 May 2024 at 17:55:49 UTC, user1234 wrote:

I think this just works:

```d
enum Flag : bool
{
no,
yes
}
```
...
must be a reason but I cant find it RN ;)


In "properly" designed Phobos packages, it's unambiguous.  Take 
for example std.datetime.stopwatch:


```d
import std.typecons : Flag;
alias AutoStart = Flag!"autoStart";
alias MyOtherFlag = Flag!"myOtherFlag";
...
//auto sw = StopWatch(true); // Not allowed
//auto sw = StopWatch(MyOtherFlag.yes); // Not allowed
auto sw = StopWatch(AutoStart.yes);
```
It doesn't allow a simple boolean to be used as an argument, or 
any other Flag as they are different instantiations of a template 
rather than equivalent aliases.
It is however awful, cumbersome, annoying design and needs to be 
completely phased out now that we have named arguments.


Re: TIL: statically initializing an Associative Array

2024-05-06 Thread Andy Valencia via Digitalmars-d-learn
On Tuesday, 7 May 2024 at 01:14:24 UTC, Steven Schveighoffer 
wrote:

On Tuesday, 7 May 2024 at 00:10:27 UTC, Andy Valencia wrote:
I had a set of default error messages to go with error code 
numbers, and did something along the lines of:


string[uint] error_text = [
400: "A message",
401: "A different message"
];

and got "expression  is not a constant"

...
This was fixed [in 
2.106.0](https://dlang.org/changelog/2.106.0.html#dmd.static-assoc-array)


 please upgrade your compiler.


I'm using ldc2 from Debian stable; great news that it's fixed as 
of late 2023.  I'll probably live with my workaround, but it's 
good to know that it's a bug which has been resolved.


Thank you!
Andy



Re: TIL: statically initializing an Associative Array

2024-05-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On Tuesday, 7 May 2024 at 00:10:27 UTC, Andy Valencia wrote:
I had a set of default error messages to go with error code 
numbers, and did something along the lines of:


string[uint] error_text = [
400: "A message",
401: "A different message"
];

and got "expression  is not a constant"

I eventually found this discussion:
https://issues.dlang.org/show_bug.cgi?id=6238

I understand that it's problematic, but a message which makes 
it clearer that compile-time initialization of global AA's are 
not supported?  Because it cost me about a half hour trying to 
figure out what I was doing wrong.


This error message was changed in 2.101.x (unsure which point 
release):


```
onlineapp.d(1): Error: static initializations of associative 
arrays is not allowed.
onlineapp.d(1):associative arrays must be initialized at 
runtime: 
https://dlang.org/spec/hash-map.html#runtime_initialization

```



(My workaround was to initialize the data structure once during 
app startup.)


This was fixed [in 
2.106.0](https://dlang.org/changelog/2.106.0.html#dmd.static-assoc-array)


 please upgrade your compiler.

-Steve


Re: TIL: statically initializing an Associative Array

2024-05-06 Thread matheus via Digitalmars-d-learn

On Tuesday, 7 May 2024 at 01:02:04 UTC, matheus wrote:

On Tuesday, 7 May 2024 at 00:10:27 UTC, Andy Valencia wrote:
...
Based on what I understood and that issue, I think it was fixed:
...


By the way it works as immutable too.

Matheus.




Re: TIL: statically initializing an Associative Array

2024-05-06 Thread matheus via Digitalmars-d-learn

On Tuesday, 7 May 2024 at 00:10:27 UTC, Andy Valencia wrote:
I had a set of default error messages to go with error code 
numbers, and did something along the lines of:


string[uint] error_text = [
400: "A message",
401: "A different message"
];

and got "expression  is not a constant"

I eventually found this discussion:
https://issues.dlang.org/show_bug.cgi?id=6238

I understand that it's problematic, but a message which makes 
it clearer that compile-time initialization of global AA's are 
not supported?  Because it cost me about a half hour trying to 
figure out what I was doing wrong.


(My workaround was to initialize the data structure once during 
app startup.)


Based on what I understood and that issue, I think it was fixed:

import std.stdio;

string[uint] aa1 = [1:"ABC",2:"DEF"];

void main(){
auto aa2 = ['A':1,'B':2];

writeln(aa1[1]);
writeln(aa1[2]);
writeln(aa2['A']);
writeln(aa2['B']);
}

Prints:

ABC
DEF
1
2

Matheus.


TIL: statically initializing an Associative Array

2024-05-06 Thread Andy Valencia via Digitalmars-d-learn
I had a set of default error messages to go with error code 
numbers, and did something along the lines of:


string[uint] error_text = [
400: "A message",
401: "A different message"
];

and got "expression  is not a constant"

I eventually found this discussion:
https://issues.dlang.org/show_bug.cgi?id=6238

I understand that it's problematic, but a message which makes it 
clearer that compile-time initialization of global AA's are not 
supported?  Because it cost me about a half hour trying to figure 
out what I was doing wrong.


(My workaround was to initialize the data structure once during 
app startup.)




Re: Why is Phobos `Flag` so overthought ?

2024-05-06 Thread user1234 via Digitalmars-d-learn

On Monday, 6 May 2024 at 18:06:53 UTC, Julian Fondren wrote:

On Monday, 6 May 2024 at 17:55:49 UTC, user1234 wrote:

I think this just works:

```d
enum Flag : bool
{
no,
yes
}

alias AllowVancancy = Flag; // example usage
```


```d
import std.stdio : writeln;

enum Flag : bool { no, yes }
alias Traditional = Flag;
alias Color = Flag;

void hello(Traditional traditional, Color color) {
if (traditional && color) {
writeln("\x1b[31;1mhello world\x1b[0m");
} else if (traditional && !color) {
writeln("hello world");
} else if (!traditional && color) {
writeln("\x1b[31;1mHello, world!\x1b[0m");
} else {
writeln("Hello, world!");
}
}

void main() {
hello(Color.yes, Traditional.yes); // this is wrong, but 
accepted

}
```


Ah yes I see, strongly typed bools.
Thanks .




Re: Why is Phobos `Flag` so overthought ?

2024-05-06 Thread Julian Fondren via Digitalmars-d-learn

On Monday, 6 May 2024 at 17:55:49 UTC, user1234 wrote:

I think this just works:

```d
enum Flag : bool
{
no,
yes
}

alias AllowVancancy = Flag; // example usage
```


```d
import std.stdio : writeln;

enum Flag : bool { no, yes }
alias Traditional = Flag;
alias Color = Flag;

void hello(Traditional traditional, Color color) {
if (traditional && color) {
writeln("\x1b[31;1mhello world\x1b[0m");
} else if (traditional && !color) {
writeln("hello world");
} else if (!traditional && color) {
writeln("\x1b[31;1mHello, world!\x1b[0m");
} else {
writeln("Hello, world!");
}
}

void main() {
hello(Color.yes, Traditional.yes); // this is wrong, but 
accepted

}
```


Why is Phobos `Flag` so overthought ?

2024-05-06 Thread user1234 via Digitalmars-d-learn

I think this just works:

```d
enum Flag : bool
{
no,
yes
}

alias AllowVancancy = Flag; // example usage
```

Also this is completion friendly whereas Phobos version does not 
permit DCD completion as it's based on opDispatch.


Compare to phobos version:

```d
template Flag(string name) {
enum Flag : bool
{
no = false,
yes = true
}
}

struct Yes
{
template opDispatch(string name)
{
enum opDispatch = Flag!name.yes;
}
}

struct No
{
template opDispatch(string name)
{
enum opDispatch = Flag!name.no;
}
}
```

must be a reason but I cant find it RN ;)


Re: Phobos function to remove all occurances from dynamic array?

2024-05-06 Thread Lance Bachmeier via Digitalmars-d-learn
On Wednesday, 1 May 2024 at 15:18:03 UTC, Steven Schveighoffer 
wrote:
On Wednesday, 1 May 2024 at 01:09:33 UTC, Liam McGillivray 
wrote:
This is presumably such a common task that I'm surprised it 
isn't easy to find the answer by searching;


Is there a standard library function that removes all elements 
from a dynamic array that matches an input argument?


In `std.array` there's the `replace` function which is 
supposed to replace all occurrences that match an input with 
another. It seems to work as described on strings, but I get 
compiler errors when using it on other array types. I've tried 
using it to replace occurrences of a certain object in an 
array with `[]` in order to remove all occurrences, but it's 
not allowed.


Is there a Phobos function that does what I want? It would be 
crazy if there isn't.


`remove`

https://dlang.org/phobos/std_algorithm_mutation.html#remove

```d
arr = arr.remove!(v => shouldBeRemoved(v));
```

Why the reassignment? Because `remove` removes elements *in 
place*, and does not change the range extents. It returns the 
portion of the range that contains the unremoved elements.


So to give an example:

```d
auto arr = [1, 2, 3, 4, 5];
auto result = arr.remove!(i => i % 2 == 1); // remove odd 
elements

assert(result == [2, 4]);

// first 2 are the slice that is stored in result
// the last three are leftovers.
assert(arr == [2, 4, 3, 4, 5]);
```

-Steve


In case anyone comes upon this in a search, I wanted to point out 
a couple dangers of using remove. The first is that it mutates 
arr, as shown in Steve's example. The second is


```
result[0] = 4;
assert(result == [4, 4]);
assert(arr == [2, 4, 3, 4, 5]); // Fails
arr[0] = 2;
assert(result == [4, 4]); // Fails
```

Any future changes you make to result or arr change the other. 
You can use remove to avoid the allocation of a new array, but 
you better be sure you never read or modify the original array 
again. If you use filter


```
auto result = arr.filter!(i => i % 2 == 0).array;
```

arr is unchanged and you can use arr and result as you want.


Re: How can I put the current value of a variable into a delegate?

2024-05-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On Monday, 6 May 2024 at 06:29:49 UTC, Liam McGillivray wrote:
Delegates can be a pain, as they often have results different 
from what one would intuitively expect. This can easily result 
in bugs.


Here's a line that caused a bug that took me awhile to find:
```
foreach(card; unitCards) card.submitted = delegate() => 
selectUnit(card.unit);

```

Each `UnitInfoCard` object (which `card` is a member of) 
contains a `Unit` object called `unit`. The intention of this 
line was that each object in `unitCards` would call 
`selectUnit` with it's own `unit` every time it calls 
`submitted`. Instead, every card calls `submitted` with the 
*last* value of `card`.


Yes, this is because the foreach loop reuses the same memory slot 
for `card`.


Even though this is allocated as a closure, it still only 
allocates the frame stack of the *enclosing function*, and does 
not allocate a new slot for each loop iteration.


You can force this by using a lambda which allocates the closure:

```d
foreach(card; unitCards)
card.submitted = (c2) { return () => selectUnit(c2.unit); 
}(card);

```

This is a lambda which accepts `card` as a parameter, and returns 
an appropriate delegate. It is important to use a parameter, 
because if you just use card inside there, it's still using the 
single stack frame of the calling function!


I renamed the inner parameter `c2` to avoid confusion, but you 
could name it `card` also. Essentially, the stack frame of the 
inner function is now allocated a closure, and it has it's own 
reference to `card` as a parameter.


This is a very old issue: 
https://issues.dlang.org/show_bug.cgi?id=2043 since "moved" to 
https://issues.dlang.org/show_bug.cgi?id=23136


I would love to see a solution, but the workaround at least 
exists!


-Steve


Re: How can I put the current value of a variable into a delegate?

2024-05-06 Thread Nick Treleaven via Digitalmars-d-learn

On Monday, 6 May 2024 at 06:29:49 UTC, Liam McGillivray wrote:

Here's a line that caused a bug that took me awhile to find:
```
foreach(card; unitCards) card.submitted = delegate() => 
selectUnit(card.unit);

```


I think you can do:
```d
import std.algorithm.iteration : each;
unitCards.each!(c => c.submitted = () => selectUnit(c.unit));
```



Re: How can I put the current value of a variable into a delegate?

2024-05-06 Thread Nick Treleaven via Digitalmars-d-learn

On Monday, 6 May 2024 at 06:29:49 UTC, Liam McGillivray wrote:
This is because the delegate assignment causes the local `card` 
variable to remain alive. The delegate that's assigned is 
linked to this variable itself, not the value at the time that 
the delegate is assigned.


This is https://issues.dlang.org/show_bug.cgi?id=23136. Perhaps 
it can be fixed in the next edition.


Is there a way I can dereference a variable when placing it in 
a delegate, so that it's current value is used, rather than the 
variable itself?


I think you would need to make an array before the loop, assign 
to an indexed element and use that in the delegate.


How can I put the current value of a variable into a delegate?

2024-05-06 Thread Liam McGillivray via Digitalmars-d-learn
Delegates can be a pain, as they often have results different 
from what one would intuitively expect. This can easily result in 
bugs.


Here's a line that caused a bug that took me awhile to find:
```
foreach(card; unitCards) card.submitted = delegate() => 
selectUnit(card.unit);

```

Each `UnitInfoCard` object (which `card` is a member of) contains 
a `Unit` object called `unit`. The intention of this line was 
that each object in `unitCards` would call `selectUnit` with it's 
own `unit` every time it calls `submitted`. Instead, every card 
calls `submitted` with the *last* value of `card`.


This is because the delegate assignment causes the local `card` 
variable to remain alive. The delegate that's assigned is linked 
to this variable itself, not the value at the time that the 
delegate is assigned.


Is there a way I can dereference a variable when placing it in a 
delegate, so that it's current value is used, rather than the 
variable itself?


Re: Show dialog box for uncaught exception (Windows, lld-link)

2024-05-05 Thread SimonN via Digitalmars-d-learn

On Sunday, 5 May 2024 at 18:28:29 UTC, SimonN wrote:

My implementation for the message box is now:


According to [UTF-8 
Everywhere](https://utf8everywhere.org/#windows), I shouldn't use 
`MessageBoxA` at all. The `A` means ANSI codepages, _not_ UTF-8. 
My above code _will_ show garbage output when there is some 
non-ASCII in the exception message.


Better: Convert to UTF-16 yourself and call `MessageBoxW`:

version (Windows) {
import core.sys.windows.windows;
import std.conv;
const wstring messageBody = wtext(/* ... */, "\0");
MessageBoxW(null, messageBody.ptr, null, MB_ICONERROR);
throw /* ... */;
}

-- Simon


Re: Show dialog box for uncaught exception (Windows, lld-link)

2024-05-05 Thread SimonN via Digitalmars-d-learn

On Sunday, 5 May 2024 at 17:15:10 UTC, Steven Schveighoffer wrote:

} catch(Exception e) {
visualDisplayOfException(e);
throw e;
}


Thanks! That's practically the same pattern that I already use 
for logging: Try-catch near the entry point, show the message, 
re-throw. My implementation for the message box is now:


catch (Throwable t) {
import core.sys.windows.windows;
const string errText = /* ... parse t ... */
MessageBoxA(null, errText.ptr, null, MB_ICONERROR);
}

That solves my problem. Even though I don't pass my game's window 
as the parent of the message box (first argument, where I pass 
`null`), the graphical game halts before exiting, shows the 
error, and users can screenshot both together. That's good.


From your answer, I'll assume: There is no standardized way in 
the D ecosystem (e.g., by calling a DRuntime function from my 
usercode) to opt into displaying such a message box for uncaught 
exceptions. I have to call third-party APIs myself.


Or is there something after all? From reading the 2019 thread 
[Deactivate windows MessageBox dialog on 
exception](https://forum.dlang.org/post/tlhjypvsaxzymccfc...@forum.dlang.org), it sounds like we should get an error box when we link with `-subsystem:windows`, and no box otherwise.


-- Simon


Re: Show dialog box for uncaught exception (Windows, lld-link)

2024-05-05 Thread Steven Schveighoffer via Digitalmars-d-learn

On Sunday, 5 May 2024 at 14:55:20 UTC, SimonN wrote:
My application is a graphical game. I close stdout and stderr 
by passing `-subsystem:windows` to `lld-link` to suppress the 
extra console window. For a few fatal errors (missing required 
resources, can't open display, ...), I throw exceptions, log 
them to logfile, then re-throw them to crash. I can tell 
Windows users to look in the logfile, but it would be more 
fitting on Windows to show an error dialog box in addition to 
the logging.


```d
int realMain(string[] args)
{
   // all your normal code goes here
}

int main(string[] args)
{
version(Windows) {
try {
realMain(args);
} catch(Exception e) {
visualDisplayOfException(e);
throw e;
}
} else {
// presumably, non-windows systems shouldn't show a 
graphical Exception

// trace?
realMain(args);
}
}
```

-Steve


Show dialog box for uncaught exception (Windows, lld-link)

2024-05-05 Thread SimonN via Digitalmars-d-learn

Hi,

for Windows, I link my executables with `lld-link`, whether for 
32-bit and 64-bit and whether I've built with LDC or DMD.


How can I generate a dialog box for uncaught exceptions that fly 
out of my executable's `main()`?


When I linked with Optlink years ago for Windows 32-bit, it 
generated an error dialog box for an uncaught exception. But with 
`lld-link`, the exception's message lands only on stderr. I 
didn't see anything related in `lld-link -help`. Can I configure 
DRuntime in a special way at runtime?


My application is a graphical game. I close stdout and stderr by 
passing `-subsystem:windows` to `lld-link` to suppress the extra 
console window. For a few fatal errors (missing required 
resources, can't open display, ...), I throw exceptions, log them 
to logfile, then re-throw them to crash. I can tell Windows users 
to look in the logfile, but it would be more fitting on Windows 
to show an error dialog box in addition to the logging.


-- Simon


Re: dlang.org/Learn "hello_world".sort.chain ...

2024-05-05 Thread Marko Merpovich via Digitalmars-d-learn

On Tuesday, 26 December 2023 at 10:53:10 UTC, Tony wrote:
I just typed in the program that is on the first page of Learn. 
It has this line:


sort(chain(arr1, arr2, arr3));

I assigned that to a variable:

arr4 = sort(chain(arr1, arr2, arr3));

then printed it out

writefln("%s",arr4);   // works

and then tried to print out the type of arr4:

writefln("%s",typeof(arr4));

and got this error:

// HelloWorld.d:25:19: error: cannot pass type 
SortedRange!(Result, "a < b") as a function argument


What exactly is that type? Or maybe, what would it take to 
understand what that type is?


The error message suggests that `SortedRange!(Result, "a < b")` 
is the type returned by the `sort` function. For additional 
insights and assistance, you can explore resources like online 
dissertation help literature review 
https://literaturereviewwritingservice.com/ This type represents 
a sorted range of elements, possibly of type `Result`, sorted 
based on the comparison predicate `"a < b"`. To understand it 
better, you may need to inspect its definition or consider 
alternative methods for printing its type.


Re: Turning fixed sized array into tuple

2024-05-04 Thread Dmitry Olshansky via Digitalmars-d-learn

On Saturday, 4 May 2024 at 19:11:14 UTC, Nick Treleaven wrote:

On Saturday, 4 May 2024 at 16:58:00 UTC, Dmitry Olshansky wrote:

So I have a function:

```d
size_t awaitAny(T...)(T args) { ... }
```

And I have:
``d
Event*[4] events;
``

How do I pass all 4 of events to awaitAny as tuple of 
arguments?


Use `awaitAny(events.tupleof)`?
https://dlang.org/spec/arrays.html#array-properties


Thanks, totally missed it!

—
Dmitry Olshansky
CEO @ [Glow labs](https://glow-labs.pro)
https://olshansky.me




Re: Turning fixed sized array into tuple

2024-05-04 Thread Nick Treleaven via Digitalmars-d-learn

On Saturday, 4 May 2024 at 16:58:00 UTC, Dmitry Olshansky wrote:

So I have a function:

```d
size_t awaitAny(T...)(T args) { ... }
```

And I have:
``d
Event*[4] events;
``

How do I pass all 4 of events to awaitAny as tuple of arguments?


Use `awaitAny(events.tupleof)`?
https://dlang.org/spec/arrays.html#array-properties


Turning fixed sized array into tuple

2024-05-04 Thread Dmitry Olshansky via Digitalmars-d-learn

So I have a function:

```d
size_t awaitAny(T...)(T args) { ... }
```

And I have:
``d
Event*[4] events;
``

How do I pass all 4 of events to awaitAny as tuple of arguments?

--
Dmitry Olshansky
CEO @ [Glow labs](https://glow-labs.pro)
https://olshansky.me/about/



Re: Deprecation: foreach: loop index implicitly converted from size_t to int

2024-05-03 Thread BoQsc via Digitalmars-d-learn
Well all these proposals to `int` index like `size_t` and `const 
typeof(arr.length)` are cryptic and less readable and less 
straightforward in comparison to how it used to be. Feels like 
horrible decision if the language is suppose to be somewhat 
futureproof. The `int` was simple, straighforward and great. 
These suggestions feel like some `C++` all over again.


Re: Goto skipping declarations

2024-05-03 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

On 04/05/2024 8:38 AM, Jonathan M Davis wrote:

In any case, I expect that the compiler is just going dumb here because of
the label for some reason, and one or more of the checks that it's supposed
to be doing is being missed.


It is very simple code.

A reverse search over the double linked list for the goto from the label.

I looked into it fairly recently as an example of type state analysis D 
is already designed against.


Re: Goto skipping declarations

2024-05-03 Thread Ben Jones via Digitalmars-d-learn

On Friday, 3 May 2024 at 20:38:31 UTC, Jonathan M Davis wrote:




https://issues.dlang.org/show_bug.cgi?id=24535


Re: Goto skipping declarations

2024-05-03 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, May 3, 2024 2:38:31 PM MDT Jonathan M Davis via Digitalmars-d-learn 
wrote:
> On Friday, May 3, 2024 1:15:16 PM MDT Ben Jones via Digitalmars-d-learn 
wrote:
> > In general, you can't skip a declaration with goto, but it seems
> > to be allowed if the declaration you're skipping is labelled...
> > Is that expected or an accepts invalid bug?
> >
> > https://godbolt.org/z/4qx8Pf6G7
> >
> > ```d
> > void f1(){ //fails with error about skipping a declaration
> >
> >  int x;
> >  goto Label;
> >  int y;
> >  Label:
> >  int z;
> >
> > }
> >
> > void f2(){ //compiles fine
> >
> >  int x;
> >  goto Label;
> >  Dummy:
> >  int y;
> >  Label:
> >  int z;
> >
> > }
> > ```
>
> It has to be a bug, and taking it a step further shows that. If you print
> out y, you'll get a seemingly random number. E.G. On the first run, I got
>
> 554440803
>
> and on the second I got
>
> 549310547
>
> Presumably, it's a garbage value from whatever happened to be on the stack.
>
> I'm quite sure that the spec doesn't have anything about being allowed to
> skip a declaration just because it has a label on it (honestly, if we _did_
> want that to be the case, the spec would probably be missing it, since it
> tends to fall on the side of having too few details rather than too many),
> but even if it did, the code is clearly doing something that should not be
> happening with initialization without explicitly using = void. So,
> _something_ here would nee to be fixed.
>
> In any case, I expect that the compiler is just going dumb here because of
> the label for some reason, and one or more of the checks that it's supposed
> to be doing is being missed.

Here. I reported it:

https://issues.dlang.org/show_bug.cgi?id=24534

- Jonathan M Davis





Re: Goto skipping declarations

2024-05-03 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, May 3, 2024 1:15:16 PM MDT Ben Jones via Digitalmars-d-learn wrote:
> In general, you can't skip a declaration with goto, but it seems
> to be allowed if the declaration you're skipping is labelled...
> Is that expected or an accepts invalid bug?
>
> https://godbolt.org/z/4qx8Pf6G7
>
> ```d
> void f1(){ //fails with error about skipping a declaration
>  int x;
>  goto Label;
>  int y;
>  Label:
>  int z;
> }
>
> void f2(){ //compiles fine
>  int x;
>  goto Label;
>  Dummy:
>  int y;
>  Label:
>  int z;
> }
> ```

It has to be a bug, and taking it a step further shows that. If you print
out y, you'll get a seemingly random number. E.G. On the first run, I got

554440803

and on the second I got

549310547

Presumably, it's a garbage value from whatever happened to be on the stack.

I'm quite sure that the spec doesn't have anything about being allowed to
skip a declaration just because it has a label on it (honestly, if we _did_
want that to be the case, the spec would probably be missing it, since it
tends to fall on the side of having too few details rather than too many),
but even if it did, the code is clearly doing something that should not be
happening with initialization without explicitly using = void. So,
_something_ here would nee to be fixed.

In any case, I expect that the compiler is just going dumb here because of
the label for some reason, and one or more of the checks that it's supposed
to be doing is being missed.

- Jonathan M Davis





Goto skipping declarations

2024-05-03 Thread Ben Jones via Digitalmars-d-learn
In general, you can't skip a declaration with goto, but it seems 
to be allowed if the declaration you're skipping is labelled... 
Is that expected or an accepts invalid bug?


https://godbolt.org/z/4qx8Pf6G7

```d
void f1(){ //fails with error about skipping a declaration
int x;
goto Label;
int y;
Label:
int z;
}

void f2(){ //compiles fine
int x;
goto Label;
Dummy:
int y;
Label:
int z;
}
```


Re: Recommendations on porting Python to D

2024-05-03 Thread mw via Digitalmars-d-learn

On Friday, 3 May 2024 at 17:38:10 UTC, Chris Piker wrote:

On Thursday, 25 April 2024 at 16:57:53 UTC, mw wrote:

On Wednesday, 24 April 2024 at 22:07:41 UTC, Chris Piker wrote:


Python-AST to D source converter may already exist?


https://github.com/joortcom/eiffel_rename/tree/main/yi

A rudimentary converter from (extended) Python to D. Maybe you 
can use it as a starting point.


Thanks for the suggestions.  I put the question aside for a 
bit, but yesterday ran across a python transpiler here:


  https://github.com/py2many/py2many

It already has support for C++, Go and others.  Since I have 
mountains of python code created over many years, maybe it 
would be worth contributing to this project out of self 
interest.


Can you take a look at py2many and see what you think about it? 
 Getting D on the support list might be good.


(Haven't checked its own implementation and output code quality.)

But it says has output for Kotlin, Dart, these two languages are 
similar to D syntactically, so will be a good start.




Re: Recommendations on porting Python to D

2024-05-03 Thread Chris Piker via Digitalmars-d-learn

On Thursday, 25 April 2024 at 16:57:53 UTC, mw wrote:

On Wednesday, 24 April 2024 at 22:07:41 UTC, Chris Piker wrote:


Python-AST to D source converter may already exist?


https://github.com/joortcom/eiffel_rename/tree/main/yi

A rudimentary converter from (extended) Python to D. Maybe you 
can use it as a starting point.


Thanks for the suggestions.  I put the question aside for a bit, 
but yesterday ran across a python transpiler here:


  https://github.com/py2many/py2many

It already has support for C++, Go and others.  Since I have 
mountains of python code created over many years, maybe it would 
be worth contributing to this project out of self interest.


Can you take a look at py2many and see what you think about it?  
Getting D on the support list might be good.




Re: Deprecation: foreach: loop index implicitly converted from size_t to int

2024-05-03 Thread user1234 via Digitalmars-d-learn

On Friday, 3 May 2024 at 15:19:13 UTC, user1234 wrote:

On Friday, 3 May 2024 at 14:59:57 UTC, BoQsc wrote:

On Friday, 3 May 2024 at 13:18:02 UTC, user1234 wrote:

[...]





So how would you update this example, what is the right index 
type here to choose?


```
import std.stdio : writefln;

void main() {
auto arr = [
[5, 15],  // 20
[2, 3, 2, 3], // 10
[3, 6, 2, 9], // 20
];

foreach (i, row; arr)
{
double total = 0.0;
foreach (e; row)
total += e;

auto avg = total / row.length;
writefln("AVG [row=%d]: %.2f", i, avg);
}
}
```

Example taken from 
https://tour.dlang.org/tour/en/basics/foreach


Isn't that obvious ?

```d
foreach (const size_t i, row; arr)
```

`arr` is not a static array, it is a dynamic one, consequently 
its `.length` type is `size_t`, even if you have the feeling 
that, in the present situation, `int` bitwidth would be 
sufficient.


even better:

```d
foreach (const typeof(arr.length) i, row; arr)
```

Otherwise I respect your POV, it's just that here I have no 
problem with the way that works. I dont see any issue with the 
type system. D type system is static, strong, but optionally 
inferred. And that's it.


Re: Deprecation: foreach: loop index implicitly converted from size_t to int

2024-05-03 Thread user1234 via Digitalmars-d-learn

On Friday, 3 May 2024 at 14:59:57 UTC, BoQsc wrote:

On Friday, 3 May 2024 at 13:18:02 UTC, user1234 wrote:

On Friday, 3 May 2024 at 10:50:03 UTC, BoQsc wrote:

[...]


**You can specify the index type, just choose the right one.** 
For now there's a deprecation message but after some while 
you'll get a proper error message, e.g _"index type for arr 
must be of type T because arr.length type is T"_.


What's is happening now is to help people updating their code 
and prevent abrupt breakages.





So how would you update this example, what is the right index 
type here to choose?


```
import std.stdio : writefln;

void main() {
auto arr = [
[5, 15],  // 20
[2, 3, 2, 3], // 10
[3, 6, 2, 9], // 20
];

foreach (i, row; arr)
{
double total = 0.0;
foreach (e; row)
total += e;

auto avg = total / row.length;
writefln("AVG [row=%d]: %.2f", i, avg);
}
}
```

Example taken from https://tour.dlang.org/tour/en/basics/foreach


Isn't that obvious ?

```d
foreach (const size_t i, row; arr)
```

`arr` is not a static array, it is a dynamic one, consequently 
its `.length` type is `size_t`, even if you have the feeling 
that, in the present situation, `int` bitwidth would be 
sufficient.


Re: Deprecation: foreach: loop index implicitly converted from size_t to int

2024-05-03 Thread BoQsc via Digitalmars-d-learn

On Friday, 3 May 2024 at 13:18:02 UTC, user1234 wrote:

On Friday, 3 May 2024 at 10:50:03 UTC, BoQsc wrote:
Why am I forced to visit this D Lang thread, why this 
deprecation warning still appears in my console window in the 
latest version of DMD. Does not make any sense from the 
developer's perspective to show this warning and pollute the 
already polluted logging entries of the compiler. How am I 
suppose to program anything effectively if half of the screen 
are some nonsensical deprecation warnings without guidance or 
sane explanations.


This is not better
```
foreach (i, row; arr)
```
than
```
foreach (int i, row; arr)
```
Hides the datatype and makes the D language appear in-explicit 
and annoying.


What is this language becoming. A completely weak typed 
language or something?


I would use JavaScript if I would want that. How are we 
suppose to make whole sane Operating Systems with such 
syntaxes. Do everyone just enjoy having bugs with some 
implicit size_t, or do everyone just enjoy deprecation 
warnings in their logging systems when there are way more 
important problems to solve, that are actually project related.


**You can specify the index type, just choose the right one.** 
For now there's a deprecation message but after some while 
you'll get a proper error message, e.g _"index type for arr 
must be of type T because arr.length type is T"_.


What's is happening now is to help people updating their code 
and prevent abrupt breakages.





So how would you update this example, what is the right index 
type here to choose?


```
import std.stdio : writefln;

void main() {
auto arr = [
[5, 15],  // 20
[2, 3, 2, 3], // 10
[3, 6, 2, 9], // 20
];

foreach (i, row; arr)
{
double total = 0.0;
foreach (e; row)
total += e;

auto avg = total / row.length;
writefln("AVG [row=%d]: %.2f", i, avg);
}
}
```

Example taken from https://tour.dlang.org/tour/en/basics/foreach


Re: Deprecation: foreach: loop index implicitly converted from size_t to int

2024-05-03 Thread user1234 via Digitalmars-d-learn

On Friday, 3 May 2024 at 10:50:03 UTC, BoQsc wrote:
Why am I forced to visit this D Lang thread, why this 
deprecation warning still appears in my console window in the 
latest version of DMD. Does not make any sense from the 
developer's perspective to show this warning and pollute the 
already polluted logging entries of the compiler. How am I 
suppose to program anything effectively if half of the screen 
are some nonsensical deprecation warnings without guidance or 
sane explanations.


This is not better
```
foreach (i, row; arr)
```
than
```
foreach (int i, row; arr)
```
Hides the datatype and makes the D language appear in-explicit 
and annoying.


What is this language becoming. A completely weak typed 
language or something?


I would use JavaScript if I would want that. How are we suppose 
to make whole sane Operating Systems with such syntaxes. Do 
everyone just enjoy having bugs with some implicit size_t, or 
do everyone just enjoy deprecation warnings in their logging 
systems when there are way more important problems to solve, 
that are actually project related.


You can specify the index type, just choose the right one. For 
now there's a deprecation message but after some while you'll get 
a proper error message, e.g _"index type for arr must be of type 
T because arr.length type is T"_.


What's is happening now is to help people updating their code and 
prevent abrupt breakages.


Re: Deprecation: foreach: loop index implicitly converted from size_t to int

2024-05-03 Thread BoQsc via Digitalmars-d-learn
Why am I forced to visit this D Lang thread, why this deprecation 
warning still appears in my console window in the latest version 
of DMD. Does not make any sense from the developer's perspective 
to show this warning and pollute the already polluted logging 
entries of the compiler. How am I suppose to program anything 
effectively if half of the screen are some nonsensical 
deprecation warnings without guidance or sane explanations.


This is not better
```
foreach (i, row; arr)
```
than
```
foreach (int i, row; arr)
```
Hides the datatype and makes the D language appear in-explicit 
and annoying.


What is this language becoming. A completely weak typed language 
or something?


I would use JavaScript if I would want that. How are we suppose 
to make whole sane Operating Systems with such syntaxes. Do 
everyone just enjoy having bugs with some implicit size_t, or do 
everyone just enjoy deprecation warnings in their logging systems 
when there are way more important problems to solve, that are 
actually project related.


Re: Challenge Tuples

2024-05-03 Thread NotYouAgain via Digitalmars-d-learn

On Friday, 3 May 2024 at 05:11:28 UTC, Salih Dincer wrote:


..
Wouldn't it be great if there was a feature that worked at 
runtime...


SDB@79


module m;
@safe:
private:
import std;

void main()
{
auto myTuple = tuple(1, 2, 3, [1, 3], 5);
int[] arrToSum;

foreach(int i, val; myTuple.expand)
{
if(typeof(val).stringof == "int[]")
{
foreach(v; myTuple.expand[i..i+1])
arrToSum ~= v;
}
else
{
arrToSum ~= val;
}
}

writefln("The total value of the tuples is: %s", 
arrToSum.sum); // 15

}



Re: Challenge Tuples

2024-05-02 Thread Salih Dincer via Digitalmars-d-learn

On Wednesday, 1 May 2024 at 14:15:19 UTC, Andrey Zherikov wrote:



Shorter and without allocations:
```d
import std.typecons : tuple;
import std.algorithm : sum, each;

auto sum(int i) => i;

void main()
{
  auto t = tuple(1, 2, 3, [1, 3], 5);

  int res=0;
  t.each!(e => res += sum(e));
  assert(res == 15);
}
```


Super!

In summary, D is clearly ahead of the tuple. Especially with its 
features similar to AliasSeq, I think it is unrivaled. Wouldn't 
it be great if there was a feature that worked at runtime...


SDB@79



Recommendations for good concurrent hashset (esp. for strings)?

2024-05-01 Thread mw via Digitalmars-d-learn

Hi,

I'm looking for recommendations for good concurrent hashset (esp. 
for strings)?


Any libraries?

Thanks.




Re: Phobos function to remove all occurances from dynamic array?

2024-05-01 Thread Steven Schveighoffer via Digitalmars-d-learn

On Wednesday, 1 May 2024 at 01:09:33 UTC, Liam McGillivray wrote:
This is presumably such a common task that I'm surprised it 
isn't easy to find the answer by searching;


Is there a standard library function that removes all elements 
from a dynamic array that matches an input argument?


In `std.array` there's the `replace` function which is supposed 
to replace all occurrences that match an input with another. It 
seems to work as described on strings, but I get compiler 
errors when using it on other array types. I've tried using it 
to replace occurrences of a certain object in an array with 
`[]` in order to remove all occurrences, but it's not allowed.


Is there a Phobos function that does what I want? It would be 
crazy if there isn't.


`remove`

https://dlang.org/phobos/std_algorithm_mutation.html#remove

```d
arr = arr.remove!(v => shouldBeRemoved(v));
```

Why the reassignment? Because `remove` removes elements *in 
place*, and does not change the range extents. It returns the 
portion of the range that contains the unremoved elements.


So to give an example:

```d
auto arr = [1, 2, 3, 4, 5];
auto result = arr.remove!(i => i % 2 == 1); // remove odd elements
assert(result == [2, 4]);

// first 2 are the slice that is stored in result
// the last three are leftovers.
assert(arr == [2, 4, 3, 4, 5]);
```

-Steve


Re: aliasing private

2024-05-01 Thread user1234 via Digitalmars-d-learn

On Wednesday, 1 May 2024 at 12:07:26 UTC, NotYouAgain wrote:

I want to do a C like #define on private, but I can't

ie. #define private fileprivate

// ---
module m;

alias fileprivate = private; // grr!

class myClass
{
   fileprivate int n;
}

// ---


You cant. That is simply not supported.


Re: Challenge Tuples

2024-05-01 Thread Andrey Zherikov via Digitalmars-d-learn

On Friday, 26 April 2024 at 13:25:34 UTC, Salih Dincer wrote:
You have a 5-item data tuples as Tuple(1, 2, 3, [1, 3], 5) and 
implement the sum (total = 15) with the least codes using the 
sum() function of the language you are coding...



Let's start with D:

```d
import std.typecons : tuple;
import std.algorithm : sum;

void main()
{
  auto t = tuple(1, 2, 3, [1, 3], 5);

  int[] arr;
  t.each!(e => arr ~= e);
  assert(arr.sum == 15);
}
```

and bonus:

```d
import std.typecons : tuple;
import std.stdio : writeln;
void main()
{
  auto t = tuple(1, 2, 3, [1, 3], 5);
  auto results = [0];

  foreach (data; t)
  {
static
if (is(typeof(data) == int[]))
{
  int sum;
  foreach (d; data)
  {
sum += d;
  }
  results ~= sum;
}
else
{
  results ~= data;
}
  }
  results.writeln; // [0, 1, 2, 3, 4, 5]
```

I bet you won't be able to do it this easily with other 
languages!  Note: I tried with C# and Python and it didn't work!


SDB@79



Shorter and without allocations:
```d
import std.typecons : tuple;
import std.algorithm : sum, each;

auto sum(int i) => i;

void main()
{
  auto t = tuple(1, 2, 3, [1, 3], 5);

  int res=0;
  t.each!(e => res += sum(e));
  assert(res == 15);
}
```



Re: Phobos function to remove all occurances from dynamic array?

2024-05-01 Thread Nick Treleaven via Digitalmars-d-learn

On Wednesday, 1 May 2024 at 01:09:33 UTC, Liam McGillivray wrote:
I get compiler errors when using it on other array types. I've 
tried using it to replace occurrences of a certain object in an 
array with [] in order to remove all occurrences, but it's not 
allowed.


Can you post a code example?


aliasing private

2024-05-01 Thread NotYouAgain via Digitalmars-d-learn

I want to do a C like #define on private, but I can't

ie. #define private fileprivate

// ---
module m;

alias fileprivate = private; // grr!

class myClass
{
   fileprivate int n;
}

// ---


Re: Phobos function to remove all occurances from dynamic array?

2024-04-30 Thread Liam McGillivray via Digitalmars-d-learn

On Wednesday, 1 May 2024 at 01:24:55 UTC, Lance Bachmeier wrote:

Does filter do what you need?

https://dlang.org/phobos/std_algorithm_iteration.html#.filter


It seems to do it with the following line:
```
allObjects = allObjects.filter!(element => element !is 
this).array;

```

So I've found a way to do it. It's still rather strange that it's 
so difficult to find the solution to such a common problem in the 
documentation.


Re: Phobos function to remove all occurances from dynamic array?

2024-04-30 Thread Lance Bachmeier via Digitalmars-d-learn

On Wednesday, 1 May 2024 at 01:09:33 UTC, Liam McGillivray wrote:
This is presumably such a common task that I'm surprised it 
isn't easy to find the answer by searching;


Is there a standard library function that removes all elements 
from a dynamic array that matches an input argument?


In `std.array` there's the `replace` function which is supposed 
to replace all occurrences that match an input with another. It 
seems to work as described on strings, but I get compiler 
errors when using it on other array types. I've tried using it 
to replace occurrences of a certain object in an array with 
`[]` in order to remove all occurrences, but it's not allowed.


Is there a Phobos function that does what I want? It would be 
crazy if there isn't.


Does filter do what you need?

https://dlang.org/phobos/std_algorithm_iteration.html#.filter


Re: Find homography in D?

2024-04-30 Thread Jordan Wilson via Digitalmars-d-learn

On Sunday, 21 April 2024 at 14:57:33 UTC, Paolo Invernizzi wrote:

Hi,

Someone can point me to a D implementation of the classical 
OpenCV find homography matrix?


Thank you,
Paolo


Something I wrote awhile ago...

```
import kaleidic.lubeck : svd;
import gfm.math;
import mir.ndslice : sliced;

auto generateTransformationArray(int[] p) {
return generateTransformationArray(p[0],p[1],p[2],p[3]);
}

auto generateTransformationArray(int x, int y, int x_, int y_) {
return [-x, -y, -1, 0, 0, 0, x*x_, y*x_, x_,
0, 0, 0, -x, -y, -1, x*y_, y*y_, y_];
}

auto transformCoor (mat3d mat, vec3d vec) {
auto res = mat * vec;
return res / res[2];
}

auto findHomography (int[][] correspondances) {
auto a = correspondances
.map!(a => a.generateTransformationArray)
.joiner
.array
.sliced(8,9);

auto r = a.svd;
auto homog = r.vt.back;
return mat3d(homog.map!(a => a/homog.back).array);
}
```



Re: Find homography in D?

2024-04-30 Thread Ferhat Kurtulmuş via Digitalmars-d-learn

On Sunday, 21 April 2024 at 14:57:33 UTC, Paolo Invernizzi wrote:

Hi,

Someone can point me to a D implementation of the classical 
OpenCV find homography matrix?


Thank you,
Paolo


Just for future records in the forum.

// 
https://math.stackexchange.com/questions/3509039/calculate-homography-with-and-without-svd


/+dub.sdl:
dependency "lubeck" version="~>1.5.4"
+/
import std;
import mir.ndslice;
import kaleidic.lubeck;

void main()
{
double[2] x_1 = [93,-7];
double[2] y_1 = [63,0];
double[2] x_2 = [293,3];
double[2] y_2 = [868,-6];
double[2] x_3 = [1207,7];
double[2] y_3 = [998,-4];
double[2] x_4 = [1218,3];
double[2] y_4 = [309,2];

auto A = [
-x_1[0], -y_1[0], -1, 0, 0, 0, x_1[0]*x_1[1], 
y_1[0]*x_1[1], x_1[1],
0, 0, 0, -x_1[0], -y_1[0], -1, x_1[0]*y_1[1], 
y_1[0]*y_1[1], y_1[1],
-x_2[0], -y_2[0], -1, 0, 0, 0, x_2[0]*x_2[1], 
y_2[0]*x_2[1], x_2[1],
0, 0, 0, -x_2[0], -y_2[0], -1, x_2[0]*y_2[1], 
y_2[0]*y_2[1], y_2[1],
-x_3[0], -y_3[0], -1, 0, 0, 0, x_3[0]*x_3[1], 
y_3[0]*x_3[1], x_3[1],
0, 0, 0, -x_3[0], -y_3[0], -1, x_3[0]*y_3[1], 
y_3[0]*y_3[1], y_3[1],
-x_4[0], -y_4[0], -1, 0, 0, 0, x_4[0]*x_4[1], 
y_4[0]*x_4[1], x_4[1],
0, 0, 0, -x_4[0], -y_4[0], -1, x_4[0]*y_4[1], 
y_4[0]*y_4[1], y_4[1]

].sliced(8, 9);

auto svdResult = svd(A);

auto homography = svdResult.vt[$-1].sliced(3, 3);
	auto transformedPoint = homography.mtimes([1679,  128, 
1].sliced.as!double.slice);

transformedPoint[] /= transformedPoint[2];

writeln(transformedPoint); //[4, 7, 1]
}


Re: dynamic linker flags with dub

2024-04-29 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

On 30/04/2024 10:20 AM, KytoDragon wrote:
I want to use dll-style hot-reloading for a windows application which 
requires a different name for the PDB file for each compilation. 
(windows locks the pdb file when loading the dll and the compiler can't 
create a new pdb with the same name). How can I achieve this with dub? 
Is there a way to inject variables into the linker flags?


E.g. something like this in the dub.json:

"lflags-windows-ldc": ["/PDB:foo_%random%.pdb"]


Your best bet probably is to use dub as a library, and change your 
``targetName`` or ``targetPath`` on each compilation.


Alternatively you could generate your dub file with the change in it 
each time that depends upon the actual library (which would be a 
``sourceLibrary``).


Re: Challenge Tuples

2024-04-27 Thread Julian Fondren via Digitalmars-d-learn

On Friday, 26 April 2024 at 13:25:34 UTC, Salih Dincer wrote:
You have a 5-item data tuples as Tuple(1, 2, 3, [1, 3], 5) and 
implement the sum (total = 15) with the least codes using the 
sum() function of the language you are coding...


Nim:

```nim
import std/[math, typetraits, macros]

macro unrollRange(low, high: static int; name, body: untyped) =
  result = newStmtList()
  for i in low ..< high:
result.add(newBlockStmt(newStmtList(
  newConstStmt(name, newLit i),
  copy body
)))

let t = (1, 2, 3, @[1, 3], 5)
var arr: seq[int]
unrollRange(0, t.tupleLen, i):
  arr.add t[i]
doAssert arr.sum == 15
```

vs. D

1. there's no `each` on tuples
2. there's no static for loop, so a macro is needed for the tuple 
indices

3. `add` is making use of the same overload as D's `~=`


Re: Challenge Tuples

2024-04-27 Thread Sergey via Digitalmars-d-learn

On Friday, 26 April 2024 at 13:25:34 UTC, Salih Dincer wrote:
You have a 5-item data tuples as Tuple(1, 2, 3, [1, 3], 5) and 
implement the sum (total = 15) with the least codes using the 
sum() function of the language you are coding...



Let's start with D:

```d
import std.typecons : tuple;
import std.algorithm : sum;

void main()
{
  auto t = tuple(1, 2, 3, [1, 3], 5);

  int[] arr;
  t.each!(e => arr ~= e);
  assert(arr.sum == 15);
}
```
I bet you won't be able to do it this easily with other 
languages!  Note: I tried with C# and Python and it didn't work!


For Python it is possible to use something like:
```python
t = (1,2,3,[1,3],5)
for e in t:
a.append(e) if isinstance(e, int) else a.extend(e)
print(sum(a))
```



Re: Challenge Tuples

2024-04-27 Thread Salih Dincer via Digitalmars-d-learn

On Saturday, 27 April 2024 at 15:36:40 UTC, Nick Treleaven wrote:
On Saturday, 27 April 2024 at 15:32:40 UTC, Nick Treleaven 
wrote:

On Saturday, 27 April 2024 at 11:55:58 UTC, Basile B. wrote:

foreach const e in u do
if echo(is, e, T) do
result += e;



static if (is(typeof(e) == int))
r += e;


Actually I would write that:
```d
R r;
foreach (e; v)
{
static if (is(typeof(e) : R))
```


I like the new sum() function, great Nick!  Moreover, it also 
works with an ordinary range:


```d
  enum limit = 100; // sum = 5050
  iota(limit + 1).sum.writeln;
```

Python seems too complicated to me, but C# looks delicious. 
Moreover, it was implemented without defining IEnumerator. Well 
done Matheus!


SDB@79


Re: Challenge Tuples

2024-04-27 Thread Nick Treleaven via Digitalmars-d-learn

On Saturday, 27 April 2024 at 15:32:40 UTC, Nick Treleaven wrote:

On Saturday, 27 April 2024 at 11:55:58 UTC, Basile B. wrote:

foreach const e in u do
if echo(is, e, T) do
result += e;



static if (is(typeof(e) == int))
r += e;


Actually I would write that:
```d
R r;
foreach (e; v)
{
static if (is(typeof(e) : R))
```


Re: Challenge Tuples

2024-04-27 Thread Nick Treleaven via Digitalmars-d-learn

On Saturday, 27 April 2024 at 11:55:58 UTC, Basile B. wrote:

Here's [STYX](https://gitlab.com/styx-lang/styx) solution:


function sum[T,U](U u): u32


I think you meant `: T`.


{
var T result;
foreach const e in u do
if echo(is, e, T) do
result += e;
else do
result += sum![T](e);
return result;
}

function main(): s32
{
assert((1, 2, 3, [1, 3], 5).sum![u32]() == 15);
return 0;
}


Mostly equivalent D:
```d
R sum(R = long, T)(T v)
{
R r;
foreach (e; v)
{
static if (is(typeof(e) == int))
r += e;
else
r += sum!R(e);
}
return r;
}

void main()
{
import std;
assert(tuple(1, 2, 3, [1, 3], 5).sum == 15);
}
```


Re: Challenge Tuples

2024-04-27 Thread Basile B. via Digitalmars-d-learn

On Friday, 26 April 2024 at 13:25:34 UTC, Salih Dincer wrote:
You have a 5-item data tuples as Tuple(1, 2, 3, [1, 3], 5) and 
implement the sum (total = 15) with the least codes using the 
sum() function of the language you are coding...



Let's start with D:


Here's [STYX](https://gitlab.com/styx-lang/styx) solution:


function sum[T,U](U u): u32
{
var T result;
foreach const e in u do
if echo(is, e, T) do
result += e;
else do
result += sum![T](e);
return result;
}

function main(): s32
{
assert((1, 2, 3, [1, 3], 5).sum![u32]() == 15);
return 0;
}


A few notes:

- tuples are first class citizen
- `foreach` over tuple is like in D, i.e unrolling
- `echo` is like D `__traits`
- _Implicit Generic Application_ of `U` (that's like D's IFTI) 
makes the task easy


Re: Challenge Tuples

2024-04-26 Thread Andy Valencia via Digitalmars-d-learn

On Friday, 26 April 2024 at 13:25:34 UTC, Salih Dincer wrote:
You have a 5-item data tuples as Tuple(1, 2, 3, [1, 3], 5) and 
implement the sum (total = 15) with the least codes using the 
sum() function of the language you are coding...


My Python solution (function named dosum to avoid collision w. 
Python primitive):


def dosum(itm):
if isinstance(itm, (int, float)):
return itm
return sum( dosum(_i) for _i in itm );

print dosum( [1, 2, 3, [1, 3], 5] )



Re: Challenge Tuples

2024-04-26 Thread matheus via Digitalmars-d-learn

On Friday, 26 April 2024 at 13:25:34 UTC, Salih Dincer wrote:

...


Very nice, for your first example I need to think a bit because 
I'm bit rusty in C#, but I think it will not be as easier as D 
version.


For the bonus part:

private static void Main(string[] args){
var a = (1,2,3,(1,3),5);
var t = a as ITuple;
var xx = new List();

for(var i=0;i   if(t[i].GetType() == 
typeof(System.ValueTuple)){

  var t2 = (t[i] as ITuple);
  var s = 0;
  for(var j=0;jAgain I'm rusty in C#... but so far yes it's more verbose than 
the D version.


Matheus.


Challenge Tuples

2024-04-26 Thread Salih Dincer via Digitalmars-d-learn
You have a 5-item data tuples as Tuple(1, 2, 3, [1, 3], 5) and 
implement the sum (total = 15) with the least codes using the 
sum() function of the language you are coding...



Let's start with D:

```d
import std.typecons : tuple;
import std.algorithm : sum;

void main()
{
  auto t = tuple(1, 2, 3, [1, 3], 5);

  int[] arr;
  t.each!(e => arr ~= e);
  assert(arr.sum == 15);
}
```

and bonus:

```d
import std.typecons : tuple;
import std.stdio : writeln;
void main()
{
  auto t = tuple(1, 2, 3, [1, 3], 5);
  auto results = [0];

  foreach (data; t)
  {
static
if (is(typeof(data) == int[]))
{
  int sum;
  foreach (d; data)
  {
sum += d;
  }
  results ~= sum;
}
else
{
  results ~= data;
}
  }
  results.writeln; // [0, 1, 2, 3, 4, 5]
```

I bet you won't be able to do it this easily with other 
languages!  Note: I tried with C# and Python and it didn't work!


SDB@79


Re: Recommendations on porting Python to D

2024-04-25 Thread max haughton via Digitalmars-d-learn

On Wednesday, 24 April 2024 at 19:50:45 UTC, Chris Piker wrote:

Hi D

I have a somewhat extensive CGI based web service written in 
Python and I'd like to port it to D.  I can do this manually of 
course, and maybe that's the best way, but for a rough start, 
is anyone aware of any tools that generate an abstract syntax 
tree which could then be converted to somewhat equivalent D 
code?  This might give me a jump-start on the manual conversion 
process.  Then later I can work on removing the CGI dependency.


I'm aware that this wouldn't work in general due to all the 
third party modules typically used in python, but most of this 
code is self contained Python2 and doesn't depend on many 
imports.


I can just call my old C code from D, but the old Python is 
another story.


Thanks for any advice you may have,


A strategy roughly along the lines of:

Test what you can, then port the tests, then just let chatgpt 
have at it can go further than one might reasonably expect (I 
have used chatgpt to convert to and from languages that don't 
even exist in public and it can basically get the gist of most 
things).


Treat it interactively rather than like a CLI tool, it must be 
said.





  1   2   3   4   5   6   7   8   9   10   >