Re: How to load a DLL file in D?

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

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

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


Maybe I should write some automation tool...


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


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


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


Re: How to load a DLL file in D?

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

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


Maybe I should write some automation tool...


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


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

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


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


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


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


`remove`

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

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

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


So to give an example:

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

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

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

-Steve


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


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

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


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

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


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

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

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


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


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


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


Does filter do what you need?

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


Re: Recommendations on porting Python to D

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

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

is anyone aware of any tools that generate an abstract syntax 
tree which could then be converted to somewhat equivalent D 
code?  This might give me a jump-start on the manual conversion 
process.  Then later I can work on removing the CGI dependency.


I haven't used Python much in recent years, but my recollection 
is that Python 2 had an ast module that would spit out the ast 
for you.


Re: Best way to use large C library in D as of 2024

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

On Friday, 12 April 2024 at 18:36:13 UTC, Chris Piker wrote:

On Saturday, 30 March 2024 at 07:11:49 UTC, Mike Parker wrote:
Though I appreciate the sentiment, it's much more effective 
and efficient for people actually using the feature, and who 
appreciate it, to write up a blog post about it somewhere and 
share that on Twitter/Reddit/HN, etc.


I would, but I'm just not a social media person.  I pretty much 
only post online content here and at github.com.  You may have 
the problem that D doesn't attract "very-online" personality 
types.  I do mention D in work presentations, but those are not 
visible to the public.


If you put your writeup in a markdown file on your Github account 
and then post a link in the announce group, others will post it 
to the D subreddit and elsewhere I'm sure.


Re: Best way to use large C library in D as of 2024

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

On Friday, 12 April 2024 at 18:45:21 UTC, Chris Piker wrote:

Even though DMD can't compile some C code, that's pretty much a 
non-issue for me anyway.  In my environment the servers are all 
Linux so "apt-get" (or equivalent) typically provides a 
pre-compiled dependency.  Being able to list a package as a 
system dependency and then just call it from D with no 
interface code is a Big Freaking Deal!


Compared to Python interfaces this is a huge improvement.  It 
makes D an even better replacement for the mixed mode python + 
C development I was doing before switching to D for new 
projects.


I agree that it's really good, but the issues I listed were just 
examples of the things I came across, and I know there are a 
decent number of other open issues for ImportC. What I'd prefer 
to avoid is having people try it out and concluding that it's not 
ready. Kind of like when I tried out Zig. Everyone was saying 
it's this great language but my trial was brief and I haven't 
been tempted to try it since.


Header files are a different story. They really should "just 
work" based on my experience. Other things like compiling large 
libraries or translating C code to D should probably be more in 
the camp of "experience reports" posted on individual blogs, and 
they should talk about both the successes and the edge cases.


Re: Unittests pass, and then an invalid memory operation happens after?

2024-04-06 Thread Lance Bachmeier via Digitalmars-d-learn
On Wednesday, 3 April 2024 at 21:57:00 UTC, Liam McGillivray 
wrote:


Alright. I suppose that some of the optimization decisions I 
have made so far may have resulted in less readable code for 
little performance benefit. Now I'm trying to worry less about 
optimization. Everything has been very fast so far.


I haven't used a profiler yet, but I may like to try it.


A good example where you people will get fooled is to avoid 
passing structs as function arguments/return values because 
you're worried about copying:


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

I'm guilty of having done that regularly until I learned how the 
compiler actually works and how little time certain operations 
take. One time I even changed clear string arguments to 
hard-to-remember single char values inside a loop.


Re: Best way to use large C library in D as of 2024

2024-03-31 Thread Lance Bachmeier via Digitalmars-d-learn

On Saturday, 30 March 2024 at 05:01:32 UTC, harakim wrote:

On Tuesday, 26 March 2024 at 20:42:00 UTC, Chris Piker wrote:

On Tuesday, 26 March 2024 at 20:19:27 UTC, bachmeier wrote:


Should be able to just use it, as described here: 
https://forum.dlang.org/post/qxctappnigkwvaqak...@forum.dlang.org Create a .c file that includes the header files and then call the functions you need.


Wow. **That just worked the first time!**  Holy &^@$ that's 
easy!


So why does the 2nd page returned from the google search
```
interfacing with C site:dlang.org
```
(which happens to be: 
https://dlang.org/spec/interfaceToC.html) still have this text:


Since D can call C code directly, it can also call any C 
library functions,
giving D access to the smorgasbord of existing C libraries. 
To do so, however,
one needs to write a D interface (.di) file, which is a 
translation of the C .h

header file for the C library into D.

For popular C libraries, the first place to look for the 
corresponding D interface
file is the Deimos Project. If it isn't there already, please 
write and contribute

one to the Deimos Project.

?

This lead me to believe that interfacing was a chore and I was 
considering going back to C for a small program I need.


@D Language Foundation - This is a HUGE selling point. I had to 
use cups the other day and I just copied some code from a d 
file and linked the library. It was so easy I was suspicious 
but it worked. Using C from D is pretty much as easy as using C 
from C and I think you should advertise that better!


It works well if you only need to work with a header. There are 
still a few rough edges that get in the way if you're compiling 
the full C sources (I filed bugs for all of them):


- Can't handle va_arg
- Can't cast to a pointer of a struct that's typedef'd
- Can't use complex numbers with the ternary operator

These problems should be cleaned up before heavily promoting what 
is an incredible feature. I don't think it's widely known that 
you can translate C source files into D. I think that's really 
cool, but in addition to the bugs listed above that ImportC can't 
handle, it outputs things like dpulicate aliases, function 
argument names that are D keywords, and declaring unions inside 
structs equal to void. All of these are easy to fix by hand, but 
it's time consuming.


Once these final odds and ends are working, we have a killer 
language feature.


Re: Why is this code slow?

2024-03-26 Thread Lance Bachmeier via Digitalmars-d-learn

On Tuesday, 26 March 2024 at 14:25:53 UTC, Lance Bachmeier wrote:

On Sunday, 24 March 2024 at 19:31:19 UTC, Csaba wrote:
I know that benchmarks are always controversial and depend on 
a lot of factors. So far, I read that D performs very well in 
benchmarks, as well, if not better, as C.


I wrote a little program that approximates PI using the 
Leibniz formula. I implemented the same thing in C, D and 
Python, all of them execute 1,000,000 iterations 20 times and 
display the average time elapsed.


Here are the results:

C: 0.04s
Python: 0.33s
D: 0.73s

What the hell? D slower than Python? This cannot be real. I am 
sure I am making a mistake here. I'm sharing all 3 programs 
here:


C: https://pastebin.com/s7e2HFyL
D: https://pastebin.com/fuURdupc
Python: https://pastebin.com/zcXAkSEf

As you can see the function that does the job is exactly the 
same in C and D.


Here are the compile/run commands used:

C: `gcc leibniz.c -lm -oleibc`
D: `gdc leibniz.d -frelease -oleibd`
Python: `python3 leibniz.py`

PS. my CPU is AMD A8-5500B and my OS is Ubuntu Linux, if that 
matters.


As others suggested, pow is the problem. I noticed that the C 
versions are often much faster than their D counterparts. (And 
I don't view that as a problem, since both are built into the 
language - my only thought is that the D version should call 
the C version).


Changing

```
import std.math:pow;
```

to

```
import core.stdc.math: pow;
```

and leaving everything unchanged, I get

C: Avg execution time: 0.007918
D (original): Avg execution time: 0.102612
D (using core.stdc.math): Avg execution time: 0.008134

So more or less the exact same numbers if you use 
core.stdc.math.


And then the other thing is changing

```
const int BENCHMARKS = 20;
```

to

```
enum BENCHMARKS = 20;
```

which should allow substitution of the constant directly into the 
rest of the program, which gives


```
Avg execution time: 0.007564
```

On my Ubuntu 22.04 machine, therefore, the LDC binary with no 
flags is slightly faster than the C code compiled with your flags.


Re: Why is this code slow?

2024-03-26 Thread Lance Bachmeier via Digitalmars-d-learn

On Sunday, 24 March 2024 at 19:31:19 UTC, Csaba wrote:
I know that benchmarks are always controversial and depend on a 
lot of factors. So far, I read that D performs very well in 
benchmarks, as well, if not better, as C.


I wrote a little program that approximates PI using the Leibniz 
formula. I implemented the same thing in C, D and Python, all 
of them execute 1,000,000 iterations 20 times and display the 
average time elapsed.


Here are the results:

C: 0.04s
Python: 0.33s
D: 0.73s

What the hell? D slower than Python? This cannot be real. I am 
sure I am making a mistake here. I'm sharing all 3 programs 
here:


C: https://pastebin.com/s7e2HFyL
D: https://pastebin.com/fuURdupc
Python: https://pastebin.com/zcXAkSEf

As you can see the function that does the job is exactly the 
same in C and D.


Here are the compile/run commands used:

C: `gcc leibniz.c -lm -oleibc`
D: `gdc leibniz.d -frelease -oleibd`
Python: `python3 leibniz.py`

PS. my CPU is AMD A8-5500B and my OS is Ubuntu Linux, if that 
matters.


As others suggested, pow is the problem. I noticed that the C 
versions are often much faster than their D counterparts. (And I 
don't view that as a problem, since both are built into the 
language - my only thought is that the D version should call the 
C version).


Changing

```
import std.math:pow;
```

to

```
import core.stdc.math: pow;
```

and leaving everything unchanged, I get

C: Avg execution time: 0.007918
D (original): Avg execution time: 0.102612
D (using core.stdc.math): Avg execution time: 0.008134

So more or less the exact same numbers if you use core.stdc.math.


Re: The difference between the dates in years

2024-02-10 Thread Lance Bachmeier via Digitalmars-d-learn
On Saturday, 10 February 2024 at 21:56:30 UTC, Lance Bachmeier 
wrote:
On Saturday, 10 February 2024 at 15:53:09 UTC, Alexander Zhirov 
wrote:
Is it possible to calculate the difference between dates in 
years using regular means? Something like that



```
writeln(Date(1999, 3, 1).diffMonths(Date(1999, 1, 1)));
```

At the same time, keep in mind that the month and day matter, 
because the difference between the year, taking into account 
the month that has not come, will be less.


My abilities are not yet enough to figure it out more 
elegantly.


I'm assuming you mean you want the number of full years between 
the dates. If so, I use something like this:


```
import std;

void main() {
writeln(fullYears(Date(1999, 3, 1), Date(1999, 2, 1)));
writeln(fullYears(Date(2000, 3, 1), Date(1999, 2, 1)));
writeln(fullYears(Date(2000, 3, 1), Date(1999, 4, 1)));
writeln(fullYears(Date(2006, 4, 1), Date(1999, 4, 1)));
}

bool earlierInYear(Date date1, Date date2) {
return date1 < Date(date1.year, date2.month, date2.day);
}

long fullYears(Date date1, Date date2) {
assert(date1 >= date2, "The first date has to be later");
if (date1.earlierInYear(date2)) {
return max(date1.year - date2.year, 0);
} else {
return date1.year - date2.year;
}
}
```


should be

```
long fullYears(Date date1, Date date2) {
assert(date1 >= date2, "The first date has to be later");
if (date1.earlierInYear(date2)) {
return max(date1.year - date2.year - 1, 0);
} else {
return date1.year - date2.year;
}
}
```


Re: The difference between the dates in years

2024-02-10 Thread Lance Bachmeier via Digitalmars-d-learn
On Saturday, 10 February 2024 at 15:53:09 UTC, Alexander Zhirov 
wrote:
Is it possible to calculate the difference between dates in 
years using regular means? Something like that



```
writeln(Date(1999, 3, 1).diffMonths(Date(1999, 1, 1)));
```

At the same time, keep in mind that the month and day matter, 
because the difference between the year, taking into account 
the month that has not come, will be less.


My abilities are not yet enough to figure it out more elegantly.


I'm assuming you mean you want the number of full years between 
the dates. If so, I use something like this:


```
import std;

void main() {
writeln(fullYears(Date(1999, 3, 1), Date(1999, 2, 1)));
writeln(fullYears(Date(2000, 3, 1), Date(1999, 2, 1)));
writeln(fullYears(Date(2000, 3, 1), Date(1999, 4, 1)));
writeln(fullYears(Date(2006, 4, 1), Date(1999, 4, 1)));
}

bool earlierInYear(Date date1, Date date2) {
return date1 < Date(date1.year, date2.month, date2.day);
}

long fullYears(Date date1, Date date2) {
assert(date1 >= date2, "The first date has to be later");
if (date1.earlierInYear(date2)) {
return max(date1.year - date2.year, 0);
} else {
return date1.year - date2.year;
}
}
```


Re: Using C header libs with importC

2024-01-08 Thread Lance Bachmeier via Digitalmars-d-learn

On Monday, 8 January 2024 at 18:53:47 UTC, Renato wrote:

Is it possible to use C header-only libs from D?

In C, I would need to do this:

```c
#define STB_DS_IMPLEMENTATION
#include "stb_ds.h"
```

The definition must be done in a single C file before including 
the h file.


I tried this in D:

```d
enum STB_DS_IMPLEMENTATION = 1;
import stb_ds;
```

But it doesn't work. Any suggestions? Perhaps using an 
intermediate C file to do this would work, but I wanted to know 
if D can do it.


Without knowing the specifics of what you're trying to do, this 
automatic translation of C headers to D might be what you want:


https://forum.dlang.org/post/ugvc3o$5t3$1...@digitalmars.com

The way "header-only" is usually used suggests you should change 
the file extension to .c and compile it directly.