Re: SumType extraction

2024-07-06 Thread Christian Köstlin via Digitalmars-d-learn

On Thursday, 27 June 2024 at 18:51:19 UTC, Josh Holtrop wrote:

Questions:
4. Any other general improvements to my solution?



I know it's kind of an unpopular choice these days but one could 
go

with inheritance and polymorphism or instanceof tests. something
along the lines of
```d
import std.stdio : writeln;

class Item
{
public void operationA()
{
}

public void operationB()
{
}
}

class ItemA : Item
{
override public void operationA()
{
writeln("ItemA");
}
}

class ItemB : Item
{
override public void operationB()
{
writeln("ItemB");
}
}

void main(string[] args)
{
auto items = [new ItemA(), new ItemB()];
writeln("operation a:");
foreach (item; items)
{
item.operationA();
}
writeln("operation b:");
foreach (item; items)
{
item.operationB();
}

writeln("instance of:");
foreach (item; items)
{
if (auto itemB = cast(ItemB) item)
{
writeln("Found an ItemB");
}
}
}
```

drawback might be, that if you add a new subtype the compiler will
not warn you that you did not implement one case for one of the
implementations.

Kind regards,
Christian


Re: Partial function application (Currying)

2024-01-20 Thread Christian Köstlin via Digitalmars-d-learn

Would
https://dlang.org/library/std/functional/curry.html
help you?

kind regards,
Christian


Re: Synchronisation help

2024-01-02 Thread Christian Köstlin via Digitalmars-d-learn

On Tuesday, 2 January 2024 at 10:41:55 UTC, Anonymouse wrote:
On Monday, 1 January 2024 at 19:49:28 UTC, Jonathan M Davis 
wrote:

[...]


Thank you. Yes, `Foo` is a class for the purposes of 
inheritance -- I left that out of the example.


So a completely valid solution is to write a struct wrapper 
around an AA of the type I need, overload the required 
operators, and then just drop-in replace the current AA? All 
array operations would then transparently be between lock and 
unlock statements.


[...]

I guess this can break synchronisation between the two if I 
replace the `Mutex` in either thread. Are there any other 
obvious caveats?


It might be, that this locking scheme is too narrow. E.g. you 
might want to have an "atomic" testAndSet on the AA e.g. check if 
an element is in and iff its not in put it there.


Kind regards,
Christian


Re: How to implement filterMap

2023-12-30 Thread Christian Köstlin via Digitalmars-d-learn
On Saturday, 30 December 2023 at 18:08:55 UTC, Alexandru Ermicioi 
wrote:
On Friday, 29 December 2023 at 23:10:47 UTC, Christian Köstlin 
wrote:
Is there a way to implement filterMap (meaning do mapping of a 
range, but if something happens during the map, leave this 
element out of the resulting range).


Perhaps try map to null cases that exception is thrown then 
filter out those, and then unwrap from nullable type:

```d
myRange.map!(e => e.to!T.asNullForException).filter!(e => 
!e.isNull).map!(e => e.get).myOtherAlgorithm()

```

where asNullForException will return empty `Nullable` in case 
conversion fails.


asNullForException could be nicely implemented with lazy 
parameters i guess.
then its back to the map/filter/map chain that motivated 
filter_map in rust ...

thanks for this idea...

kind regards,
Christian



Re: How to implement filterMap

2023-12-30 Thread Christian Köstlin via Digitalmars-d-learn
On Saturday, 30 December 2023 at 01:22:31 UTC, Siarhei Siamashka 
wrote:
On Friday, 29 December 2023 at 23:10:47 UTC, Christian Köstlin 
wrote:
Is there a way to implement filterMap (meaning do mapping of a 
range, but if something happens during the map, leave this 
element out of the resulting range).


It's probably not a good idea to do this in general. Expecting 
a lot of exceptions handling happening during normal program 
execution (if you want to filter out roughly half of the input 
array) will result in a major performance loss. Exceptions are 
best left to just do error handling on a very rarely used code 
path for troubleshooting purposes.

Thanks for the feedback.

This might be true, but in my example I would parse the input 
always with conv.to, so I would need to handle the exception(s).
The "original" 
https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.filter_map works with the Option(Some/None) ...


Kind regards,
Christian



How to implement filterMap

2023-12-29 Thread Christian Köstlin via Digitalmars-d-learn
Is there a way to implement filterMap (meaning do mapping of a 
range, but if something happens during the map, leave this 
element out of the resulting range).
I have two solutions (one is with evaluating the mapping function 
several times), and one tries to store the result for the next 
front call like this.
Both do not seem very clean for all possible types. Here the 
version that tries to cache the mapping results.


```d
template filterMap(mapping...) if (mapping.length == 1)
{
auto filterMap(Range)(Range range)
{
import std.range : ElementType, empty;
import std.functional : unaryFun;

alias RangeElement = ElementType!Range;
alias mappingFunction = unaryFun!mapping;
typeof(mappingFunction(RangeElement.init)) result;

void findNext() {
while (!range.empty)
{
try
{
result = mappingFunction(range.front);
break;
}
catch (Exception e)
{
range.popFront;
}
}
}
findNext();
struct FilterMap
{
bool empty()
{
return range.empty;
}

auto ref front()
{
return result;
}

void popFront()
{
range.popFront;
findNext();
}
}

return FilterMap();
}
}

@("filterMap") unittest {
import std.conv : to;
import std.array : array;
["1", "2", "abc", ""].filterMap!(s => s.to!int * 
2).array.should == [2, 4];

}
```

Kind regards,
Christian



Re: Non-blocking keyboard input

2023-12-27 Thread Christian Köstlin via Digitalmars-d-learn
On Wednesday, 27 December 2023 at 14:41:05 UTC, Christian Köstlin 
wrote:
One option (not tested) should be to close stdin so that readln 
then returns null or something on eof.


Shutting down threads is always tricky.

It would be great if there would be one or two (perhaps one 
synchronous, one asynchronous) main io-frameworks for dlang 
(also as dub packages) that cover the most common use-cases.



Kind regards,
Christian

I tested this now, but it still blocks in readln ...

Kind regards,
Christian



Re: Non-blocking keyboard input

2023-12-27 Thread Christian Köstlin via Digitalmars-d-learn

On Wednesday, 27 December 2023 at 05:07:04 UTC, Joe wrote:
??? Surely there there is a 
one liner library solution  for this?


I have a program that spawns a thread for debugging information 
and uses the keyboard input which allows me to display the 
information.


If I use getchar or readline then it blocks the thread. This is 
generally fine because that is all the thread does. The problem 
is that it also blocks the program termination as the main 
thread will not exit while the thread is running which is is 
because it's waiting on keyboard input stuck on getchar or 
fgetc or whatever.


If I terminate the threads using thread_term then it terminates 
the program but the program then does not return the return 
code that it was successfully finished(because it was 
prematurely terminated by thread_term.


Surely there is some type of peek for keyboards in D? I can't 
seem to get kbhit or because the library is not included(well, 
I tried to use one from dmc but it seemed to be invalid. 
snn.lib IIRC).



This shouldn't be hard... yet it is.


One option (not tested) should be to close stdin so that readln 
then returns null or something on eof.


Shutting down threads is always tricky.

It would be great if there would be one or two (perhaps one 
synchronous, one asynchronous) main io-frameworks for dlang (also 
as dub packages) that cover the most common use-cases.



Kind regards,
Christian



Re: Behaves different on my osx and linux machines

2023-12-27 Thread Christian Köstlin via Digitalmars-d-learn

On Wednesday, 27 December 2023 at 14:03:06 UTC, Kagamin wrote:

Maybe you're not supposed to print text while reading?


In parallel I have contacted schveiguy on discord and he found 
the culprid. But we do not have a solution yet. It probably will 
result in a bugreport at https://issues.dlang.org/.


Kind regards,
Christian




Re: Behaves different on my osx and linux machines

2023-12-22 Thread Christian Köstlin via Digitalmars-d-learn

On Friday, 22 December 2023 at 15:02:42 UTC, Kagamin wrote:

Add more debugging?
```
 bool done = false;
 while (!done) {
 writeln(1);
 auto result = ["echo", "Hello World"].execute;
 if (result.status != 0)
 {
 writeln(2);
 throw new Exception("echo failed");
 }
 writeln(result.output);
 receiveTimeout(dur!"msecs"(-1),
   (LinkTerminated t) {
   writeln("Done");
   done = true;
   },
 );
 writeln(3);
 }
 writeln("ByeBye");
```

Thanks for the suggestion. But it still behaves the same:
Output:
```
 Running vibe-io
1
Please enter something:
asdf
You entered asdf

Please enter something:
Hello World

3
1
asdf
You entered asdf

Please enter something:
Hello World

3
1
qwer
You entered qwer

Please enter something:
Hello World

3
1
```


Behaves different on my osx and linux machines

2023-12-21 Thread Christian Köstlin via Digitalmars-d-learn
I have this somehow reduced program that behaves differently on osx and 
linux.



```d
void stdioMain()
{
import std.stdio : readln, writeln;
import std.concurrency : spawnLinked, receive, receiveTimeout, 
LinkTerminated;

import std.variant : Variant;
import std.string : strip;
import std.process : execute;
import core.time : dur;
auto input = spawnLinked(() {
string getInput() {
writeln("Please enter something:");
return readln().strip();
}
string line = getInput();
while (line != "quit")
{
writeln("You entered ", line);
line = getInput();
}
});

bool done = false;
while (!done) {
auto result = ["echo", "Hello World"].execute;
if (result.status != 0)
{
throw new Exception("echo failed");
}
writeln(result.output);
receiveTimeout(dur!"msecs"(-1),
  (LinkTerminated t) {
  writeln("Done");
  done = true;
  },
);
}
writeln("ByeBye");
}

void main(string[] args)
{
stdioMain();
}
`

It should just read from stdin in one separate thread and on the main 
thread it just executes one `echo` after the other (and tries to find 
out, if the other thread finished).


In linux this behaves as expected, meaning it prints a lot of hello worlds.

In osx on the other hand it prints 'please enter something', waits for 
my input, prints it, and outputs one hello world.


What did I do wrong?

Kind regards,
Christian

p.s.: i am using ldc-1.35.0 osx version is 13.6.


Re: How do I install a package globally?

2023-11-13 Thread Christian Köstlin via Digitalmars-d-learn

On Saturday, 11 November 2023 at 23:28:18 UTC, Trevor wrote:
On Saturday, 11 November 2023 at 07:12:21 UTC, Christian 
Köstlin wrote:

On Saturday, 11 November 2023 at 01:50:54 UTC, Trevor wrote:
I'm just getting in to D , coming from a C and Python 
background. I've had a play with DUB and adding packages to 
my project, but it seems like there should be a way to 
install packages so they can be used in any D program I 
compile without creating a whole package. For example in 
Python you can just go "pip install abc" and then any script 
can use abc.


How does one install packages globally, and how can I write 
programs that use the third-party packages without being 
wrapped in a dub file?


There is no way to install a dependency for all your d 
programs globally.
In general you also should be careful about which dependencies 
you pull in and control them tightly.


In general the approach taken by dub is slightly different.
The dependencies you are using in all your programs are put to 
`$HOME/.dub/packages/...` and are in theory available for all 
your programs, but you still have to tell dub, that you want 
to use one of them. This is similar to python in that, pip 
puts your dependencies somewhere in your `$PYTHONHOME` or 
`$PYTHONPATH` (I am not 100% sure about that).
You can tell dub (and dub then tells the compiler where to 
find the dependencies) in two way:
- Create a complete dub project with dub.json/sdl and add the 
dependency there (e.g. with `dub add` or while creating the 
project or by adding them in your editor to the dub.json/sdl)
- Create a self executing d file (that is run when you just 
call it like a script and compiled on the fly). See 
https://dub.pm/advanced_usage#single-file for details.


Another way dub is able to "install" something is by using 
`dub fetch` to pull a package with a binary in it (e.g. `dub 
fetch dfmt`). You then can run this executable by `dub run` 
(e.g. `dub run dfmt -- ... here go the arguments to the dfmt 
tool).


Kind regards,
Christian


Thanks for the detailed reply. I guess what I'd like to do is 
not create a DUB package for every little project I work on. It 
seems like most modern languages require a package/dependency 
manager though. Being able to install libraries globally would 
avoid this but I can how that can cause it's own set of issues. 
It doesn't seem efficient in terms of bandwidth and hard disk 
space to have a new copy of a library for each project that 
uses it?


Did you try https://dub.pm/advanced_usage#single-file for your 
usecase.
This one installs the dependencies once in `$HOME/.dub` and 
compiles them on the fly.


- For small projects this is I think quite nice.
- For medium projects I like how dub works at the moment with a 
`dub.sdl/json` in the projects folder and the shared cache of 
dependencies in `$HOME/.dub`.
- For really big problems I would like to have a way to install 
the dependencies really locally to the project (just to have more 
control over them, e.g. like ruby's `bundle package` command 
works).


Kind regards,
Christian


Re: How do I install a package globally?

2023-11-10 Thread Christian Köstlin via Digitalmars-d-learn

On Saturday, 11 November 2023 at 01:50:54 UTC, Trevor wrote:
I'm just getting in to D , coming from a C and Python 
background. I've had a play with DUB and adding packages to my 
project, but it seems like there should be a way to install 
packages so they can be used in any D program I compile without 
creating a whole package. For example in Python you can just go 
"pip install abc" and then any script can use abc.


How does one install packages globally, and how can I write 
programs that use the third-party packages without being 
wrapped in a dub file?


There is no way to install a dependency for all your d programs 
globally.
In general you also should be careful about which dependencies 
you pull in and control them tightly.


In general the approach taken by dub is slightly different.
The dependencies you are using in all your programs are put to 
`$HOME/.dub/packages/...` and are in theory available for all 
your programs, but you still have to tell dub, that you want to 
use one of them. This is similar to python in that, pip puts your 
dependencies somewhere in your `$PYTHONHOME` or `$PYTHONPATH` (I 
am not 100% sure about that).
You can tell dub (and dub then tells the compiler where to find 
the dependencies) in two way:
- Create a complete dub project with dub.json/sdl and add the 
dependency there (e.g. with `dub add` or while creating the 
project or by adding them in your editor to the dub.json/sdl)
- Create a self executing d file (that is run when you just call 
it like a script and compiled on the fly). See 
https://dub.pm/advanced_usage#single-file for details.


Another way dub is able to "install" something is by using `dub 
fetch` to pull a package with a binary in it (e.g. `dub fetch 
dfmt`). You then can run this executable by `dub run` (e.g. `dub 
run dfmt -- ... here go the arguments to the dfmt tool).


Kind regards,
Christian




Re: Weird bug in std.logger? Possible memory corruption

2023-11-01 Thread Christian Köstlin via Digitalmars-d-learn

On Wednesday, 1 November 2023 at 14:15:55 UTC, matheus wrote:

On Tuesday, 31 October 2023 at 21:19:34 UTC, Arafel wrote:

...

Assigning the value to a variable works as expected:

```d
import std.logger : info;

void main() {
auto s = foo();
info(s);
}

auto foo() {
info("In foo");
return "Hello, world.";
}
```
...


Unless you do:

string s;
info(s=foo());

I think this is a bug, or at least very weird behavior.

Matheus.

It's really weird: https://run.dlang.io/is/fIBR2n



Re: Removing an element from a DList

2023-10-18 Thread Christian Köstlin via Digitalmars-d-learn

On Tuesday, 17 October 2023 at 17:27:19 UTC, Joakim G. wrote:
For some reason I cannot remove an element from a DList. I 
tried several range approaches but to no avail. I'm a noob.


In the end I did this:

```
private void removeFromWaitingQueue(uint jid) {
auto arr = waitingQueue[].array;
arr = arr.remove!(job => job.jid == jid);
waitingQueue.clear();
foreach(job; arr) {
waitingQueue.insertBack(job);
}
}
```

Any hints?

/J


```d
import std.container : DList;
import std.algorithm : find;
import std.range : take;
import std.stdio : writeln;
import std.range : take;
struct Job
{
int id;
}
int main(string[] args)
{
auto list = DList!Job(Job(1), Job(2), Job(3));
int idToDelete = 2;
auto toRemove = list[].find!(job => job.id == 
idToDelete).take(1);

if (!toRemove.empty)
list.linearRemove(toRemove);

foreach (i; list[])
{
writeln(i);
}

return 0;
}
```
works for me ... see https://run.dlang.io/is/OtX820 for a live 
version.


Kind regards,
Christian


Re: Vibe.d download function, how to get callback when done or error?

2023-09-24 Thread Christian Köstlin via Digitalmars-d-learn

On 24.09.23 12:01, j...@bloow.edu wrote:

On Saturday, 23 September 2023 at 20:20:31 UTC, Christian Köstlin wrote:

On 23.09.23 14:07, j...@bloow.edu wrote:

I'm using download(url, filename) to download files in vibe.d.

The issue is that I do not know when the download is finished or 
errors. There is a callback for the streaming side but not for the 
file download.


A small test program shows, that if the function return normally the 
transfer was done (and the file saved).
The function raises an exception if there is e,g, an http error status 
communicated.


I am not sure what happens if the download is interrupted in the 
middle. I guess there will be an exception, but the file might be 
written partially.




Kind regards,
Christian


I can't do any testing because overnight for no explicable reason the 
app will not compile any more.


If it is synchronous then I should be able to do what I need without 
issue. When I initially was using it and the way the app works it seemed 
like it was running in parallel because I didn't see it execute 
synchronously because the tasks were relatively short and I just thought 
it was asynchronous for some reason(I didn't give it any thought at the 
time until I got errors in the download and needed to make the code more 
robust but I can't do anything until I figure out why the code no longer 
compiles(I made a post about it but it's not showing up yet).




I recommend to use
`https://httpbin.org/drip?duration=20&numbytes=100&code=200&delay=0` as 
url to test vibes download.


Kind regards,
Christian



Re: Vibe.d download function, how to get callback when done or error?

2023-09-24 Thread Christian Köstlin via Digitalmars-d-learn

On 24.09.23 12:01, j...@bloow.edu wrote:

On Saturday, 23 September 2023 at 20:20:31 UTC, Christian Köstlin wrote:

On 23.09.23 14:07, j...@bloow.edu wrote:

I'm using download(url, filename) to download files in vibe.d.

The issue is that I do not know when the download is finished or 
errors. There is a callback for the streaming side but not for the 
file download.


A small test program shows, that if the function return normally the 
transfer was done (and the file saved).
The function raises an exception if there is e,g, an http error status 
communicated.


I am not sure what happens if the download is interrupted in the 
middle. I guess there will be an exception, but the file might be 
written partially.




Kind regards,
Christian


I can't do any testing because overnight for no explicable reason the 
app will not compile any more.


If it is synchronous then I should be able to do what I need without 
issue. When I initially was using it and the way the app works it seemed 
like it was running in parallel because I didn't see it execute 
synchronously because the tasks were relatively short and I just thought 
it was asynchronous for some reason(I didn't give it any thought at the 
time until I got errors in the download and needed to make the code more 
robust but I can't do anything until I figure out why the code no longer 
compiles(I made a post about it but it's not showing up yet).
minimal program to test the behavior (although with fibers it might be 
tricky to see whats really going on .. perhaps try to do two downloads 
after each other and see how the program behaves):



```d
import vibe.vibe;
import std.stdio : writeln;

void main(string[] args)
{
try {
download(args[1], args[2]);
} catch (Exception e)
{
writeln("puh: ", e);
}
}
```

Kind regards,
Christian


Re: Vibe.d download function, how to get callback when done or error?

2023-09-23 Thread Christian Köstlin via Digitalmars-d-learn

On 23.09.23 14:07, j...@bloow.edu wrote:

I'm using download(url, filename) to download files in vibe.d.

The issue is that I do not know when the download is finished or errors. 
There is a callback for the streaming side but not for the file download.


A small test program shows, that if the function return normally the 
transfer was done (and the file saved).
The function raises an exception if there is e,g, an http error status 
communicated.


I am not sure what happens if the download is interrupted in the middle. 
I guess there will be an exception, but the file might be written partially.




Kind regards,
Christian



Re: change object class

2023-09-23 Thread Christian Köstlin via Digitalmars-d-learn

On 23.09.23 05:11, Vitaliy Fadeev wrote:

On Friday, 22 September 2023 at 19:50:17 UTC, Christian Köstlin wrote:

another option could be to model your own VTable in a struct like this:
https://run.dlang.io/is/3LTjP5

Kind regards,
Christian


Thank, Christian !
True nice tasty solution with ```VTable```!
And further... the project is growing.
```
void Draw()
{
   DrawBG();
   DrawFG();
}
```

And we want use ```DrawBG()``` code  from ```initial``` in other states, 
like ```Selected```.


How to use some functions from ```initial``` via ```VTable``` ?

I see solution in ```classes``` and methods with ```override``` keyword.

```VTable``` does the same thing as ```__vptr``` ?


VTable is your structure .. it does exactly what you want it to do.
__vptr is the internal implementation of virtual methods in the dlang 
object model.
Line 20 and 21 in my example initialize the two `VTable`s Initial and 
Hovered. You can change VTable to contain two function pointers and 
initialize those as you like for the instances of the VTable structs.


e.g.
```d
struct DrawVTable
{
   void function(Chip, Renderer) background;
   void function(Chip, Renderer) foreground;
}

// define functions to draw the different fore and backgrounds
...
...

VTable initial = VTable(&drawInitialBackground, &drawInitialForeground);
VTable hovered = VTable(&drawHoveredBackground, &drawHoveredForeground);
VTable selected = VTable(&drawInitialBackground, &drawHoveredForegtround);

```

Kind regards,
Christian




Re: change object class

2023-09-22 Thread Christian Köstlin via Digitalmars-d-learn

On 23.09.23 05:25, Vitaliy Fadeev wrote:

On Friday, 22 September 2023 at 19:50:17 UTC, Christian Köstlin wrote:

On 17.09.23 17:05, Vitaliy Fadeev wrote:

Hi!


You could model it oop style like this:
https://run.dlang.io/is/MJb5Fk
This solution might not be to your taste, as it involves interfaces, 
and classes and objects and garbage (all the news) ...


another option could be to model your own VTable in a struct like this:
https://run.dlang.io/is/3LTjP5

Kind regards,
Christian


```Behavior``` is beautiful code!

But it contains a second ```new``` when ```Chip``` is created. One 
```new``` is possible?


Christian, really nice code!

Here a solution with less `new`s: https://run.dlang.io/is/iV1qVq.
It really depends on the program that you are doing if creating those 
news is a problem.


Kind regards,
Christian



Re: change object class

2023-09-22 Thread Christian Köstlin via Digitalmars-d-learn

On 17.09.23 17:05, Vitaliy Fadeev wrote:

Hi!
I want to change a method ```Draw``` on a custom object when the 
```MouseIn``` event occurs.

This is known as "Change State" of the object: ```Init``` -> ```Hovered```.

I want to change the state of an object by changing its class, like this:

```d

this.__vptr = typeid(CLS).vtbl.ptr;

```

I have read the ABI and am confident in replacing ```__vptr``` as long 
as the classes contain the same fields and the same interfaces.


Example:
```d
// O
//   to!state
// State_Init    : O
//   Draw
// State_Hovered : O
//   Draw
//
// o.to!State_Hovered
// o.to!State_Init

class O
{
   void to(CLS)()
   {
     // if (same fields && same interfaces && same instance size)
     this.__vptr =
   cast(immutable(void*)*)typeid(CLS).vtbl.ptr;
   }
}

State_Init : O
   void Draw() { /* ... */ }

State_Hovered : O
   void Draw() { /* ... */ }
```

when MouseIn:

```d
   ...
   o.to!State_Hovered();
   ...
```

when MouseOut:
```d
   ...
   o.to!State_Init();
   ...
```

It works! But I want to ask how to make this 100% the best of the best?
What should I consider before changing ```__vptr``` ?


You could model it oop style like this:
https://run.dlang.io/is/MJb5Fk
This solution might not be to your taste, as it involves interfaces, and 
classes and objects and garbage (all the news) ...


another option could be to model your own VTable in a struct like this:
https://run.dlang.io/is/3LTjP5

Kind regards,
Christian



Re: Json Help

2023-09-12 Thread Christian Köstlin via Digitalmars-d-learn

On 10.09.23 13:06, Vino wrote:

Hi All,

   Request your help on the below code,I am trying to convert the below 
string to json and it always throws the error, if the below can be 
accomplished with any other json package even that is fine, I tired only 
the std.json package.


Test Program: Works

import std.json;
import std.stdio: writeln;

void main () {

auto sadrsJson = parseJSON(`{ "TestHost": { "Building1": { "RackNo": 
123}}}`);

writeln(sadrsJson);

}
```
Program: Does not Work
```
import std.json;
import std.stdio;
import std.container;
import std.socket: Socket;
import std.stdio: writeln;

void main () {

string host = Socket.hostName;
string registry = "Test"

Array!string output;
Array!string errors;

output.insertBack("TESTOUTPUT");
errors.insertBack("TESTERRORS");

auto sadrsJson = parseJSON({ host: { registry: { "OUTPUT": output[], 
"ERROR": errors[]}}});

writeln(sadrsJson);

}

From,
Vino.B

`parseJSON` takes a string as arguments and tries to parse it as JSON.
The first example works, because your argument is a string and in JSON 
format.


The argument in the second example is not a string, and if it would be a 
string, its not JSON (e.g. `host:` is not `"host":`)...


Kind regards,
Christian



Re: pipeProcess output to hash string

2023-09-11 Thread Christian Köstlin via Digitalmars-d-learn

On 09.09.23 17:44, Vino wrote:

Hi All,

   Request your help on how to convert the output of 
std.process.pipeProcess to hash string


```

auto test(in Redirect redirect=Redirect.stdout | Redirect.stderr) {
     import std.process;
     import std.digest.crc;
     import std.stdio: writeln;

  result = std.process.pipeProcess("whoami" ~ "/?", redirect);
  auto content = result.stdout.readln;
  auto hash = crc32Of(content);
  return hash;
}
void main() {
   writeln(test);
}
```

Output: All writes the below.
```
[0, 0, 0, 0]
```

Required: Read the completed output and convert it to a single hash string.

From,
Vino.B

Good that you could solve your problem already.

Just three remarks:

First I would recommend to use `std.process : execute` instead of
`pipeProcess` in this usecase, as this will wait properly for the 
process to exit and it also will collect its output.


Second its always good to test the exit status of the process ... just 
in case.


Third I would not look at `stderr` too much .. well behaved commandline 
tools should not put data for machines there.


Kind regards,
Christian


Re: parallel threads stalls until all thread batches are finished.

2023-08-29 Thread Christian Köstlin via Digitalmars-d-learn

On 29.08.23 00:37, j...@bloow.edu wrote:
Well, I have 32 cores so that would spawn 64-1 threads with hyper 
threading so not really a solution as it is too many simultaneous downs 
IMO.



"These properties get and set the number of worker threads in the 
TaskPool instance returned by taskPool. The default value is totalCPUs - 
1. Calling the setter after the first call to taskPool does not changes 
number of worker threads in the instance returned by taskPool. "


I guess I could try to see if I can change this but I don't know what 
the "first call" is(and I'm using parallel to create it).
The call that is interesting in your case is the call to `taskPool` in 
your foreach loop. So if you call `defaultPoolThreads(8)` before your 
loop you should be good.


Seems that the code should simply be made more robust. Probably a just a 
few lines of code to change/add at most. Maybe the constructor and 
parallel should take an argument to set the "totalCPUs" which defaults 
to getting the total number rather than it being hard coded.


I currently don't need or have 32+ downlaods to test ATM so...


    this() @trusted
     {
     this(totalCPUs - 1);
     }

     /**
     Allows for custom number of worker threads.
     */
     this(size_t nWorkers) @trusted
     {


Basically everything is hard coded to use totalCPU's and that is the 
ultimate problem. Not all tasks should use all CPU' >

What happens when we get 128 cores? or even 32k at some poin >
It shouldn't be a hard coded value, it's really that simple and where 
the problem originates because someone didn't think ahead.

You have the option to not use the default value.

Kind regards,
Christian



Re: parallel threads stalls until all thread batches are finished.

2023-08-28 Thread Christian Köstlin via Digitalmars-d-learn

On 26.08.23 05:39, j...@bloow.edu wrote:

On Friday, 25 August 2023 at 21:31:37 UTC, Ali Çehreli wrote:

On 8/25/23 14:27, j...@bloow.edu wrote:

> "A work unit is a set of consecutive elements of range to be
processed
> by a worker thread between communication with any other
thread. The
> number of elements processed per work unit is controlled by
the
> workUnitSize parameter. "
>
> So the question is how to rebalance these work units?

Ok, your question brings me back from summer hibernation. :)

This is what I do:

- Sort the tasks in decreasing time order; the ones that will take the 
most time should go first.


- Use a work unit size of 1.

The longest running task will start first. You can't get better than 
that. When I print some progress reporting, I see that most of the 
time N-1 tasks have finished and we are waiting for that one longest 
running task.


Ali
"back to sleep"



I do not know the amount of time they will run. They are files that are 
being downloaded and I neither know the file size nor the download 
rate(in fact, the actual download happens externally).


While I could use work unit of size 1 then problem then is I would be 
downloading N files at once and that will cause other problems if N is 
large(and sometimes it is).


There should be a "work unit size" and a "max simultaneous workers". 
Then I could set the work unit size to 1 and say the max simultaneous 
workers to 8 to get 8 simultaneous downloads without stalling.


I think thats what is implemented atm ...
`taskPool` creates a `TaskPool` of size `defaultPoolThreads` (defaulting 
to totalCPUs - 1). The work unit size is only there to optimize for 
small workloads where task / thread switching would be a big performance 
problem (I guess). So in your case a work unit size of 1 should be good.


Did you try this already?

Kind regards,
Christian




Re: Giant template - changing types everywhere

2023-07-14 Thread Christian Köstlin via Digitalmars-d-learn

On 14.07.23 18:51, Steven Schveighoffer wrote:

On 7/14/23 12:40 PM, Christian Köstlin wrote:



Would Eponymous Templates 
(https://dlang.org/spec/template.html#implicit_template_properties) 
work with the wrapping template?


Only if all the functions are named the same as the template. With 
eponymous templates, you no longer get access to any of the members of 
the template aside from the eponymous member(s).


-Steve

I see ... thanks for the explanation!!!

Kind regards,
Christian



Re: Giant template - changing types everywhere

2023-07-14 Thread Christian Köstlin via Digitalmars-d-learn

On 14.07.23 16:15, Steven Schveighoffer wrote:

On 7/14/23 1:51 AM, Cecil Ward wrote:

On Friday, 14 July 2023 at 05:09:58 UTC, Cecil Ward wrote:

On Friday, 14 July 2023 at 05:05:27 UTC, Cecil Ward wrote:

On Friday, 14 July 2023 at 05:03:31 UTC, Cecil Ward wrote:


The way I can see it going is a giant template encompassing pretty 
much the whole file. Does that mean that the caller who calls my 
one public function does so by passing the type dchar or wchar ? 
And then we generate the strings from that. It might be rather more 
natural for the caller to pass one of the string types into the 
template. That’s where I get rather more confused, say caller calls


Transform(dstring)(dstring str)

or can they just do Transform( "str"d ) and it would work out that 
the type is immutable dchar[] ?


Perhaps I should just make up a small example file with two 
functions in it to see if I can get the syntax right?


If I wrap the whole thing with a template declaration of the xchar 
type, then can I get away with no changes to the individual function 
definitions?


I tried it, wrapped the whole thing in a template definition and it 
compiled, but then my test file which calls Transform( someDString ) 
failed to compile with errors saying it couldn’t find the definition 
of Transform in the other module, which is or was public. It’s as if 
it is no longer public because it’s now inside the template.


So templates don't automatically instantiate, you have to specify them. 
And then if your function is inside the template, to access it, you will 
need to do:


```d
GiantTemplate!dstring.Transform(str);
```

But this is not a usual way of creating API. Instead, you should 
template individual functions on the string type.


Depending on what you are doing, you can use:

```d
T Transform(T)(T val)
T[] Transform(T)(T[] val)
```

The first will cover cases where you have custom string types that 
aren't arrays, the second will just capture the array type, and ensures 
that the parameter/return is an array.


When you make template functions like this, a feature of D called 
Implicit Function Template Instantiation (IFTI) will automatically 
instantiate the template for you, so you don't have to specify the 
template parameters.


You just call `Transform(str)` and it works. With the wrapping template 
solution, this is not available -- you must explicitly instantiate the 
wrapper.


If you are having problems, it is nearly impossible to diagnose without 
some actual code to look at.


-Steve
Would Eponymous Templates 
(https://dlang.org/spec/template.html#implicit_template_properties) work 
with the wrapping template?


Kind regards,
Christian



Re: Mixin and compile-time functions for code generation

2023-06-30 Thread Christian Köstlin via Digitalmars-d-learn

On 24.06.23 18:31, Cecil Ward wrote:
I have a function that can be run at compile-time and which will be able 
to output code to be injected into the D source code stream. Can I get 
mixin whatever to do this for me? Mixin with a function that runs at 
compile-time and creates the required source ? Like D’s solution for a 
replacement for function-style C preprocessor macros ? - but far more 
advanced and capable ?


I need to re-read Ali Çehreli’s excellent book for the third time.

Is this what you want todo:

```d
import std.string : format, capitalize;
import std.stdio : writeln;

string getter(string v)
{
return "auto get%s() { return %s; }".format(v.capitalize, v);
}

class T
{
int abc;
mixin(getter("abc"));
}

void main() {
auto t = new T();
writeln(t.getAbc());
}
```



Re: serve-d and emacs

2023-04-20 Thread Christian Köstlin via Digitalmars-d-learn
I tried to reproduce my old eglot experiment, and for me serve-d was not 
even compiling with the newest dmd. Which versions are you using?


Kind regards,
Christian


How do you work with unittest libraries in dub packages?

2023-04-04 Thread Christian Köstlin via Digitalmars-d-learn

Recently Dmytro Katyukha brought up an issue in one of my dub packages
that is supposed to be used as a library. He even went the whole way and
came up with a simple reduced example: 
https://gitlab.com/gizmomogwai/colored/-/merge_requests/3#note_1341026928.


The problem here is, that my dub package uses unit_threaded in the
unittest configuration, and only imports unit_threaded in a `version 
(unittest)` block. Previously I imported unit_threaded only in the 
individual testfunctions themselves, but I thought to reduce some typing.


When my library is now used in another project (that does not depend on 
unit_threaded) `dub test` seems to still compile my library with the 
unittest version, but it would not run the unittests of my library. So 
in the end `dub test` fails for the dependent project (as it is not 
providing unit_threaded).


Is this behavior expected?
What would be best practice to work around that?

Kind regards,
Christian


How to work with phobos github projects

2023-03-10 Thread Christian Köstlin via Digitalmars-d-learn
Recently I was looking in contributing to dlang/phobos and found the 
github subprojects for phobos 
(https://github.com/dlang/phobos/projects?type=classic)
which include a project to improve the public examples for phobos 
(https://github.com/dlang/phobos/projects/1).


I looked at one of the cards there 
(https://github.com/dlang/phobos/projects/1#card-7028566) which wants to 
improve std.container.array's public examples.
Looking at the source and the dscanner results for std/container/array.d 
it is visible, that the modules' example already contain the examples, 
that dscanner is missing.
So one way would be to move the examples to the place that dscanner 
expects or come perhaps up with new examples. Anyways the solution to 
that is not really clear, and I would like to discuss with someone who 
is more familiar with phobos what todo (perhaps even just drop

the issue in github).

Normally one can comment on github issues, but I found no such mechanism 
for those projcts/cards. So how would one move forward there?


Kind regards,
Christian


Re: Simplest way to convert an array into a set

2023-02-13 Thread Christian Köstlin via Digitalmars-d-learn

On 13.02.23 19:04, Matt wrote:
Obviously, there is no "set" object in D, but I was wondering what the 
quickest way to remove duplicates from an array would be. I was 
convinced I'd seen a "unique" method somewhere, but I've looked through 
the documentation for std.array, std.algorithm AND std.range, and I've 
either missed it, or my memory is playing tricks on me. That, or I'm 
looking in the wrong place entirely, of course
You are looking probably for 
https://dlang.org/library/std/algorithm/iteration/uniq.html.



Kind regards,
Christian



Re: Need some technical help an object oriented wrapper I am creating for bindbc.sfml

2023-01-23 Thread Christian Köstlin via Digitalmars-d-learn

On 24.01.23 04:59, thebluepandabear wrote:

Regards,
thebluepandabear


Btw I understand this question is extremely complex, don't want to 
pressure anyone to help me because of that... but any sort of assistance 
or leads would be greatly... greatly apprecaited...
I do not know anything about sfml, but could you try a simpler shape, 
e.g. circle (that is a primitive on the native side). perhaps the 
winding order of your vertices is wrong?


Kind regards,
Christian



Re: Coding Challenges - Dlang or Generic

2023-01-12 Thread Christian Köstlin via Digitalmars-d-learn

On 10.01.23 23:30, Paul wrote:

On Tuesday, 10 January 2023 at 01:31:28 UTC, Ali Çehreli wrote:

On 1/9/23 16:17, Paul wrote:

> coding challenges

Perhaps the following two?

  https://rosettacode.org/

  https://adventofcode.com/

Ali


Excellent.  Thanks.

For this years advent-of-code Steven Schveighoffer (https://github.com
/schveiguy/adventofcode/tree/master/2022) has a complete set of dlang
solutions.

Kind regards,
Christian



Re: Coding Challenges - Dlang or Generic

2023-01-12 Thread Christian Köstlin via Digitalmars-d-learn

On 10.01.23 23:22, monkyyy wrote:

On Tuesday, 10 January 2023 at 19:10:09 UTC, Christian Köstlin wrote:

On 10.01.23 01:17, Paul wrote:
There is also https://exercism.org/tracks/d with some tasks for dlang.

Kind regards,
Christian


Its all converted code; worthless

I was not aware, that the question was searching for solutions in dlang.
At least exorcism gives a skeleton for a dlang project (including
unittest) to solve the task.

Kind regards,
Christian



Re: Coding Challenges - Dlang or Generic

2023-01-10 Thread Christian Köstlin via Digitalmars-d-learn

On 10.01.23 01:17, Paul wrote:
There is also https://exercism.org/tracks/d with some tasks for dlang.

Kind regards,
Christian



Advent of Code 2022

2022-12-10 Thread Christian Köstlin via Digitalmars-d-learn

Is anybody participating with dlang in the advent of code 22?
It would be interesting to discuss dlang specific things from the puzzles.

Kind regards,
Christian


Re: Gotcha with photos' documentation

2022-12-09 Thread Christian Köstlin via Digitalmars-d-learn

On 09.12.22 19:55, H. S. Teoh wrote:

On Fri, Dec 09, 2022 at 12:51:27PM +0100, Christian Köstlin via 
Digitalmars-d-learn wrote:

On 09.12.22 02:27, H. S. Teoh wrote:

[...]

https://github.com/dlang/phobos/pull/8646

[...]

Thanks a lot ...
that was fast.


It only took a minute to fix. :-D



Is there also an implementation that works on non sorted ranges?

[...]

Not as far as I know, because on a non-sorted range you'd have a much
higher time/space complexity.  You could sort the range first, but
that's O(n log n) time and possibly O(n) space if you want to preserve
the original range.

Alternatively, you could use an AA to keep track of items already seen,
but that's also O(n) space in the worst case.  Ostensibly it'd be O(n)
time as well, but that depends on your data set (some pathological cases
may trigger poorer AA performance). It will also trigger GC allocations.
Something along these lines:

auto noDuplicates(R)(R range)
if (isInputRange!R)
{
bool[ElementType!R] aa;
return range.filter!((e) {
if (e in aa)
return false;
aa[e] = true;
return true;
});
}


T

Thanks for the sketch ... sure ... for pathological cases all hope is 
lost :).


Kind regards,
Christian


Re: Gotcha with photos' documentation

2022-12-09 Thread Christian Köstlin via Digitalmars-d-learn

On 09.12.22 02:27, H. S. Teoh wrote:

On Thu, Dec 08, 2022 at 05:21:52PM -0800, H. S. Teoh via Digitalmars-d-learn 
wrote:
[...]

I'll see if I can reword this to be more explicit.

[...]

https://github.com/dlang/phobos/pull/8646


T


Thanks a lot ...
that was fast.

Is there also an implementation that works on non sorted ranges?


Kind regards,
Christian



Gotcha with photos' documentation

2022-12-08 Thread Christian Köstlin via Digitalmars-d-learn

Recently I stumbled upon a small issue in dlang's docs.
I wanted to look up uniq in std.algorithm. Started from 
https://dlang.org/phobos/std_algorithm.html and clicked uniq, no

problem, all good. But my code did not work. After some debugging
I saw, that for some inputs uniq just did not work. I clicked around
some more in the online docs and finally arrived at https://dlang.org
/phobos/std_algorithm_iteration.html which also lists uniq at the
beginning of the page and mentions (only there) that the input needs to
be sorted.
With that all was back to good :)

Would it make sense to mention this prerequisite also at the main 
documentation of uniq 
(https://dlang.org/phobos/std_algorithm_iteration.html#uniq)


Kind regards,
Christian


Is it just me, or does vibe.d's api doc look strange?

2022-12-02 Thread Christian Köstlin via Digitalmars-d-learn
Please see this screenshot: https://imgur.com/Ez9TcqD of my browser 
(firefox or chrome) of https://vibed.org/api/vibe.web.auth/


Kind regards,
Christian


Re: Makefiles and dub

2022-11-05 Thread Christian Köstlin via Digitalmars-d-learn

On 05.11.22 12:38, rikki cattermole wrote:

We have a few build formats that dub can generate for you automatically:

```
visuald - VisualD project files
sublimetext - SublimeText project file
cmake - CMake build scripts
build - Builds the package directly
```

Unfortunately none of them are make, it would be nice to have that if 
you are looking to contribute!

If cmake works, then cmake could generate a normal makefile :)

Kind regards,
Christian



Re: Make IN Dlang

2022-11-02 Thread Christian Köstlin via Digitalmars-d-learn

On 02.11.22 17:24, Kagamin wrote:
Another idea is to separate the script and interpreter then compile them 
together.

```
--- interp.d ---
import script;
import ...more stuff
...boilerplate code
int main()
{
   interpret(script.All);
   return 0;
}

--- script.d ---
#! ?
module script;
import mind;

auto All=Task(...);
...more declarative tasks

--- run ---
dmd /usr/local/interp.d /path/to/script.d
```

Thanks, have to think a little about that :)

Kind regards,
Christian



Re: Make IN Dlang

2022-11-02 Thread Christian Köstlin via Digitalmars-d-learn

On 02.11.22 20:16, H. S. Teoh wrote:

On Wed, Nov 02, 2022 at 03:08:36PM +, JN via Digitalmars-d-learn wrote:

On Tuesday, 1 November 2022 at 23:40:22 UTC, Christian Köstlin wrote:

  sh("touch %s".format(t.name));


One of the problems of many Make-like tools is that they offer lots of
freedom, especially when allowing you to launch arbitrary shell
commands. But this also comes with drawbacks, because this touch
command will instantly break Windows builds, might also be a problem
on some non-Linux platforms like macOS. Declarative approach from
tools like dub might be restrictive, but it also lets me as a user
know that I can download an arbitrary dub project and 99% chance it
will just compile out of the box on Windows.


IMO, the ideal situation is a hybrid situation: the underlying build
mechanism should be purely declarative, because otherwise the complexity
just goes out of control and you end up with non-portability,
non-reproducible builds, intractibility of static analysis (e.g., for an
external tool to understand what the build does).  However, quite often
in a large project you need to perform some complex tasks, and doing
this declaratively can be too cumbersome.  So what you want is a
procedural element to the build description that *generates* the
underlying declarative elements of the build.  The procedural part does
not perform any build actions; its job is to generate the declarative
build description.  The actual build is carried out based on this
declarative build description.


T

Thats an interesting approach. Reggae goes a little bit in that 
direction, right?


Kind regards,
Christian



Re: Make IN Dlang

2022-11-02 Thread Christian Köstlin via Digitalmars-d-learn

On 02.11.22 04:07, rikki cattermole wrote:

Something to consider:

dub can be used as a library.

You can add your own logic in main to allow using your build 
specification to generate a dub file (either in memory or in file system).

Nice ... I will perhaps give that a try!

Kind regards,
Christian



Re: Make IN Dlang

2022-11-02 Thread Christian Köstlin via Digitalmars-d-learn

On 02.11.22 03:25, Tejas wrote:

On Tuesday, 1 November 2022 at 23:40:22 UTC, Christian Köstlin wrote:

Dear dlang-folk,

one of the tools I always return to is rake 
(https://ruby.github.io/rake/). For those that do not know it, its a 
little like make in the

sense that you describe your build as a graph of tasks with dependencies
between them, but in contrast to make the definition is written in
a normal programming language (in this case ruby) with all features of
it.

[...]


Sounds pretty similar to [tup](https://gittup.org/tup/)
I am a great admirer of tup (especially because they incorporated as the 
first system (that I know of) a filesystem monitor outside of IDEs).

Its language is make like I would say, for that I do not like it that much.

Reggae, the build system mentioned by Adam, supports tup as a backend, 
so you could use that as well

+1

Kind regards,
Christian



Re: Make IN Dlang

2022-11-02 Thread Christian Köstlin via Digitalmars-d-learn

On 02.11.22 00:51, Adam D Ruppe wrote:
I don't have specific answers to your questions but your goal sounds 
similar to Atila's reggae project so it might be good for you to take a 
look at:


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

Hi Adam,

thanks for the pointer. I forgot about reggae ;-)
From the documentation it looks more high level and already defines
things like libraries and so on. It's also very ambitious in that it
tries to support different backends!

Mind is more low level (although some language specific things could be
added on top of it.

I like reggaes approach in reading in the "source" and creating 
something new from it (perhaps with dub as library) this could get rid 
of some of the boilerplate of what I have now.


Kind regards,
Christian



Make IN Dlang

2022-11-01 Thread Christian Köstlin via Digitalmars-d-learn

Dear dlang-folk,

one of the tools I always return to is rake 
(https://ruby.github.io/rake/). For those that do not know it, its a 
little like make in the

sense that you describe your build as a graph of tasks with dependencies
between them, but in contrast to make the definition is written in
a normal programming language (in this case ruby) with all features of
it.

Dlang is also quite expressive, so I thought why not define the build in 
Dlang.


The result is mind (https://gitlab.com/gizmomogwai/mind). An example 
mindfile looks like this:

```
#!/usr/bin/env dub
/+ dub.sdl:
   name "mindfile"
   dependency "mind" version="~master"
   ...further dependencies...
 +/
import mind;
import std.stdio : writeln;
import std.format : format;
import std.range : iota;
import std.algorithm : map;
import std.array : array;
import core.thread.osthread : Thread;
import core.time : msecs;

int main(string[] args)
{
description("Do all");
auto all = task("all", null, (t) {});

for (int i=0; i<1000; ++i)
{
auto fileName = "out/file-%s.txt".format(i);
all.enhance(fileName);
description(fileName);
file(fileName, null, (t)
 {
 Thread.sleep(100.msecs);
 sh("touch %s".format(t.name));
 },
);
}

return mindMain(args);
}

```

This uses dub's single file feature
(https://dub.pm/advanced_usage#single-file) to get the helper library
and "execution engine" (mind).

The main functions defines a bunch of tasks or file-tasks and finally
forwards to the main function of the library for parallel (if possible)
execution of the tasks.

At the moment this is still in an experimental stage, but has nice
features such as:
- colorized --help (thanks to argparse)
- --tasks to show all defined (and commented tasks)
- parallel execution


I am still trying to find answers to the following questions:
1. Is it somehow possible to get rid of the dub single file scheme, and
   e.g. interpret a full dlang script at runtime?
2. How can the program as is made nicer/shorter? (one could just import
   std, or make use of https://code.dlang.org/packages/scriptlike)?
3. Does this make sense at all, or should we just use make/rake? (dub
   also uses a custom build.d file).


Kind regards,
Christian


Re: rotate left an array

2022-10-04 Thread Christian Köstlin via Digitalmars-d-learn
If you are ok with using things from std.range you could use something 
like this:



```d
import std.range : cycle, drop, take;
import std.stdio : writeln;

int main(string[] args)
{
auto r = [1, 2, 3, 4, 5, 6, 7, 8];
writeln(r.cycle.drop(3).take(r.length));
return 0;
}
```

Kind regards,
Christian




Re: Is there a way to mark a dub package as linux only?

2022-09-27 Thread Christian Köstlin via Digitalmars-d-learn

On 27.09.22 13:07, Ahmet Sait wrote:

On Monday, 26 September 2022 at 20:57:06 UTC, Christian Köstlin wrote:

Or posix only? Or not windows?

Kind regards,
Christian


Not necessarily a dub solution but you can do something like this:
```d
version(Posix) { }
else
     static assert(0, "Unsupported platform.");
```
This will result in a compiler error while targetting a non-posix platform.
Thanks a lot ... but thats a little late for me :) as someone already 
might have added my library and was looking forward on using it.




Is there a way to mark a dub package as linux only?

2022-09-26 Thread Christian Köstlin via Digitalmars-d-learn

Or posix only? Or not windows?

Kind regards,
Christian




Anaphoric "macros"

2022-09-24 Thread Christian Köstlin via Digitalmars-d-learn

Hi,

I just stumbled upon anaphoric macros 
(https://en.wikipedia.org/wiki/Anaphoric_macro) in elisp. Seems that the 
dlang feature e.g. `map!"a*2"` is something similar to that, although I 
never read about it phrased like that before.


Kind regards,
Christian




Re: Setting import paths - project (dub) and also rdmd or dmd

2022-09-19 Thread Christian Köstlin via Digitalmars-d-learn

On 19.09.22 16:24, David wrote:

Hi,

New to D (and enjoying the learning..) I've probably missed something 
obvious but I'm slightly confused with the best way to achieve a simple 
build.


I like to keep my reusable modules in a directory outside of the project 
directory so I can use them on another project for example.


I do :-

import externalmodulename;

rdmd app.d and get a fail.

No problems, I can run rdmd thus :-

rdmd -I../EXTERNALMODULES app.d

and it all compiles nicely.

Same goes for dmd just use dmd -I and it compiles the code clean.

I'd normally just have a CPPFLAGS=... line in a classic Makefile to do 
this for me but can't see a native D way of doing it.  I looked at dub 
and that that :-


dub add-path ../EXTERNALMODULES

would do the trick but it doesn't make a difference (the path is added 
to the relevant json file in ~/.dub), I also tried add-local but no 
difference.  I was expecting it to add something to dub.sdl but that 
hasn't changed since I created the project.


TLDR: How do I automatically specify the -I to the compilers so I don't 
need to specify it manually each time ?



Regards,


D
Another option that goes completely around the -I issue is if you make 
your module into a full dub package and add this with dub add-local. 
Then it becomes available as a regular dub dependency, which can be used 
in dub builds as well as in rdmd builds (see 
https://dub.pm/advanced_usage#single-file). Not sure how to solve the 
dmd thing though, besides what Steven proposed.


Kind regards,
Christian




Re: dub lint

2022-09-16 Thread Christian Köstlin via Digitalmars-d-learn

On 16.09.22 02:23, rikki cattermole wrote:


https://github.com/dlang/dub/issues/2483
Also the double --config option is already in a bugreport (quite old), 
but not fixed as far as i can see:

https://github.com/dlang/dub/issues/1940

Kind regards,
Christian




Re: dub lint

2022-09-15 Thread Christian Köstlin via Digitalmars-d-learn

On 16.09.22 01:14, Christian Köstlin wrote:

On 16.09.22 00:14, Ali Çehreli wrote:

On 9/15/22 15:04, Ali Çehreli wrote:

 > Is there a way to silence specific 'dub lint' warnings?

Answering myself, I don't think it's possible but luckily my catching 
an Error was in unittests only so I can do either of the following to 
skip unittest code when linting:


a) Pass --skipTests to dscanner (what 'dub lint' runs behind the 
scenes) along with --styleCheck, which --skipTests requires


   dub lint -- --skipTests --styleCheck

b) Pass --styleCheck indirectly through 'dub lint', which has its own 
spelling for it :), but --skipTests is still required of course:


   dub lint --style-check -- --skipTests

Ali

There is `dub run dscanner -- --defaultConfig` which creates a default 
config in `~/.config/dscanner/dscanner.ini` (for linux and osx). There 
one can disable only the checks for bad exception handling

```
; Check for poor exception handling practices
exception_check="disabled"
```
and then its possible to move this file e.g. to the project folder and 
use in with `dub lint --config=dscanner.ini` ...

interestingly `dub lint --help` shows two different options for `--config`:

```
dub lint --help
USAGE: dub lint [[@]] [] [-- 
]

..
..
   --config=VALUE    Use the given configuration file.
..
..
   -c  --config=VALUE    Builds the specified configuration.
..
..

```

Kind regards,
Christian
p.s. phobos for example includes its own dscanner.ini file in 
https://github.com/dlang/phobos/blob/master/.dscanner.ini







Re: dub lint

2022-09-15 Thread Christian Köstlin via Digitalmars-d-learn

On 16.09.22 00:14, Ali Çehreli wrote:

On 9/15/22 15:04, Ali Çehreli wrote:

 > Is there a way to silence specific 'dub lint' warnings?

Answering myself, I don't think it's possible but luckily my catching an 
Error was in unittests only so I can do either of the following to skip 
unittest code when linting:


a) Pass --skipTests to dscanner (what 'dub lint' runs behind the scenes) 
along with --styleCheck, which --skipTests requires


   dub lint -- --skipTests --styleCheck

b) Pass --styleCheck indirectly through 'dub lint', which has its own 
spelling for it :), but --skipTests is still required of course:


   dub lint --style-check -- --skipTests

Ali

There is `dub run dscanner -- --defaultConfig` which creates a default 
config in `~/.config/dscanner/dscanner.ini` (for linux and osx). There 
one can disable only the checks for bad exception handling

```
; Check for poor exception handling practices
exception_check="disabled"
```
and then its possible to move this file e.g. to the project folder and 
use in with `dub lint --config=dscanner.ini` ...

interestingly `dub lint --help` shows two different options for `--config`:

```
dub lint --help
USAGE: dub lint [[@]] [] [-- 
]

..
..
  --config=VALUEUse the given configuration file.
..
..
  -c  --config=VALUEBuilds the specified configuration.
..
..

```

Kind regards,
Christian




Re: How check if destructor has been called?

2022-09-13 Thread Christian Köstlin via Digitalmars-d-learn

On 13.09.22 19:13, Ben Jones wrote:

On Tuesday, 13 September 2022 at 14:06:42 UTC, Injeckt wrote:
Hi, I'm trying to check if destructor has been called, but when I'm 
deleting class object I didn't get any calls from destructor.


myclass.d

    ~this() {
    this.log("\nDestructor\n");
    this._free_trash();
    }


main.d

    try {
    server.server_init(server);
    } catch (Exception e) {
    server.log(e.msg);
    server = null;
    }


Classes are allocated on the GC heap, so even though you're setting the 
reference to null, it's not being collected at that point.  You can use 
`destroy` to make sure the destructor is called (see here: 
https://dlang.org/spec/class.html#destructors)


Or you could make your instance `scope` and then it basically follows 
the same lifetime rules as `struct`s.
Some more things to watch out are mentioned in 
https://p0nce.github.io/d-idioms/#The-trouble-with-class-destructors.


In one of my programs I had problems with allocating in GC called 
destructors (by doing "harmless" writeln debugging).


Kind regards,
Christian




How do you work with lst files?

2022-08-24 Thread Christian Köstlin via Digitalmars-d-learn
I want to ask around how you from the dlang community work with .lst 
coverage files?
For me those files are really one of the best formats as they are 
(really, in contrast to some xml things) human readable and someone 
added them to codecov.


My setup at the moment consists of a small tool that I can plug into 
postRunCommands (e.g. of the unittest dub configuration) and that 
converts those files to "normal" dmd style warnings, so that my editor 
(in my case emacs, but the same works with the vs code plugin) can pick 
them up.


looking forward to learn about your setup!

Kind regards,
Christian





Re: Recommendation for parallelism with nested for loops?

2022-08-20 Thread Christian Köstlin via Digitalmars-d-learn

On 20.08.22 12:28, Christian Köstlin wrote:

On 19.08.22 03:49, Shriramana Sharma wrote:
Hello. I want to parallelize a computation which has two for loops, 
one nested within another. All inner-loop-param+outer-loop-param 
combinations can be computed independent of one another.


As I suspected, 
[https://forum.dlang.org/post/xysyidbkjdinclmrx...@forum.dlang.org](this forum post) says that only one loop can be parallelized. Will it be an error or inefficient or useless if I try to do both?


Also, what is the best way to do parallelism in such a situation?
You could also do a custom range that makes a one-dimensional range (aka 
iota out of your nested loops) and then process this with parallel.
Another way (more similar to Ali's solution) would be to write the 
nested loops as you have them, but collect the parameters for the work 
in an array or something and then process this array in parallel.


Kind regards,
Christian


Actually phobos brings already all that is required (especially the 
cartesian product):


```d
import std;

void doSomething(int i, string s)
{
writeln("%s-%s".format(i, s));
}

void main()
{
foreach (t; cartesianProduct(iota(1, 4), ["abc", "def", 
"ghi"]).parallel) {

doSomething(t.expand);
}
}
```

kind regards,
Christian



Re: Recommendation for parallelism with nested for loops?

2022-08-20 Thread Christian Köstlin via Digitalmars-d-learn

On 19.08.22 03:49, Shriramana Sharma wrote:
Hello. I want to parallelize a computation which has two for loops, one 
nested within another. All inner-loop-param+outer-loop-param 
combinations can be computed independent of one another.


As I suspected, 
[https://forum.dlang.org/post/xysyidbkjdinclmrx...@forum.dlang.org](this 
forum post) says that only one loop can be parallelized. Will it be an 
error or inefficient or useless if I try to do both?


Also, what is the best way to do parallelism in such a situation?
You could also do a custom range that makes a one-dimensional range (aka 
iota out of your nested loops) and then process this with parallel.
Another way (more similar to Ali's solution) would be to write the 
nested loops as you have them, but collect the parameters for the work 
in an array or something and then process this array in parallel.


Kind regards,
Christian




Re: How to use exceptions

2022-08-13 Thread Christian Köstlin via Digitalmars-d-learn

On 13.08.22 17:00, kdevel wrote:
"Exception enrichment" would be my wording which is supported by google 
[1].
There is also the notion of "exception context" [2] and "contexted 
exception" [3].

Thats really a good word! Especially it describes better what the java
guys are doing by adding information to an existing object and
rethrowing, without creating a new exception, covering the tracks of the
original exception by wrapping it and throwing this.
Can we have that for dlang exceptions as well (I mean as additional api
in the baseclass)? It would not break old code, as it would be
additional api?

The current filename imposes a context on its processing. The exception 
thrown from readText knows that filename and propagates it within the 
exception msg. Unfortunately exceptions are frequently only "stringly 
typed", e.g.

yes .. thats a shame. I think it is, because its much shorter than
defining a new member, a new constructor, a new message method in the
new exception subclass.



394: throw new JSONException("JSONValue is not a number type");
406: throw new JSONException("JSONValue is not a an integral type");

This should have been made into an exception hierarchy with the faulty 
value beeing a data member of the respective class. That would nicely 
support the crafting of a message for the user in the presentation layer.

I do agree.

Of course the UTF8Exception must be enriched with the filename in the 
application code.

I do not agree. As for me it looks like `readText` works with kind of
two API's internally. One is the file API that can throw, and forwards
information nicely (about which file has the problem). And then some
UTF-8 processing based on data from that file (which should also forward
the information of the file, as the end user of this API did not even
touch a file at all (only a string representing a filename)).
But for sure there are different scenarios where the enrichment needs to
happen at call site.

3. localization is a fantastic example of data that needs to be added 
to almost every exception that raises from below.


How would you handle a FileException.msg = "myconfig.cnf: Permission 
denied"? Run regular expressions over the msg? Something is 
fundamentally wrong if any kind of parsing of error strings is required.

Thats what I mean with "that raises from below". I think the
FileException is not supposed to be on the top of the exception stack,
but a more application level exception (e.g. Cannot process
configuration file (as Configuration file is something on application
level)).

Then there is another type of user who shall not be faced with any kind 
of specific error message: The client of a company which runs a web 
application. This case is easy to implement: Catch any Exception and 
replace it with an "The Unforeseen happend, id#" message. Leave the code 
as it is and let the stack trace go into the error_log. The devops 
people of the company probably understand english messages.

One could argue, that every exception stacktrace that comes to
stdout/-err or a user interface is already a bug. It might be helpful
for developers and system administrators, but not for end users. So your
solution is perhaps inconvinient for developers, but good in general.


[1] 
https://jenkov.com/tutorials/java-exception-handling/exception-enrichment.html


[2] 
https://docs.microsoft.com/en-us/dotnet/api/system.web.mvc.exceptioncontext?view=aspnet-mvc-5.2


[3] 
https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/exception/ContextedException.html


thanks again for the links ... nice read!!!

Kind regards,
Christian





Re: How to use exceptions

2022-08-13 Thread Christian Köstlin via Digitalmars-d-learn

On 13.08.22 15:00, kdevel wrote:

On Friday, 12 August 2022 at 21:41:25 UTC, Christian Köstlin wrote:


which would enable something like

```d
    return  s
    .readText
    .parseJSON
    .contextWithException((UTFException e) {
    return new Exception("Cannot process UTF-8 in config 
file%s\n  %s".format(s, e.msg), e);

    })
    .contextWithException((FileException e) {
    return new Exception("Cannot process config file%s\n 
%s".format(s, e.msg), e);

    });
```


This is not as DRY as it could be. Furthermore I would try implement the 
error handling completely outside the main execution path, ideally in a 
wrapper around a the old main function (renamed to main_). This approach 
becomes problematic if exceptions of the same class can be thrown from 
two functions of the chain. >

Your code is printing e.msg. How to you localize that string?
Those 3 points are exactly touching the problems (I am ignoring the DRY 
thing for now, as this is a side battle):
1. error handling in main path: exactly thats what I would like todo. 
but for that the errors that raise need to have meaningful information. 
this is exactly what I am trying in those context* functions ... they do 
not do error handling, but more something like error enhancement (by 
fixing up the error information).
2. yes ... for that the chain would need to be broken up, then you can 
react on the same exception classes of different members of the chain 
differently ... for that I do not see a nice way to write it in d.
3. localization is a fantastic example of data that needs to be added to 
almost every exception that raises from below. my example with the 
strings is just an example, it could also be that by conventions of your 
application framework all context* functions raise 
LocalizableExceptions, that somehow can then be mapped to different 
languages with their own api. the generalalized main function then would 
handle those exception classes differently from "normal" exceptions.


hope that makes sense.

kind regards,
christian





Re: How to use exceptions

2022-08-12 Thread Christian Köstlin via Digitalmars-d-learn

On 12.08.22 23:05, Christian Köstlin wrote:

On 12.08.22 01:50, H. S. Teoh wrote:

...

 >

The OP's idea of wrapping throwing code with a function that tacks on
extra information is a good idea.  Perhaps the use of strings isn't
ideal, but in principle I like his idea of exceptions acquiring
higher-level information as it propagates up the call stack.


Thanks for the kind words ... I am still thinking how to put this
into a nicer API ... as it is in my current demo, its not much to type
out so I am happy with that. Actually having read the source of
ifThrown, its amazing how lazy makes wrapping easy!

One thing that can be done is to templateize the exception handler so
that only exceptions of a certain type are handled.
```d
auto contextWithException(T, E)(lazy scope T expression, Exception 
delegate(E) handler)

{
Exception newException;
try
{
return expression();
}
catch (E e)
{
newException = handler(e);
}
throw newException;
}
```

which would enable something like

```d
return  s
.readText
.parseJSON
.contextWithException((UTFException e) {
return new Exception("Cannot process UTF-8 in config 
file%s\n  %s".format(s, e.msg), e);

})
.contextWithException((FileException e) {
return new Exception("Cannot process config file%s\n 
%s".format(s, e.msg), e);

});
```

Not sure if that makes it any better though, as I have the feeling that
most exceptions need to be wrapped at least once on their way to the end
user.

kind regards,
Christian



Run dub build with all generated files in /tmp

2022-08-12 Thread Christian Köstlin via Digitalmars-d-learn

Sometimes I do not only rely on git to transport dub projects from
computer to computer, but also on Dropbox or Syncthing or similar
tools. For that it would be great if it would be possible to do all
dub commands (e.g. build) in a way, that they are not touching the
current working directory. For `dub run` I found the option
`--temp-build` that builds to /tmp, but I did not find a similar
option for dub build.

Is there some way to have all files generated by dub out of the project 
folder?


Kind regards,
Christian




Re: How to use exceptions

2022-08-12 Thread Christian Köstlin via Digitalmars-d-learn

On 12.08.22 01:50, H. S. Teoh wrote:

...

>

The OP's idea of wrapping throwing code with a function that tacks on
extra information is a good idea.  Perhaps the use of strings isn't
ideal, but in principle I like his idea of exceptions acquiring
higher-level information as it propagates up the call stack.


Thanks for the kind words ... I am still thinking how to put this
into a nicer API ... as it is in my current demo, its not much to type
out so I am happy with that. Actually having read the source of
ifThrown, its amazing how lazy makes wrapping easy!





Re: How to use exceptions

2022-08-11 Thread Christian Köstlin via Digitalmars-d-learn

On 12.08.22 01:06, Adam D Ruppe wrote:

You might find my recent blog post interesting too:

http://dpldocs.info/this-week-in-d/Blog.Posted_2022_08_01.html#exception-template-concept

and a draft of some more concepts:
http://arsd-official.dpldocs.info/source/arsd.exception.d.html


I also find the lack of information disturbing, but I also hate 
formatting it all into strings, so I wanted to experiment with other 
options there that avoid the strings.

Yes ... I already read your blog post. In general I am with you there as
it makes sense to have either dedicated exception classes or something 
more along the lines of what you describe in your post.





How to use exceptions

2022-08-11 Thread Christian Köstlin via Digitalmars-d-learn

Dear d-lang experts,

lets say in general I am quite happy with exceptions.
Recently though I stumbled upon two problems with them:
1. Its quite simple to loose valuable information
2. Its hard to present the exception messages to end users of your
   program

Let me elaborate on those:
Lets take a simple config parser example (pseudocode, the real code is 
in the end):

```d
auto parseConfig(string filename)
{
return s
.readText
.parseJSON;
}
..
void main()
{
...
auto config = parseConfig("config.json");
run(config);
...
}
```
Lets look at what we would get in terms of error messages for the user 
of this program (besides that a full stacktrace is printed, which is 
nice for the developer of the program, but perhaps not so nice for the 
end user)

- file is not there: config.json: No such file or directory
  nice ... its almost human readable and one could guess that something
  with the config file is amiss
- file is not readable for the user: config.json: Permission denied
  nice ... quite a good explanation as well
- file with invalid UTF-8: Invalid UTF-8 sequence (at index 1)
  not so nice ... something is wrong with some UTF-8 in the program,
  but where and in which area of the program
- file with broken json: Illegal control character. (Line 4:0)
  not nice ... line of which file, illegal control character does
  not even sound like json processing.

Arguably readText could behave a little better and not throw away
information about the file its working with, but for parseJSON the
problem is "bigger" as it is only working with a string in memory not
with a file anymore, so it really needs some help of the application
developer I would say. When browsing through phobos I stumbled upon the
genius std.exception.ifThrown function, that allows for very nice
fallbacks in case of recoverable exceptions. Building on that I came up
with the idea (parhaps similar to Rusts error contexts) to use this
mechanism to wrap the exceptions in better explaining exceptions. This
would allow to provide exceptions with the information that might
otherwise be lost aswell as lift the error messages onto a end user 
consumable level (at least if only the topmost exception message is 
looked at).



```d
#!/usr/bin/env rdmd
import std;

auto contextWithString(T)(lazy scope T expression, string s)
{
try
{
return expression();
}
catch (Exception e)
{
throw new Exception("%s\n%s".format(s, e.msg));
}
assert(false);
}

auto contextWithException(T)(lazy scope T expression, Exception 
delegate(Exception) handler)

{
Exception newException;
try
{
return expression();
}
catch (Exception e)
{
newException = handler(e);
}
throw newException;
}

// plain version, no special error handling
JSONValue readConfig1(string s)
{
// dfmt off
return s
.readText
.parseJSON;
// dfmt.on
}

// wraps all exceptions with a description whats going on
JSONValue readConfig2(string s)
{
// dfmt off
return s
.readText
.parseJSON
.contextWithString("Cannot process config file %s".format(s));
// dfmt on
}

// tries to deduplicate the filename from the exception messages
// but misses on utf8 errors
JSONValue readConfig3(string s)
{
// dfmt off
auto t = s
.readText;
return t
.parseJSON
.contextWithString("Cannot process config file %s".format(s));
// dfmt on
}

// same as 3 just different api
JSONValue readConfig4(string s)
{
// dfmt off
auto t = s
.readText;
return t
.parseJSON
.contextWithException((Exception e) {
return new Exception("Cannot process config file%s\n 
%s".format(s, e.msg));

});
// dfmt on
}

void main()
{
foreach (file; [
"normal.txt",
"missing.txt",
"broken_json.txt",
"not_readable.txt",
"invalid_utf8.txt",
])
{

writeln("=");
size_t idx = 0;
foreach (kv; [
tuple("readConfig1", &readConfig1),
tuple("readConfig2", &readConfig2),
tuple("readConfig3", &readConfig3),
tuple("readConfig4", &readConfig4),
])
{
auto f = kv[1];
try
{
if (idx++ > 0) 
writeln("-");

writeln("Working on ", file, " with ", kv[0]);
f("testfiles/%s".format(file));
}
catch (Exception e)
{
writeln(e.msg);
}
}
}
}
```

What do you guys think about that?
Full dub project available at 
g...@github.com:gizmomogwai/d-exceptions.git ... If you want to play with 
it, please run ./setup-files.sh first (which will create a file that is 
not readable).


One thing I

Re: Combining JSON arrays into a single JSON array -- better way than this?

2022-08-01 Thread Christian Köstlin via Digitalmars-d-learn

On 2022-08-01 06:24, ikelaiah wrote:

Hi,

I've written a cli tool to merge JSON files (containing JSON array) in 
the current folder as a single JSON file.


My algorithm:

1. Create a string to store the output JSON array as a string,
2. read each file
3. read each object in JSON array from input file
4. append the string representation of each JSON object in a string
5. Parse the result string as JSON
6. Save string representation of point 6 above.

**Question**

While this works, is there a more concise way than this?
Thank you for your time.


```d
module combinejsonv2;

import std.file;
import std.stdio;
import std.json;
import std.array;
import std.algorithm.searching;

void main()
{
     // can't I use this for JSON array?
     JSONValue jj;

     // create a string opening [ for JSON array
     string stringResult = "[";

     foreach (string filename; dirEntries(".", "*.json", SpanMode.shallow))
     {
     // if filename contains 'output' in it, ignore
     if(canFind(filename, "output")) {
     std.stdio.writeln("ignoring: " ~ filename);
     continue;
     }

     // show status to console
     std.stdio.writeln("processing: " ~ filename);

     // read JSON file as string
     string content = std.file.readText(filename);
     // parse as JSON
     JSONValue j = parseJSON(content);

     foreach (JSONValue jsonObject; j.array) {
     // Combine objects from files into a single list of JSON 
object

     // std.stdio.writeln(jsonObject.toPrettyString);
     stringResult ~= jsonObject.toString;
     stringResult ~= ",";
     }
     }

     // create closing ] for the JSON array
     stringResult ~= "]";

     // parse the string as a JSON object
     JSONValue jsonResult = parseJSON(stringResult);

     // write to file
     std.file.write("output-combined.json", jsonResult.toPrettyString);
}

```

An arguably shorter solution (that drops some of your logging) could be:

```d
import std;

void main() {
dirEntries(".", "*.json", SpanMode.shallow)
.filter!(f => !f.name.canFind("output"))
.map!(readText)
.map!(parseJSON)
.fold!((result, json) { result ~= json.array; return result; })
.toPrettyString
.reverseArgs!(std.file.write)("output-combined.json");
}
```
not sure if you are looking for this style though.


kind regards,
Christian


How to work with coverage data

2022-07-31 Thread Christian Köstlin via Digitalmars-d-learn

Hi dlang lovers,

I recently wanted to improve how I work with coverage data (locally).

For that I came up with a small program, that can be either called after 
a `dub test --coverage` or that can be automatically executed after the 
unittest with `postRunCommands "$DUB run lst2errormessages"` in 
`dub.sdl` and that converts the generated lst files to error messages 
compatible with dmd output.


That way you can integrate them into your favorite editor, if it already 
has some dmd error output support. I use it mainly in emacs compile-mode 
or flycheck-mode (the latter with another small addition), but its also 
possible to run this in vscode + d-code.


Is there any interest in a more detailed write up of this.

Anyways, the code is available at 
https://gitlab.com/gizmomogwai/lst2errormessages


Kind regards,
Christian


Re: Fetching licensing info for all dependencies of a DUB project

2022-06-29 Thread Christian Köstlin via Digitalmars-d-learn

On 2022-06-28 14:34, Guillaume Piolat wrote:

On Monday, 27 June 2022 at 21:36:31 UTC, Christian Köstlin wrote:


I played around with the idea and came up with a small dub package, 
that is not (yet) uploaded to the dub registry.
Source is available at https://github.com/gizmomogwai/packageinfo, 
feedback very welcome.



I've done something similar not for licences but for code amount, to 
extract from a DUB project:

  - DUB packages used by project
  - source files used by project
  - and their LOC count

This is a D forums exclusive:
https://pastebin.com/RFbFCgR2

Keep your debt in check!


Interesting ... there is also dscanner that can count lines of code.
in another toy project of mine I create a dependency dot graph, might be 
good to collect all those things together ... there is also 
https://github.com/funkwerk/cogito that collect another metric of projects.


Re: Fetching licensing info for all dependencies of a DUB project

2022-06-27 Thread Christian Köstlin via Digitalmars-d-learn

On 2020-05-12 15:23, Paul Backus wrote:

On Tuesday, 12 May 2020 at 13:08:01 UTC, Joseph Rushton Wakeling wrote:

On Tuesday, 12 May 2020 at 12:59:14 UTC, Paul Backus wrote:
You should be able to get this information from the JSON output of 
`dub describe`.


Cool, thanks.  Much appreciated :-)

Has anyone created any tools to condense that into a licensing 
report?  No worries if not, just curious.


Not that I know of. If you end up making one yourself, it might be worth 
posting in the Announce forum.


Hi all,

I played around with the idea and came up with a small dub package, that 
is not (yet) uploaded to the dub registry.
Source is available at https://github.com/gizmomogwai/packageinfo, 
feedback very welcome.


Kind regards,
Christian



Re: Whats the proper way to write a Range next function

2022-06-15 Thread Christian Köstlin via Digitalmars-d-learn

On 2022-06-15 19:36, JG wrote:

On Wednesday, 15 June 2022 at 17:30:31 UTC, JG wrote:

On Wednesday, 15 June 2022 at 13:52:24 UTC, Christian Köstlin wrote:

the naive version would look like

```d
auto next(Range)(Range r) {
    r.popFront;
    return r.front;
}
```

But looking at a mature library e.g. 
https://github.com/submada/btl/blob/9cc599fd8495215d346ccd62d6e9f1f7ac140937/source/btl/vector/package.d#L229 
is looks like there should be tons of annotations/attributes on it.


Kind regards,
Christian


I not sure of your use case. But you need to check if the range is 
empty before and after calling popFront (and decide what to if it is). 
Also unless you want the original range passed in mutated you should 
call save (assuming you have a forward range) before calling your next 
or you need to modify next so it calls save.


This is what I would write for next (which should only be called after
checking if the range is empty).

It produces a range whose front points at the next element.
```d
auto next(Range)(Range r) {
   auto ret = r.save;
   ret.popFront;
   return ret;
}
```

Thanks for the explanation!
I actually want to mutate the original range and I know, that there are 
at least 2 elements in my range.


e.g. the program
```d
import std.stdio;
import std.range;

auto next(Range)(Range r) {
r.popFront;
return r.front;
}
int main(string[] args) {
auto i = iota(10);
writeln(i.next);
writeln(i.next);
return 0;
}
```
prints:
```
1
1
```

whereas
```d
import std.stdio;
import std.range;

auto next(Range)(ref Range r) {
r.popFront;
return r.front;
}
int main(string[] args) {
auto i = iota(10);
writeln(i.next);
writeln(i.next);
return 0;
}
```
prints
```
1
2
```
which is what I would want. So it depends if the Range is a value or 
reference type ...


Whats the proper way to write a Range next function

2022-06-15 Thread Christian Köstlin via Digitalmars-d-learn

the naive version would look like

```d
auto next(Range)(Range r) {
r.popFront;
return r.front;
}
```

But looking at a mature library e.g. 
https://github.com/submada/btl/blob/9cc599fd8495215d346ccd62d6e9f1f7ac140937/source/btl/vector/package.d#L229 
is looks like there should be tons of annotations/attributes on it.


Kind regards,
Christian



Re: Templatized delegates

2022-05-31 Thread Christian Köstlin via Digitalmars-d-learn

On 2022-05-31 23:15, Andrey Zherikov wrote:

I have tightly coupled code which I'd like to decouple but I'm a bit stuck.
For simplicity, I reduced the amount of code to something simple to 
understand. So I have a struct `S` that has templated member function 
that does something. On the other side I have delegate holder `R` - this 
delegate takes `S` object as an argument and calls that function. My 
goal is to remove dependency from `R` to `S`.


Here is code example:

```d
import std.stdio: writeln;

struct S
{
     // function that should be called from delegate
     void doSomething(T)(T value) { value.writeln; }
}

alias DG = void delegate (ref S s);

auto createDG(T)(T value)
{
     return delegate (ref S s) { s.doSomething(value); };
}

struct R
{
     DG dg;

     this(int value)
     {
     dg = createDG(value);
     }
}

void main()
{
     auto r = R(5);

     S s;
     r.dg(s);
}
```

An obvious way is to add a type template parameter to `R`, `DG` and 
`createDG` but I would like to avoid this. Is there another way to do so?


I think ideal solution would be having templatized delegate `void 
delegate (S)(ref S s)` and then call `r.dg!S(s)` but it's not available: 
`alias DG = void delegate (S) (ref S s)` gives unclear `Error: function 
declaration without return type. (Note that constructors are always 
named 'this')` message.Would it help to not create the delegate in R's constructor, but feed 
the delegate into it (and create the delegate outside). This would also 
resemble your description (R is a delegate holder) more.





Re: Tracing/Profiling D Applications

2022-05-31 Thread Christian Köstlin via Digitalmars-d-learn

On 2022-05-29 23:00, Ali Çehreli wrote:

On 5/29/22 13:53, Christian Köstlin wrote:

 > According to
 > 
https://www.schveiguy.com/blog/2022/05/comparing-exceptions-and-errors-in-d/ 


 > its bad to catch Errors ...

Correct in the sense that the program should not continue after catching 
Error.


 > so dowork should catch only Exception?

It should catch Error as well. Otherwise you will have no idea why a 
thread disappeared. You may agree with me here:


   https://youtu.be/dRORNQIB2wA?t=1950


Thanks a lot for this explanation!
Probably a try catch (Throwable) is a good thing to have in any thread 
that does not only use nothrows ...





I catch'ed Throwable in the code just because it's a quick little 
experiment.


 > it might be better
 > to crash directly ...

Sounds good but only after leaving the reason behind somehow.

Ali



Kind regards,
Christian


Re: Tracing/Profiling D Applications

2022-05-31 Thread Christian Köstlin via Digitalmars-d-learn

On 2022-05-29 23:08, Ali Çehreli wrote:

On 5/29/22 13:47, Christian Köstlin wrote:

 > Our discussion with using TLS for the
 > collectors proposed to not need any lock on the add method for
 > collector, because its thread local and with that thread safe?

It would be great that way but then the client changed the requirements 
on us:


On 5/26/22 12:54, Christian Köstlin wrote:
 > I want to be able to dump tracings even while the program is still 
running.


:p

If the collected data were TLS, then the dumping thread should be able 
to ask each thread to provide data collected so far. That either 
requires synchronization, which I did, which necessitated shared 
Collector objects; or messaging, which would require each thread 
checking their Concurrency message box.


I don't know...

A third option came to me: Each thread periodically puts their data to a 
common location and dumper dumps whatever is aggregated up to that 
point. This would reduce contention.
Thats also a nice idea, e.g. the collectors could aggregate their data 
and only propagate it once every second or every 10 seconds, or every 
1000 events or something! Will think about that some more!


Thanks a lot!
Christian



Re: Execute the Shell command and continue executing the algorithm

2022-05-31 Thread Christian Köstlin via Digitalmars-d-learn

On 2022-05-30 15:25, Ali Çehreli wrote:

On 5/30/22 04:18, Alexander Zhirov wrote:

 > I want to run a command in the background

The closest is spawnShell:

import std.stdio;
import std.process;
import core.thread;

void main() {
   auto pid = spawnShell(`(sleep 1 & echo SLEEP >> log)`);
   Thread.sleep(5.seconds);
   kill(pid);
   writeln("Terminated with ", wait(pid));
}

I am not good at shell scripting but I had to change your && to & to see 
anything in log.

I think this runs sleep 1 in the background and emits the echo directly.

As std.process documentation explains, the value returned by wait() (and 
more) are platform dependent.


Ali





Re: Tracing/Profiling D Applications

2022-05-29 Thread Christian Köstlin via Digitalmars-d-learn

On 2022-05-29 20:52, Ali Çehreli wrote:

On 5/27/22 06:55, Christian Köstlin wrote:

 > I wonder how I can synchronize the "dumping" and the
 > collection of the threads. Would be cool to have an efficient lockless
 > implementation of appender ...

That turned out to be nontrivial.

The following is a draft I played with. Collector collects and Dumper 
dumps. They use a SpinLock, an unpublished feature of core.internal for 
locking. The implementation of spinlock (e.g. at 
/usr/include/dlang/dmd/core/internal/spinlock.d) has a reference to 
"test and test-and-set (TTAS)":


   https://en.wikipedia.org/wiki/Test_and_test-and-set

I learned about TTAS from Rikki Cattermole yesterday at TeaConf. :)

The code is attached and works on my system.

Ali

import std;
import std.datetime.stopwatch;
import core.thread;
import core.atomic;
import core.internal.spinlock;

enum workerCount = 8;
enum threadRunTime = 4.seconds;
enum mainRunTime = threadRunTime + 1.seconds;

shared struct ScopeLock {
   @disable this(this);
   @disable void opAssign(ref const(typeof(this)));

   SpinLock * lock;

   this(shared(SpinLock) * lock) {
     this.lock = lock;
     lock.lock();
   }

   ~this() {
     lock.unlock();
   }
}

struct Collector {
   long[] data;

   shared(SpinLock) lock;

   auto scopeLock() shared {
     return ScopeLock(&lock);
   }

   // Adds a data point to this collector.
   void add(long i) shared {
     auto sl = scopeLock();

     /// Some crazy way of adding data points. Real code should
     // make more sense.
     data ~= i;
   }

   // Adds the data of this collector to the specified array
   // array. Again, real code should use a more sophisticated
   // method.
   void aggregate(ref long[] where) shared {
     auto sl = scopeLock();

     where ~= data.sum;
     data.length = 0;
     (cast(long[])data).assumeSafeAppend();
   }
}

// A variable to help us trust the code. We will print this at
// the end of main.
long allThatHasBeenDumped = 0;
// Used only for validating the code.
shared long allCollectedByThreads;

synchronized class Dumper {
private:
   shared(Collector)*[] collectors;

   void register(shared(Collector) * collector) shared {
     writeln("registering ", collector);
     collectors ~= collector;
   }

   // Dumps current results.
   void dump(File output) shared {
     long[] data;

     foreach (collector; collectors) {
   collector.aggregate(data);
     }

     const allData = data.sum;

     if (allData != 0) {
   stdout.writefln!"Just collected:%-(\n  %,s%)"(data);
   allThatHasBeenDumped += allData;
     }
   }
}

shared(Dumper) dumper;

shared static this() {
   writeln("Making a Dumper");
   dumper = new Dumper();
}

shared(Collector) * collector;

static this() {
   writeln("Making a Collector");
   collector = new shared(Collector)();
   dumper.register(cast(shared)collector);
}

// Main thread function
void doWork() {
   try {
     doWorkImpl();

   } catch (Throwable exc) {
     stderr.writeln("Caught Throwable: ", exc.msg);
   }
}

// The implementation of each thread.
void doWorkImpl() {
   auto sw = StopWatch();
   sw.start();

   long i = 0;
   while (sw.peek < threadRunTime) {
     (cast(shared)collector).add(i);
     ++i;
   }

   --i;
   auto total = i * (i + 1) / 2;
   writefln("Thread collected %,s items equaling %,s with %s",
    i, total, collector);

   atomicOp!"+="(allCollectedByThreads, total);
}

void main() {
   writeln("main started");
   iota(workerCount).each!(_ => spawn(&doWork));

   auto sw = StopWatch();
   sw.start();

   while (sw.peek < mainRunTime) {
     dumper.dump(stdout);
     Thread.sleep(100.msecs);
   }

   // One final collection (and dump):
   dumper.dump(stdout);

   assert(allThatHasBeenDumped == allCollectedByThreads);
}

According to 
https://www.schveiguy.com/blog/2022/05/comparing-exceptions-and-errors-in-d/ 
its bad to catch Errors ... so dowork should catch only Exception? Or is 
this a special case to just log the error per thread and be done with 
it? still if not everything is cleaned up correctly it might be better 
to crash directly ...


Kind regards,
Christian


Re: Tracing/Profiling D Applications

2022-05-29 Thread Christian Köstlin via Digitalmars-d-learn

On 2022-05-29 20:52, Ali Çehreli wrote:

On 5/27/22 06:55, Christian Köstlin wrote:

 > I wonder how I can synchronize the "dumping" and the
 > collection of the threads. Would be cool to have an efficient lockless
 > implementation of appender ...

That turned out to be nontrivial.

The following is a draft I played with. Collector collects and Dumper 
dumps. They use a SpinLock, an unpublished feature of core.internal for 
locking. The implementation of spinlock (e.g. at 
/usr/include/dlang/dmd/core/internal/spinlock.d) has a reference to 
"test and test-and-set (TTAS)":


   https://en.wikipedia.org/wiki/Test_and_test-and-set

I learned about TTAS from Rikki Cattermole yesterday at TeaConf. :)

The code is attached and works on my system.

Ali

import std;
import std.datetime.stopwatch;
import core.thread;
import core.atomic;
import core.internal.spinlock;

enum workerCount = 8;
enum threadRunTime = 4.seconds;
enum mainRunTime = threadRunTime + 1.seconds;

shared struct ScopeLock {
   @disable this(this);
   @disable void opAssign(ref const(typeof(this)));

   SpinLock * lock;

   this(shared(SpinLock) * lock) {
     this.lock = lock;
     lock.lock();
   }

   ~this() {
     lock.unlock();
   }
}

struct Collector {
   long[] data;

   shared(SpinLock) lock;

   auto scopeLock() shared {
     return ScopeLock(&lock);
   }

   // Adds a data point to this collector.
   void add(long i) shared {
     auto sl = scopeLock();

     /// Some crazy way of adding data points. Real code should
     // make more sense.
     data ~= i;
   }

   // Adds the data of this collector to the specified array
   // array. Again, real code should use a more sophisticated
   // method.
   void aggregate(ref long[] where) shared {
     auto sl = scopeLock();

     where ~= data.sum;
     data.length = 0;
     (cast(long[])data).assumeSafeAppend();
   }
}

// A variable to help us trust the code. We will print this at
// the end of main.
long allThatHasBeenDumped = 0;
// Used only for validating the code.
shared long allCollectedByThreads;

synchronized class Dumper {
private:
   shared(Collector)*[] collectors;

   void register(shared(Collector) * collector) shared {
     writeln("registering ", collector);
     collectors ~= collector;
   }

   // Dumps current results.
   void dump(File output) shared {
     long[] data;

     foreach (collector; collectors) {
   collector.aggregate(data);
     }

     const allData = data.sum;

     if (allData != 0) {
   stdout.writefln!"Just collected:%-(\n  %,s%)"(data);
   allThatHasBeenDumped += allData;
     }
   }
}

shared(Dumper) dumper;

shared static this() {
   writeln("Making a Dumper");
   dumper = new Dumper();
} >
shared(Collector) * collector;

static this() {
   writeln("Making a Collector");
   collector = new shared(Collector)();
   dumper.register(cast(shared)collector);
}

// Main thread function
void doWork() {
   try {
     doWorkImpl();

   } catch (Throwable exc) {
     stderr.writeln("Caught Throwable: ", exc.msg);
   }
}

// The implementation of each thread.
void doWorkImpl() {
   auto sw = StopWatch();
   sw.start();

   long i = 0;
   while (sw.peek < threadRunTime) {
     (cast(shared)collector).add(i);
     ++i;
   }

   --i;
   auto total = i * (i + 1) / 2;
   writefln("Thread collected %,s items equaling %,s with %s",
    i, total, collector);

   atomicOp!"+="(allCollectedByThreads, total);
}

void main() {
   writeln("main started");
   iota(workerCount).each!(_ => spawn(&doWork));

   auto sw = StopWatch();
   sw.start();

   while (sw.peek < mainRunTime) {
     dumper.dump(stdout);
     Thread.sleep(100.msecs);
   }

   // One final collection (and dump):
   dumper.dump(stdout);

   assert(allThatHasBeenDumped == allCollectedByThreads);
}



Hi Ali,

thanks a lot for that, I will first have to digest that.
Just one first question: Our discussion with using TLS for the 
collectors proposed to not need any lock on the add method for 
collector, because its thread local and with that thread safe?


Kind regards,
Christian


Re: Tracing/Profiling D Applications

2022-05-27 Thread Christian Köstlin via Digitalmars-d-learn

On 2022-05-26 22:19, Ali Çehreli wrote:

On 5/26/22 12:54, Christian Köstlin wrote:

 > I want to be able to dump
 > tracings even while the program is still running. Then I would have to
 > collect the tls data of all still running threads.

I am not sure without testing but I am under the impression that mutexes 
can be very slow especially if the data collection is happening very 
frequently. The threads may not have breathing room to perform their 
tasks. Since dumping would be much slower compared to the performance 
penalty of grabbing a mutex that it can be measured as zero-cost in the 
dumping time. :) So, you may still want to collect per-thread and 
combine incrementally as you dump? Perhaps a premature optimization... 
Please test. :)


You are certainly right.. It really depends on the usecase. I also think 
my current approach is not good to e.g. do syscall tracing of something 
like read. I wonder how I can synchronize the "dumping" and the 
collection of the threads. Would be cool to have an efficient lockless 
implementation of appender ...



If you want to combine before dumping, then collector registration may 
be needed so that the dumper can contact each collector and say "please 
add your data".


 > __gshared does not put
 > the shared type attribute the the profiler.

Correct.

thanks!



 > If I use shared I would also
 > have to make all methods I call on the shared profiler shared and also
 > would have to have a shared appender (or cast shared away)?

Possibly. :/

Ali





---
Christian


Re: Tracing/Profiling D Applications

2022-05-26 Thread Christian Köstlin via Digitalmars-d-learn

On 2022-05-25 23:56, Ali Çehreli wrote:

On 5/25/22 14:35, Christian Köstlin wrote:

 > 1. I went for a singleton for storing tracing/logging information that
 > needs to be initialized manually. Is __gshared the right way to do that?

I think this is where thread-local storage comes in handy. As the D 
runtime does for dmd's -profile command line switch, you can have a 
module-level Appender, which collects data for that thread without 
worrying about race conditions.
Nice idea. Similar to the fast singleton here: 
https://p0nce.github.io/d-idioms/#Leveraging-TLS-for-a-fast-thread-safe-singleton


Not sure if this will work for me though, as I want to be able to dump 
tracings even while the program is still running. Then I would have to 
collect the tls data of all still running threads.



 > to unlock the mutex?

You need the mutex only when each thread is exiting to combine their 
results. Each static ~this() could grab the mutex and add its result to 
the one global Appender. And that "global" Appender would be 'shared' or 
__gshared; doesn't matter.
Thanks for the explanation. From my understanding __gshared does not put 
the shared type attribute the the profiler. If I use shared I would also 
have to make all methods I call on the shared profiler shared and also 
would have to have a shared appender (or cast shared away)?


Kind regards,
Christian



Re: Tracing/Profiling D Applications

2022-05-26 Thread Christian Köstlin via Digitalmars-d-learn

On 2022-05-26 01:05, frame wrote:

On Wednesday, 25 May 2022 at 21:35:07 UTC, Christian Köstlin wrote:
Is there also a way to get the "real"

threadid?


I'm using that functions inside threads:

core.sys.windows.winbase.GetCurrentThreadId on Windows
core.sys.posix.pthread.pthread_self on Unix (implied pthreads are used)Thanks, 
I will give those a try!






Tracing/Profiling D Applications

2022-05-25 Thread Christian Köstlin via Digitalmars-d-learn
I experimented with application level tracing/profiling of d 
applications similar to what is described in 
https://dlang.org/blog/2020/03/13/tracing-d-applications/ as the 
"writef-based approach". Only difference is, that I am emitting json 
(https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/edit#heading=h.lpfof2aylapb) 
that is compatible with https://ui.perfetto.dev/ which gives nice 
interactive insights of the data.


The code is available at https://github.com/gizmomogwai/profiled and can 
be used as dub package by registering it locally with dub add-local. The 
github repository also contains one screenshot produced with a patched 
unit-threaded library to emit the tracing information on a small project 
of mine.



I do have a few question on how to do things in dlang though:

1. I went for a singleton for storing tracing/logging information that 
needs to be initialized manually. Is __gshared the right way to do that?


2. The data is stored in a std.array.appender protected by a mutex and 
only later printed as json. Any way to do this more elegantly than with 
the scope(exit) constructs to unlock the mutex?


3. For the tracing/profiling events I went with subclasses of an 
abstract event class (I only implemented one kind of event, whereas the 
tracing json format supports a lot more scenarios). When one is 
interested in when something happens and how long it takes, one can call
`public Unique!CompleteEventProcess start(string name)` on the profiler 
which an uniquepointer that is then automatically deleted if it goes out 
of scope (and then takes the time). Is this a reasonable way todo it? 
E.g. it would be an error if the unique ptr is passed to another thread, 
because the CompleteEvents of the tracing format expect to be starting 
and stopping on the same thread.


4. Would something like that be interesting for others as a dub package 
(ATM its so small, that having it as an external dependency is not worth 
it IMHO)?


5. The complete event normally expects the real process and thread id as 
used by the os. Looks like 
https://dlang.org/phobos/std_process.html#.Pid.processID delivers the 
process id. Is there also a way to get the "real" threadid?



Thanks in advance,
Christian


Re: Help with DynamicArray of Emsi Containers

2022-05-01 Thread Christian Köstlin via Digitalmars-d-learn

On 2022-05-01 09:12, vit wrote:

DynamicArray has disabled postblit (is not copyable).


Package autoptr is deprecated (internaly redirected to btl:atuoptr), all 
functionality is moved to package 
[BTL](https://code.dlang.org/packages/btl) (subpackage btl:autoptr). 
This library contains subpackage btl:vector with functionality like 
DynamicArray with support for copying. I use IntrusivePtr inside 
Vector/SmallVector and i have no problems.
Thanks a lot for those pointers, I changed/upgraded my dependencies, and 
it already looks better.




Help with DynamicArray of Emsi Containers

2022-04-30 Thread Christian Köstlin via Digitalmars-d-learn
I am struggling with initializing an Emsi Containers DynamicArray in a 
nice way. Some background information of my usecase:


I experimenting in porting some old 3d engine code of mine from c++ to 
dlang. In the engine I want to exactly control when resources are freed 
and not rely on the garbage collector. For that I am using reference 
counters courtesy of autoptr.


e.g.

```d

alias Texture = IntrusivePtr!TextureData; // dub package autoptr
class TextureData
{
  IFImage image; // dub package imagefmt
}

```


another class of mine now is supposed to hold several of those textures 
for multitexturing and should be initialized in its constructor:


```d
class Appearance
{
  Texture[] textures;
  this(Texture[] textures)
  {
this.textures = textures;
  }
}
```
Unfortunately this does not work properly together with autoptr's (see 
https://github.com/submada/autoptr/issues/5#issuecomment-997683868).


Because of that I am using now DynamicArrays from Emsi Containers, but I 
am having trouble initializing them:


```d
class Apperance
{
  DynamicArray!Texture textures;
  this(DynamicArray!Texture textures)
  {
this.textures = textures;
  }
}
```
does not compile.

What would be the best way to initialize the variable?

Kind regards,
Christian



Re: Offline D documentation/tutorial

2022-02-16 Thread Christian Köstlin via Digitalmars-d-learn

On 2022-02-13 01:16, LorenDB wrote:
Is there a way to download tour.dlang.org, the D spec, and/or the Phobos 
spec as an offline HTML site? I like the ability of cppreference.com to 
be saved as an offline HTML archive and I'd like to have that for D as 
well.

In addition to the already mentioned solutions there are at least two more:

1. I was pointed by Seb to https://devdocs.io/d/ which offers an offline 
mode via html5.


2. Another nice thing for dlang would be to support dash docsets 
(https://kapeli.com/dash). There is a free opensource reader for those 
as well (https://zealdocs.org/). 
https://github.com/trishume/d-phobos-docset tried to create such docsets 
with a small script, but thats not up2date.



All in all I think there are almost to many half baked solutions to the 
offline documentation problem in dlang. Perhaps this could be something 
for the steering committee.


Kind regards,
Christian


Re: std.concurrency and const

2022-01-06 Thread Christian Köstlin via Digitalmars-d-learn

On 2022-01-06 02:55, frame wrote:

On Wednesday, 5 January 2022 at 22:22:19 UTC, Christian Köstlin wrote:

Hi all,

I really like std.concurrency but I now stumbled upon the following.
When receiving messages as const, they also need to be sent as const 
(otherwise they are not matched). Comparing this to normal function 
calls I would expect a different behavior.


They do. You have an error:

`Message` doesn't match with `(Tid sender, const(Message) m)`. You don't 
get the argument `sender` here.

Duh ... you are right, my mistake!!!

Thanks!
Christian



std.concurrency and const

2022-01-05 Thread Christian Köstlin via Digitalmars-d-learn

Hi all,

I really like std.concurrency but I now stumbled upon the following.
When receiving messages as const, they also need to be sent as const 
(otherwise they are not matched). Comparing this to normal function 
calls I would expect a different behavior.



```d
import std.concurrency;
import std.stdio;

struct Message
{
}

void fun(const(Message) m) {
writeln("fun(const(Message))");
}
/*
void fun(Message m) {
writeln("fun(Message)");
}
*/
void receiver()
{
receive(
(Tid sender, const(Message) m)
{
writeln("received const(Message)");
},
(const(Variant) v)
{
writeln("Received const(Variant)", v);
},
(Variant v)
{
writeln("Received variant", v);
},
);
writeln("done");
}
int main(string[] args)
{
auto blubTid = spawnLinked(&receiver);
blubTid.send(Message());

receive(
(LinkTerminated t)
{
}
);

fun(Message());
fun(const(Message)());
return 0;
}

```

output is something like:
```
Received variantMessage()
done
fun(const(Message))
fun(const(Message))
```

whereas I would expect
```
received const(Message)
done
fun(const(Message))
fun(const(Message))
```

Looking forward for the explanation of that.


Kind regards and happy 2022!
Christian


Re: Is it possible to exchange the linker with a dub project to use mold

2021-12-22 Thread Christian Köstlin via Digitalmars-d-learn

On 2021-12-22 16:28, Paul Backus wrote:

On Wednesday, 22 December 2021 at 15:20:15 UTC, Christian Köstlin wrote:

https://github.com/rui314/mold

Kind regards,
Christian


This was recently discussed in the "General" forum:

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

Thanks for the pointer. Very interesting reads in the bugreports!

Kind regards,
Christian



Is it possible to exchange the linker with a dub project to use mold

2021-12-22 Thread Christian Köstlin via Digitalmars-d-learn

https://github.com/rui314/mold

Kind regards,
Christian


Re: Display a random image with vibe.d

2021-06-21 Thread Christian Köstlin via Digitalmars-d-learn

On 2021-06-20 17:14, vnr wrote:

On Sunday, 20 June 2021 at 14:28:26 UTC, jfondren wrote:

On Sunday, 20 June 2021 at 13:58:22 UTC, vnr wrote:


Thanks for the answers, I understand better what is going on.

So, what should I do to make my server respond with a random image, 
and not the random image page? I'm fairly new to vibe.d, so I don't 
yet know the intricacies of how to handle this style of thing and I 
couldn't find how to do it in the documentation.


Thank you.


Responding with a random image is an option, but what you have is
a good start, you just need to also serve images on request.

I'm very distracted right now or I would've included more in my
earlier post, but Vibe's online documentation has what you need.

Try, especially, https://vibed.org/docs#http-routing

You want a route for the random-image page, and you want to serve
static files under images/


Great, thanks a lot, it works as expected! Here is the code used 
(app.d), for those who are interested:


```
import vibe.vibe;

void main()
{

     auto router = new URLRouter;
     router.get("/", &index);
     router.get("*", serveStaticFiles("public"));

     auto settings = new HTTPServerSettings;
     settings.bindAddresses = ["::1", "127.0.0.1"];
     settings.port = 8080;

     auto listener = listenHTTP(settings, router);
     scope (exit) listener.stopListening();

     logInfo("Please open http://127.0.0.1:8080/ in your browser.");
     runApplication();
     }

     /// The index page
     void index(HTTPServerRequest req, HTTPServerResponse res)
     {
     import std.random;
     import std.format;

     auto rnd = Random(unpredictableSeed);
     const auto rndimg = format("/images/rndimg/img%d.jpg", 
uniform(1, 27, rnd));


     res.render!("index.dt", req, rndimg);
     }
     ```
The Random object should only be created once, but here its created for 
every request.

1. It is relatively slow to reinitialize it
2. If you really want to have uniform distribution its probably better 
to not throw the UniformRandomNumberGenerator generator away.


You can simplify that by using just uniform(1, 27) (it should fallback 
to the default rndGen that is initialized per thread 
(https://dlang.org/library/std/random/rnd_gen.html).


here a benchmark of both functions:

```
import std;
import std.datetime.stopwatch;

auto onlyUniform() {
  return uniform(1, 27);
}
auto withNewRandom() {
auto rnd = Random(unpredictableSeed);
return uniform(1, 27, rnd);
}
void main() {
  100_000.benchmark!(onlyUniform, withNewRandom).writeln;
}
```


Re: How to work around the infamous dual-context when using delegates together with std.parallelism

2021-05-31 Thread Christian Köstlin via Digitalmars-d-learn

On 2021-05-31 18:50, Christian Köstlin wrote:

On 2021-05-31 13:40, CandG wrote:

On Thursday, 27 May 2021 at 14:44:29 UTC, Steven Schveighoffer wrote:

On 5/27/21 10:13 AM, Christian Köstlin wrote:
P.S.: I still do not get how to post formatted snippets with 
thunderbird to the newsgroup/forum :/


It's not possible currently.


I no longer use thunderbird, but:
  - 
https://github.com/CyberShadow/DFeed/commit/2e60edab2aedd173c7ea3712cb9500d90d4b795d#diff-0ecfc518dcbf670fdac54985dd56663a16a0806fd57a05ac09bf40a933b851e5R338 

  - IIRC thunderbird allows changing headers: try adding 
"Content-Type" to the comma-separated list "mail.compose.other.header"
  - Then in the composition window make sure Content-Type is set to 
something like "text/plain; markup=markdown"

Thanks for the tip, lets see if it works:

```D
void main(string[] args) {
   writeln("Hello World");
}
```

Kind regards,
Christian



another try.

```D
void main(string[] args) {
   writeln("Hello World");
}
```



Re: How to work around the infamous dual-context when using delegates together with std.parallelism

2021-05-31 Thread Christian Köstlin via Digitalmars-d-learn

On 2021-05-31 13:40, CandG wrote:

On Thursday, 27 May 2021 at 14:44:29 UTC, Steven Schveighoffer wrote:

On 5/27/21 10:13 AM, Christian Köstlin wrote:
P.S.: I still do not get how to post formatted snippets with 
thunderbird to the newsgroup/forum :/


It's not possible currently.


I no longer use thunderbird, but:
  - 
https://github.com/CyberShadow/DFeed/commit/2e60edab2aedd173c7ea3712cb9500d90d4b795d#diff-0ecfc518dcbf670fdac54985dd56663a16a0806fd57a05ac09bf40a933b851e5R338 

  - IIRC thunderbird allows changing headers: try adding "Content-Type" 
to the comma-separated list "mail.compose.other.header"
  - Then in the composition window make sure Content-Type is set to 
something like "text/plain; markup=markdown"

Thanks for the tip, lets see if it works:

```D
void main(string[] args) {
  writeln("Hello World");
}
```

Kind regards,
Christian



Re: where do I find the complete phobos function list names ?

2021-05-27 Thread Christian Köstlin via Digitalmars-d-learn

On 2021-05-26 01:46, Paul Backus wrote:

On Tuesday, 25 May 2021 at 22:05:16 UTC, someone wrote:
I was unsuccessfully searching the site for them in the form of a 
master index to begin with.


I need them, in plain text, in order to add them to a VIM custom 
syntax highlight plugin I already made which I am already using but is 
lacking phobos support.


Can anyone point me to the right place please ?


There is no global index in the online documentation; the best you can 
get is an index of each module.


If you really want this, your best bet is probably to run a source-code 
indexer like `ctags` on the Phobos source tree, and do some scripting to 
transform the results into something usable in your Vim plugin.
e.g. I found this file https://dlang.org/library/symbols.js which is 
used e.g. by https://dlang.org/library/std/algorithm/sorting/sort.html 
to implement the search. Perhaps that helps.


Kind regards,
Christian



Re: How to work around the infamous dual-context when using delegates together with std.parallelism

2021-05-27 Thread Christian Köstlin via Digitalmars-d-learn

On 2021-05-27 18:56, Ali Çehreli wrote:

On 5/27/21 9:19 AM, Ali Çehreli wrote:


   auto result = new string[users.length];
   users.enumerate.parallel.each!(en => result[en.index] = 
servers.doSomething(en.value));

   writeln(result);


I still like the foreach version more:

     auto result = new string[users.length];
     foreach (i, user; users.parallel) {
   result[i] = servers.doSomething(user);
     }
     writeln(result);

Ali


Hi Ali,

both of those variants do work for me, thanks a lot!
Still not sure which I prefer (almost too many options now :) ).

I am so happy that I asked in this forum, help is much appreciated!

Christian


Re: where do I find the complete phobos function list names ?

2021-05-27 Thread Christian Köstlin via Digitalmars-d-learn

On 2021-05-26 01:46, Paul Backus wrote:

On Tuesday, 25 May 2021 at 22:05:16 UTC, someone wrote:
I was unsuccessfully searching the site for them in the form of a 
master index to begin with.


I need them, in plain text, in order to add them to a VIM custom 
syntax highlight plugin I already made which I am already using but is 
lacking phobos support.


Can anyone point me to the right place please ?


There is no global index in the online documentation; the best you can 
get is an index of each module.


If you really want this, your best bet is probably to run a source-code 
indexer like `ctags` on the Phobos source tree, and do some scripting to 
transform the results into something usable in your Vim plugin.
Where is the index for the search functionality on dlang.org located? 
Could that be used?


Kind regards,
Christian


Re: How to work around the infamous dual-context when using delegates together with std.parallelism

2021-05-27 Thread Christian Köstlin via Digitalmars-d-learn

On 2021-05-27 15:00, sighoya wrote:

On Thursday, 27 May 2021 at 12:58:28 UTC, Christian Köstlin wrote:

That looks nice, but unfortunately my data for servers and users in 
the real world is not static but comes from a config file.


Okay, but then parametrizing the static lambda with runtime parameters 
should work. The important fact is that the closure needs to be static.

Ah thanks, now I understand.
So what I came up with now is a combination of the things mentioned:

```D
import std;

string doSomething(string[] servers, string user) {
return user ~ servers[0];
}
struct UserWithServers {
string user;
string[] servers;
}
void main(string[] args) {
auto servers = args;
auto users = ["u1", "u2", "u3"];
auto usersWithServers = users.map!(user => UserWithServers(user, 
servers)).array;


static fn = function(UserWithServers user) => 
user.servers.doSomething(user.user);

writeln(taskPool.amap!(fn)(usersWithServers));
}
```

Making also the example a little bit more "realistic" by using dynamic 
data for servers.


I would like to use auto fn, but somehow saying that its a function is 
not enough for dmd. From my understanding a function would never need a 
context?!?


Thanks a lot!
Christian

P.S.: I still do not get how to post formatted snippets with thunderbird 
to the newsgroup/forum :/


Re: How to work around the infamous dual-context when using delegates together with std.parallelism

2021-05-27 Thread Christian Köstlin via Digitalmars-d-learn

On 2021-05-27 14:48, sighoya wrote:

On Thursday, 27 May 2021 at 12:17:36 UTC, Christian Köstlin wrote:
Can you explain me, where here a double context is needed? Because all 
data now should be passed as arguments to amap?


Kind regards,
Christian


I  believe D's type system isn't smart enough to see independence 
between context and closure, otherwise your original example would also 
work as users and servers are context independent.


What about:

```D
string doSomething(string[] servers, string user) {
     return user ~ servers[0];
}
void main() {
     static servers = ["s1", "s2", "s3"];
     static users = ["u1", "u2", "u3"];
     static lambda = (string user) => servers.doSomething(user);
     writeln(map!(user => servers.doSomething(user))(users));
     writeln(taskPool.amap!(lambda)(users));
}
```

That looks nice, but unfortunately my data for servers and users in the 
real world is not static but comes from a config file.


Re: How to work around the infamous dual-context when using delegates together with std.parallelism

2021-05-27 Thread Christian Köstlin via Digitalmars-d-learn

On 2021-05-27 13:11, sighoya wrote:

On Thursday, 27 May 2021 at 09:58:40 UTC, Christian Köstlin wrote:

I have this small program here

test.d:
```
import std;
string doSomething(string[] servers, string user) {
    return user ~ servers[0];
}
void main() {
    auto servers = ["s1", "s2", "s3"];
    auto users = ["u1", "u2", "u3"];
    writeln(map!(user => servers.doSomething(user))(users));
    writeln(taskPool.amap!(user => servers.doSomething(user))(users));
}
```




I think it relates to https://issues.dlang.org/show_bug.cgi?id=5710

The reason is that amap requires a this pointer of type TaskPool and a 
context pointer to the closure which belongs to main, at least because 
it requires servers. Having both isn't possible due to problems in non 
DMD compilers.


If you rewrite it more statically:
```D
string doSomething(string[] servers, string user) {
     return user ~ servers[0];
}

string closure(string user)
{
     return servers.doSomething(user);
}
auto servers = ["s1", "s2", "s3"];
int main()
{
     auto users = ["u1", "u2", "u3"];
     writeln(map!(user => servers.doSomething(user))(users));
     writeln(taskPool.amap!(closure)(users));
     return 0;
}
```

PS: Just enable markdown if you want to highlight D code
On a second not I needed to make server __gshared in my real program, as 
otherwise its a thread local variable (in the small demo program, this 
did not occur, I guess because the parallel operations we're too fast).


Kind regards,
Christian


Re: How to work around the infamous dual-context when using delegates together with std.parallelism

2021-05-27 Thread Christian Köstlin via Digitalmars-d-learn
Thanks for the proposed solution. It also works in my slightly bigger 
program (although I do not like to make servers more global).


I tried also the following (which unfortunately also does not work as 
intended):


```D
import std;
string doSomething(string[] servers, string user) {
return user ~ servers[0];
}

int main()
{
auto users = ["u1", "u2", "u3"];
auto servers = ["s1", "s2", "s3"];
auto usersWithServers = users.map!(user => tuple!("user", 
"servers")(user, servers)).array;
writeln(map!(userWithServers => 
userWithServers.servers.doSomething(userWithServers.user))(usersWithServers));
writeln(taskPool.amap!(userWithServers => 
userWithServers.servers.doSomething(userWithServers.user))(usersWithServers));

return 0;
}
```

Here I try to put the data I need together into one tuple ("manually") 
and then pass it all to amap. Can you explain me, where here a double 
context is needed? Because all data now should be passed as arguments to 
amap?


Kind regards,
Christian


  1   2   >