Re: Unexpected range assignment behaviour

2024-07-19 Thread Lance Bachmeier via Digitalmars-d-learn

On Friday, 19 July 2024 at 09:34:13 UTC, Lewis wrote:

```
string[3][string] lookup;
string[] dynArray = ["d", "e", "f"];
lookup["test"] = dynArray[0..$];
```

This fails at runtime with RangeError. But if I change that 
last line to:


```
lookup["test"] = dynArray[0..3];
```

then it works. But the value of $ here is 3. Why do I get a 
RangeError at runtime even though the slice is the correct size 
(and the same size as the hardcoded one that works)? I would 
have expected to only get a RangeError if at runtime the value 
turned out to be wrong.


The simplest solution is to keep them consistent:

```
string[3][string] lookup;
string[3] dynArray = ["d", "e", "f"];
```

or

```
string[][string] lookup;
string[] dynArray = ["d", "e", "f"];
```

Avoid the temptation to mix static and dynamic arrays and your 
life will be easier. If you run into a situation where it's tough 
to avoid, use an explicit conversion:


```
lookup["test"] = dynArray.to!(string[3])[0..$];
```

(I don't know all the complicated under the hood stuff as others 
do, but I know what works and why.)


Re: Being reading a lot about betterC, but still have some questions

2024-07-09 Thread Lance Bachmeier via Digitalmars-d-learn

On Tuesday, 9 July 2024 at 07:54:12 UTC, kiboshimo wrote:

If you haven't done so, I'd recommend reading the blog posts from 
Walter to get an understanding of why BetterC was introduced and 
how to use it: https://dlang.org/blog/category/betterc/


- betterC does not need glue code to interop with C. Does it 
achieve this by "gluing" behind the scenes? I've read in a 
comment somewhere that the ABI is the same, but idk people say 
lots of things.


You're declaring your D code extern(C), as you can see in 
Walter's blog posts, so yes, you're using the C ABI.




Re: Why does this mixin fail to compile?

2024-07-03 Thread Lance Bachmeier via Digitalmars-d-learn
On Wednesday, 3 July 2024 at 03:52:41 UTC, Steven Schveighoffer 
wrote:



```d
mixin template implement()
{
mixin(() {
// ctfe new array is basically the same as static array
char[] buffer = new char[4096];
int pos = 0;

void append(string str)
{
buffer[pos .. pos + str.length] = str[];
pos += str.length;
}

append("void* ctx;");
return buffer[0 .. pos];
}());
}
```

And yes, it is faster to do this than appending. But you have 
to do a *lot* of it to make a huge difference.


What about creating an array of strings and then using join? One 
obvious problem with this solution is the requirement to specify 
the size of `buffer`.


Re: ImportC "no include path set"

2024-06-22 Thread Lance Bachmeier via Digitalmars-d-learn

On Saturday, 22 June 2024 at 10:47:42 UTC, bachmeier wrote:

I don't normally use Dub for this reason (it takes longer for 
me to figure out how to create the dub.json than it's worth). 
I'd expect "dflags" to work, but I haven't tried, and I'm not 
sure how much of ImportC even works with GDC.


It doesn't seem to be documented, but there is a `cImportPaths` 
argument, which presumably does what you want: 
https://github.com/dlang/dub/blob/a8da51eb8a5485956622282f2339ec5a39c8c761/source/dub/recipe/json.d#L233


Re: How to use D without the GC ?

2024-06-13 Thread Lance Bachmeier via Digitalmars-d-learn

On Thursday, 13 June 2024 at 07:18:48 UTC, Dukc wrote:

Lance Bachmeier kirjoitti 13.6.2024 klo 1.32:


Why would it be different from calling malloc and free 
manually? I guess I'm not understanding, because you put the 
same calls to malloc and free that you'd otherwise be doing 
inside this and ~this.


Because with `SafeRefCounted`, you have to decide the size of 
your allocations at compile time, meaning you need to do a 
varying number of `malloc`s and `free`s to vary the size of 
your allocation at runtime. Even if you were to use templates 
to vary the type of `SafeRefCounted` object based on size of 
your allocation, the spec puts an upper bound of 16MiB to size 
of a static array.


We must be talking about different things. You could, for 
instance, call a function in a C library to allocate memory at 
runtime. That function returns a pointer and you pass it to 
SafeRefCounted to ensure it gets freed. Nothing is known about 
the allocation at compile time. This is in fact my primary use 
case - allocating an opaque struct allocated by a C library, and 
not wanting to concern myself with freeing it when I'm done with 
it.


Re: How to use D without the GC ?

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

On Wednesday, 12 June 2024 at 21:59:54 UTC, drug007 wrote:

Yes, but you get all the benefits of `double[]` for free if 
you do it that way, including the more concise foo[10] syntax.


I meant you do not need to add `ptr` field at all


I see. You're right. I thought it would be easier for someone new 
to the language to read more explicit code rather than assuming 
knowledge about data.ptr. In practice it's better to not have a 
ptr field.


Re: How to use D without the GC ?

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

On Wednesday, 12 June 2024 at 21:36:30 UTC, Dukc wrote:

bachmeier kirjoitti 12.6.2024 klo 18.21:
You're splitting things into GC-allocated memory and manually 
managed memory. There's also SafeRefCounted, which handles the 
malloc and free for you.


I suspect `SafeRefCounted` (or `RefCounted`) is not the best 
fit for this scenario. The problem with it is it `malloc`s and 
`free`s individual objects, which doesn't sound efficient to me.


Maybe it performs if the objects in question are big enough, or 
if they can be bundled to static arrays so there's no need to 
refcount individual objects. But even then, you can't just 
allocate and free dozens or hundreds of megabytes with one 
call, unlike with the GC or manual `malloc`/`free`. I honestly 
don't know if calling malloc/free for, say each 64KiB, would 
have performance implications over a single allocation.


Why would it be different from calling malloc and free manually? 
I guess I'm not understanding, because you put the same calls to 
malloc and free that you'd otherwise be doing inside this and 
~this.


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.