Re: Socket and spawn()

2024-05-31 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, May 31, 2024 10:07:23 AM MDT Andy Valencia via Digitalmars-d-learn 
wrote:
> I'm coding a server which takes TCP connections.  I end up in the
> main thread with .accept() which hands me a Socket.  I'd like to
> hand this off to a spawn()'ed thread to do the actual work.
>
>  Aliases to mutable thread-local data not allowed.
>
> Is there some standard way to get something which _isn't_ in TLS?
>   Or do I have to drop back to file descriptors and do my own
> socket handling?
>
> TIA,
> Andy

Strictly speaking, unless you're dealing with a module or static-level
variable, the object is not in TLS. It's treated as thread-local by the type
system, and the type system will assume that no other thread has access to
it, but you can freely cast it to shared or immutable and pass it across
threads. It's just that it's up to you to make sure that you don't have a
thread-local reference to shared data that isn't protected in a fashion that
accessing the thread-local references is guarantee to be thread-safe (e.g.
the appropriate mutex has been locked).

So, if you're just passing it to another thread, and that other thread is
all that uses the object, then you would temporarily cast it to shared or
immutable, give it to the other thread, and then that thread would cast it
back to thread-local to use it, and the original thread would have nothing
to do with it any longer.

On the other hand, if you're actively sharing an object across threads, then
you cast it to shared and give it to the other thread. But then you have to
use an appropriate thread-synchronization mechanism (likely a mutex in the
case of a socket) to ensure that accessing the object is thread-safe.

So, typically, you would lock a mutex to ensure that no other thread is
accessing the object, and then you temporarily cast away shared while the
object is protected by the mutex so that you can do whatever you need to do
with the object, and once you're ready to release the mutex, you make sure
that no thread-local references to the object remain before releasing the
mutex. So, any code actually operating on the object would do so while it's
typed as thread-local, and the compiler would complain if you accidentally
accessed it through the shared referenc to the data (though the compiler
doesn't currently catch all such cases - the -preview=nosharedaccess switch
turns on more of the checks, and that's supposed to be become the default
eventually, but it hasn't yet).

In any case, you can freely cast between thread-local and shared. It's just
that you need to be sure that when you do that, you're not violating the
type system by having a thread-local reference to shared data access that
shared data without first protecting it with a mutex. And that typically
means not having any thread-local references to the shared data except when
the mutex is locked. But if all you're doing is passing an object across
threads, then it's pretty straightforward, since you just cast it to shared
or immutable to be able to pass it across threads and then cast back to
thread-local on the other side to use it as normal again (you just need to
make sure that you don't leave a reference to the data on the original
thread when you do that).

- Jonathan M Davis





Socket and spawn()

2024-05-31 Thread Andy Valencia via Digitalmars-d-learn
I'm coding a server which takes TCP connections.  I end up in the 
main thread with .accept() which hands me a Socket.  I'd like to 
hand this off to a spawn()'ed thread to do the actual work.


Aliases to mutable thread-local data not allowed.

Is there some standard way to get something which _isn't_ in TLS? 
 Or do I have to drop back to file descriptors and do my own 
socket handling?


TIA,
Andy



Re: need help to use C++ callback from garnet

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

On Wednesday, 29 May 2024 at 07:47:01 UTC, Dakota wrote:
I try use 
https://github.com/microsoft/garnet/blob/main/libs/storage/Tsavorite/cc/src/device/native_device_wrapper.cc from D



Not sure how to make this work with D:

```c++
	EXPORTED_SYMBOL FASTER::core::Status 
NativeDevice_ReadAsync(NativeDevice* device, uint64_t source, 
void* dest, uint32_t length, FASTER::core::AsyncIOCallback 
callback, void* context) {
		return device->ReadAsync(source, dest, length, callback, 
context);

}

	EXPORTED_SYMBOL FASTER::core::Status 
NativeDevice_WriteAsync(NativeDevice* device, const void* 
source, uint64_t dest, uint32_t length, 
FASTER::core::AsyncIOCallback callback, void* context) {
		return device->WriteAsync(source, dest, length, callback, 
context);

}
```

I need to define `FASTER::core::AsyncIOCallback callback` from 
D, any way to workaround ? (like modify garnet source code to 
support pass a C function callback)


I am newbie to C++ and D, any help will be appreciate



(here is the signature of callback)
https://github.com/microsoft/garnet/blob/ade2991f3737b9b5e3151d0dd0b614adfd4bcecd/libs/storage/Tsavorite/cc/src/device/async.h#L25

```cpp
typedef void(*AsyncIOCallback)(IAsyncContext* context, Status 
result, size_t bytes_transferred);

```

This can be written as following to match namespace and mangling 
scheme, assuming IAsyncContext is opaque pointer here, though I 
don't remember if enum need namespace as well.

But no guarantess anyways, try it and adapt it.
Also I can't remember if string list makes proper namespace or 
you should put `FASTER.core` instead (without quotes).


```d
enum Status : ubyte {
  Ok = 0,
  Pending = 1,
  NotFound = 2,
  OutOfMemory = 3,
  IOError = 4,
  Corruption = 5,
  Aborted = 6,
}

extern(C++, "FASTER", "core")
class IAsyncContext;

alias AsyncIOCallback = extern(C++, "FASTER", "core") void 
function(IAsyncContext context, Status result, size_t 
bytes_transferred);

```


need help to use C++ callback from garnet

2024-05-29 Thread Dakota via Digitalmars-d-learn
I try use 
https://github.com/microsoft/garnet/blob/main/libs/storage/Tsavorite/cc/src/device/native_device_wrapper.cc from D



Not sure how to make this work with D:

```c++
	EXPORTED_SYMBOL FASTER::core::Status 
NativeDevice_ReadAsync(NativeDevice* device, uint64_t source, 
void* dest, uint32_t length, FASTER::core::AsyncIOCallback 
callback, void* context) {
		return device->ReadAsync(source, dest, length, callback, 
context);

}

	EXPORTED_SYMBOL FASTER::core::Status 
NativeDevice_WriteAsync(NativeDevice* device, const void* source, 
uint64_t dest, uint32_t length, FASTER::core::AsyncIOCallback 
callback, void* context) {
		return device->WriteAsync(source, dest, length, callback, 
context);

}
```

I need to define `FASTER::core::AsyncIOCallback callback` from D, 
any way to workaround ? (like modify garnet source code to 
support pass a C function callback)


I am newbie to C++ and D, any help will be appreciate


Re: Get milliseconds from time and construct time based on milliseconds

2024-05-29 Thread bauss via Digitalmars-d-learn
On Tuesday, 28 May 2024 at 23:18:46 UTC, Steven Schveighoffer 
wrote:

On Tuesday, 28 May 2024 at 18:41:02 UTC, bauss wrote:
On Tuesday, 28 May 2024 at 18:29:17 UTC, Ferhat Kurtulmuş 
wrote:

On Tuesday, 28 May 2024 at 17:37:42 UTC, bauss wrote:
I have two questions that I can't seem to find a solution to 
after looking at std.datetime.


First question is how do I get the current time but in 
milliseconds?


Second is how do I construct a time ex. systime or datetime 
based on milliseconds?


Thanks


Unixtime might be what you want:

import std;

import std.datetime;
import std.stdio;

void main() {
// Get the current time in the UTC time zone
    auto currentTime = Clock.currTime();

// Convert the time to the Unix epoch 
(1970-01-01T00:00:00Z)
    Duration unixTime = currentTime - 
SysTime(DateTime(1970, 1, 1), UTC());


You can do `SysTime(unixTimeToStdTime(0))` to get a SysTime 
that is at the unix epoch.




Also figured out the second question based on your result.

Simply doing:

```
SysTime(DateTime(1970, 1, 1), UTC()) + 
dur!"msecs"(milliseconds)

```

Seems to work.


Note there is an `msecs` function:

```d
SysTime(unixTimeToStdTime(0)) + milliseconds.msecs;
```

https://dlang.org/phobos/std_datetime_systime.html#unixTimeToStdTime
https://dlang.org/phobos/core_time.html#msecs

-Steve


Thanks! That's a lot cleaner


Re: Get milliseconds from time and construct time based on milliseconds

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

On Tuesday, 28 May 2024 at 18:41:02 UTC, bauss wrote:

On Tuesday, 28 May 2024 at 18:29:17 UTC, Ferhat Kurtulmuş wrote:

On Tuesday, 28 May 2024 at 17:37:42 UTC, bauss wrote:
I have two questions that I can't seem to find a solution to 
after looking at std.datetime.


First question is how do I get the current time but in 
milliseconds?


Second is how do I construct a time ex. systime or datetime 
based on milliseconds?


Thanks


Unixtime might be what you want:

import std;

import std.datetime;
import std.stdio;

void main() {
// Get the current time in the UTC time zone
    auto currentTime = Clock.currTime();

// Convert the time to the Unix epoch 
(1970-01-01T00:00:00Z)
    Duration unixTime = currentTime - 
SysTime(DateTime(1970, 1, 1), UTC());


You can do `SysTime(unixTimeToStdTime(0))` to get a SysTime that 
is at the unix epoch.




Also figured out the second question based on your result.

Simply doing:

```
SysTime(DateTime(1970, 1, 1), UTC()) + dur!"msecs"(milliseconds)
```

Seems to work.


Note there is an `msecs` function:

```d
SysTime(unixTimeToStdTime(0)) + milliseconds.msecs;
```

https://dlang.org/phobos/std_datetime_systime.html#unixTimeToStdTime
https://dlang.org/phobos/core_time.html#msecs

-Steve


Re: Get milliseconds from time and construct time based on milliseconds

2024-05-28 Thread bauss via Digitalmars-d-learn

On Tuesday, 28 May 2024 at 18:29:17 UTC, Ferhat Kurtulmuş wrote:

On Tuesday, 28 May 2024 at 17:37:42 UTC, bauss wrote:
I have two questions that I can't seem to find a solution to 
after looking at std.datetime.


First question is how do I get the current time but in 
milliseconds?


Second is how do I construct a time ex. systime or datetime 
based on milliseconds?


Thanks


Unixtime might be what you want:

import std;

import std.datetime;
import std.stdio;

void main() {
// Get the current time in the UTC time zone
    auto currentTime = Clock.currTime();

// Convert the time to the Unix epoch 
(1970-01-01T00:00:00Z)
    Duration unixTime = currentTime - 
SysTime(DateTime(1970, 1, 1), UTC());


// Get the total milliseconds
long milliseconds = unixTime.total!"msecs";

// Print the Unix time in milliseconds
writeln("Unix time in milliseconds: ", milliseconds);
}


Thanks a lot.

Also figured out the second question based on your result.

Simply doing:

```
SysTime(DateTime(1970, 1, 1), UTC()) + dur!"msecs"(milliseconds)
```

Seems to work.


Re: Get milliseconds from time and construct time based on milliseconds

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

On Tuesday, 28 May 2024 at 17:37:42 UTC, bauss wrote:
I have two questions that I can't seem to find a solution to 
after looking at std.datetime.


First question is how do I get the current time but in 
milliseconds?


Second is how do I construct a time ex. systime or datetime 
based on milliseconds?


Thanks


Unixtime might be what you want:

import std;

import std.datetime;
import std.stdio;

void main() {
// Get the current time in the UTC time zone
    auto currentTime = Clock.currTime();

// Convert the time to the Unix epoch 
(1970-01-01T00:00:00Z)
    Duration unixTime = currentTime - SysTime(DateTime(1970, 
1, 1), UTC());


// Get the total milliseconds
long milliseconds = unixTime.total!"msecs";

// Print the Unix time in milliseconds
writeln("Unix time in milliseconds: ", milliseconds);
}



Get milliseconds from time and construct time based on milliseconds

2024-05-28 Thread bauss via Digitalmars-d-learn
I have two questions that I can't seem to find a solution to 
after looking at std.datetime.


First question is how do I get the current time but in 
milliseconds?


Second is how do I construct a time ex. systime or datetime based 
on milliseconds?


Thanks


Re: Hide console on Windows with app running SDL2

2024-05-28 Thread bauss via Digitalmars-d-learn
On Tuesday, 28 May 2024 at 12:45:39 UTC, Steven Schveighoffer 
wrote:

On Tuesday, 28 May 2024 at 12:35:42 UTC, bauss wrote:
Running into a couple of problems trying to hide the console 
that opens when running an app that uses sdl2.


First of all I am trying to compile with this using dub:

```
"lflags": ["/SUBSYSTEM:windows"]
```

However that gives me the following error:

```
error LNK2019: unresolved external symbol WinMain
```

And then if I add a WinMain like below:

```
extern (Windows) int WinMain() { return 0; }
```

Then of course it doesn't work, but what is the obvious way to 
solve this?


I basically just want to hide the console, but nothing seems 
to work straight out of the box.


I think this is still relevant: 
https://wiki.dlang.org/D_for_Win32


-Steve


Thanks a lot, that helped and solved the issue


Re: Hide console on Windows with app running SDL2

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

On Tuesday, 28 May 2024 at 12:35:42 UTC, bauss wrote:
Running into a couple of problems trying to hide the console 
that opens when running an app that uses sdl2.


First of all I am trying to compile with this using dub:

```
"lflags": ["/SUBSYSTEM:windows"]
```

However that gives me the following error:

```
error LNK2019: unresolved external symbol WinMain
```

And then if I add a WinMain like below:

```
extern (Windows) int WinMain() { return 0; }
```

Then of course it doesn't work, but what is the obvious way to 
solve this?


I basically just want to hide the console, but nothing seems to 
work straight out of the box.


I think this is still relevant: https://wiki.dlang.org/D_for_Win32

-Steve


Re: Implementation Details

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

On 28/05/2024 12:54 PM, Ruby The Roobster wrote:
As of late, I have taken up an interest in learning about how the D 
language is implemented at a compiler level, specifically the GC 
implementation.  Unfortunately, the source code is poorly documented, 
and is too large to simply read all of it in a reasonable amount of 
time.  If anyone here can help me, or at least point me to relevant 
resources, I would be very grateful.


From a theory standpoint this book should give you a pretty good 
overview of how GC's work. It is the book I recommend for introduction 
to GC's.


https://www.amazon.com/Garbage-Collection-Handbook-International-Perspectives-dp-1032218037/dp/1032218037/ref=dp_ob_title_bk

But yes that GC is very hard to get into, and its been tacked on over 
the years which make it even harder to untangle. Plus there is a memory 
allocator in there too.


Implementation Details

2024-05-27 Thread Ruby The Roobster via Digitalmars-d-learn
As of late, I have taken up an interest in learning about how the 
D language is implemented at a compiler level, specifically the 
GC implementation.  Unfortunately, the source code is poorly 
documented, and is too large to simply read all of it in a 
reasonable amount of time.  If anyone here can help me, or at 
least point me to relevant resources, I would be very grateful.


Re: Problem with clear on shared associative array?

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

On 28/05/2024 12:36 PM, Andy Valencia wrote:

On Monday, 27 May 2024 at 04:04:03 UTC, mw wrote:

Pls NOTE: it is
a   `sharded` (meaning trunk-ed) NON-concurrent map,
not `shared` concurrent map.


Assuming I put it in shared memory, in what way is it not able to be 
used concurrently?  It seems to have the needed lock operations?


Thanks,
Andy


A concurrent data structure handles all of this for you.

AA's are not concurrent because it doesn't offer any protection.

Protecting a data structure with a mutex doesn't make it concurrent, but 
it may allow you to use it concurrently safely. Subtle difference!


Re: Problem with clear on shared associative array?

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

On Monday, 27 May 2024 at 04:04:03 UTC, mw wrote:

Pls NOTE: it is
a   `sharded` (meaning trunk-ed) NON-concurrent map,
not `shared` concurrent map.


Assuming I put it in shared memory, in what way is it not able to 
be used concurrently?  It seems to have the needed lock 
operations?


Thanks,
Andy



Re: Problem with clear on shared associative array?

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

On Monday, 27 May 2024 at 00:43:47 UTC, Serg Gini wrote:

On Sunday, 26 May 2024 at 20:15:54 UTC, Andy Valencia wrote:
For others wrestling with this issue, I found out how to cast 
to unshared at this article:




You can check also this solution 
https://github.com/DmitryOlshansky/sharded-map



Pls NOTE: it is
a   `sharded` (meaning trunk-ed) NON-concurrent map,
not `shared` concurrent map.

These two words looks similar, but the meaning is very different.




Re: Problem with clear on shared associative array?

2024-05-26 Thread Serg Gini via Digitalmars-d-learn

On Sunday, 26 May 2024 at 20:15:54 UTC, Andy Valencia wrote:
For others wrestling with this issue, I found out how to cast 
to unshared at this article:




You can check also this solution 
https://github.com/DmitryOlshansky/sharded-map


Re: Problem with clear on shared associative array?

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

On Sunday, 26 May 2024 at 20:00:50 UTC, Jonathan M Davis wrote:
No operation on an associative array is thread-safe. As such, 
you should not be doing _any_ operation on a shared AA without 
first locking a mutex to protect it. Then you need to cast away 
shared to access or mutate it or do whatever it is you want to 
do with it other than pass it around. And then when you're 
done, you make sure that no thread-local references to the AA 
exist, and you release the mutex.

...


Thank you, that's exactly the big picture explanation I was 
hoping for.


For others wrestling with this issue, I found out how to cast to 
unshared at this article:


https://forum.dlang.org/thread/jwasqvrvkpqzimlut...@forum.dlang.org

Andy



Re: Problem with clear on shared associative array?

2024-05-26 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, May 26, 2024 8:39:53 AM MDT Andy Valencia via Digitalmars-d-learn 
wrote:
> The following code fails to compile; it appears from the error
> message that the library's clear() function is not ready to act
> on a shared AA?
>
> synchronized class F {
>
> private:
>  string[int] mydict;
>
> public:
>  void clear() {
>  this.mydict.clear();
>  }
> }
>
> void
> main()
> {
>  auto f = new shared F();
>  f.clear();
> }

No operation on an associative array is thread-safe. As such, you should not
be doing _any_ operation on a shared AA without first locking a mutex to
protect it. Then you need to cast away shared to access or mutate it or do
whatever it is you want to do with it other than pass it around. And then
when you're done, you make sure that no thread-local references to the AA
exist, and you release the mutex. This is true for any type which is not
specifically designed to be shared, and none of the built-in types are
designed to be shared. They will work as shared so long as you protect them
appropriately and then temporarily cast away shared to operate on them as
thread-local, but they should never be mutated as shared, and it's on you to
make sure that the object is actually protected appropriately when you cast
away shared, since the language has no way of knowing when that's actually
safe to do. It can just prevent you from accidentally accessing an object
when it's shared, since when it's shared, the type system marks it as shared
across threads and thus not thread-safe to access.

The language is supposed to prevent you from doing any operations on a
shared object which are not guaranteed to be thread-safe (which is pretty
much anything other than passing it around by reference or pointer), but
unfortunately, since that wasn't entirely implemented up front, some of
those checks are currently behind the -preview=nosharedaccess flag and will
be made the default at some point in the future (but not now). So, some
shared operations may work when they really shouldn't, but the compiler will
prevent you from calling a function like clear, because it operates on
thread-local variables, not shared ones.

And with regards to AAs, you will need to be particularly careful with the
in operator, because it returns a pointer a value in the AA. So, if you cast
away shared to operate on it and then use in, you'll get a thread-local
pointer to the AA, meaning that the lock needs to stay in place as long as
that pointer is around, whereas a function like clear is done as soon as its
been called, so unless you're doing more with the AA at that point, you
could release the lock then.

Using synchronized is one way to get a mutex, and a synchronized function is
implicitly shared, so your clear function is both synchronized and shared,
meaning that you can call it on a shared object, and it will lock a mutex
when it's called, but you still need to cast away shared from mydict to be
able to call anything on it. The compiler is not smart enough to know that
removing shared is thread-safe within your function, so it will not do it
for you, and the clear function for AAs can't work on shared AAs, because it
has no way of guaranteeing that that's thread-safe. So, the solution is that
you must explicitly removed shared temporarily to call clear when you know
that it's thread-safe to do so.

- Jonathan M Davis





Problem with clear on shared associative array?

2024-05-26 Thread Andy Valencia via Digitalmars-d-learn
The following code fails to compile; it appears from the error 
message that the library's clear() function is not ready to act 
on a shared AA?


synchronized class F {

private:
string[int] mydict;

public:
void clear() {
this.mydict.clear();
}
}

void
main()
{
auto f = new shared F();
f.clear();
}


Re: How does one attach a manifest file to a D executable on Windows?

2024-05-25 Thread John Chapman via Digitalmars-d-learn

On Saturday, 25 May 2024 at 13:13:08 UTC, solidstate1991 wrote:

No, I meant something like this:

https://learn.microsoft.com/en-us/windows/win32/controls/cookbook-overview


Not tested but from memory I do this:

1) Copy that first XML snippet from the page you linked, save to 
a file called example.exe.manifest
2) Create a resource script file called resources.rc, with this 
at the top:

   1 24 "example.exe.manifest"
3) Compile it with rc.exe
4) Include the resulting resources.res on your DMD command line

You might also need to call InitCommonControls or 
InitCommonControlsEx before creating any windows.


Re: How does one attach a manifest file to a D executable on Windows?

2024-05-25 Thread solidstate1991 via Digitalmars-d-learn

On Friday, 24 May 2024 at 21:26:12 UTC, Ferhat Kurtulmuş wrote:

I think this is what you need

https://github.com/aferust/doitlater/tree/master/views/res


No, I meant something like this:

https://learn.microsoft.com/en-us/windows/win32/controls/cookbook-overview


Re: Parallel safe associative array?

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

https://code.dlang.org/packages/rust_interop_d

wrapped:

DashMap: is an implementation of a concurrent associative 
array/hashmap in Rust.


Re: How does one attach a manifest file to a D executable on Windows?

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

On Friday, 24 May 2024 at 21:04:53 UTC, Ferhat Kurtulmuş wrote:

On Friday, 24 May 2024 at 19:07:24 UTC, solidstate1991 wrote:
I have tried resource compiling, then using `dflags` in dug to 
add the resulting obj file, but I still get the issue of the 
old GUI style.


I did that before, but I don't remember now. Probably you will 
figure that out based on this.


https://gitlab.com/aferust/gtkdappcreator/-/tree/master/win_res?ref_type=heads


I think this is what you need

https://github.com/aferust/doitlater/tree/master/views/res



Re: How does one attach a manifest file to a D executable on Windows?

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

On Friday, 24 May 2024 at 19:07:24 UTC, solidstate1991 wrote:
I have tried resource compiling, then using `dflags` in dug to 
add the resulting obj file, but I still get the issue of the 
old GUI style.


I did that before, but I don't remember now. Probably you will 
figure that out based on this.


https://gitlab.com/aferust/gtkdappcreator/-/tree/master/win_res?ref_type=heads


Parallel safe associative array?

2024-05-24 Thread Andy Valencia via Digitalmars-d-learn
I was playing with parallel programming, and experienced 
"undefined behavior" when storing into an Associative Array in 
parallel.  Guarding the assignments with a synchronized barrier 
fixed it, of course.  And obviously loading down your raw AA with 
thread barriers would be foolish.


But this set me searching through the library for a standard 
Associative Array construct which _is_ thread safe?  It didn't 
jump out at me.  I know I can place such a thing within a 
synchronized class, but I was wondering if there's a standard AA 
which has the standard usage but is safe when called in parallel?


Thanks,
Andy



Re: Recommendations on porting Python to D

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

On Friday, 3 May 2024 at 17:53:41 UTC, mw wrote:

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:

[...]


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.


I took another quick look of the project, it uses the Python 
builtin `ast` module as parser, and visitor design pattern to 
implement the transcompiler, so I think it's of decent quality.


HTH.


Re: Anybody know about SDL and particularly SDL_TTF initialization?

2024-05-23 Thread Jerry via Digitalmars-d-learn

On Sunday, 12 May 2024 at 20:13:04 UTC, WhatMeWorry` wrote:


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


Something hit a null pointer, time to fire up the debugger :)




Re: Anybody know about SDL and particularly SDL_TTF initialization?

2024-05-22 Thread Danny Arends via Digitalmars-d-learn

On Sunday, 12 May 2024 at 20:13:04 UTC, WhatMeWorry` wrote:

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


No idea why this fails, seems alright to me. You can use: 
TTF_GetError() for a human-readable error message,when the call 
to TTF_Init() fails (return -1).


Good luck
Danny


Re: __gshared is "somewhat" transitive, isn't it ?

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

On Thursday, 16 May 2024 at 17:04:09 UTC, user1234 wrote:

Given

```d
struct S
{
int member;
}

__gshared S s;
```

It's clear that `s.member` is `__gshared` too, right ?
What does happen for

```d
struct S
{
int member;
static int globalMember;
}

__gshared S s;
```

Is then `S.globalMember` a TLS variable ? (I'd expect that)


`__gshared` is a storage class. It means, store this thing in the 
global memory segment. `static` storage class means store this 
thing in TLS.


Storage classes are *not* transitive, and they are not type 
constructors. They optionally might apply a type constructor to 
the type (such as the `const` storage class), but not always.


So in this case `typeof(s)` is `S`, not `__gshared S`. `s.member` 
is in the global segment since structs members are placed within 
the struct memory location (in this case, the global memory 
segment).


`globalMember` is placed in TLS because it's storage class is 
`static`, and `static` means, do not store with the instance 
(which for `s` would mean the global memory segment), but rather 
in TLS.


-Steve


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;
}
```


  1   2   3   4   5   6   7   8   9   10   >