Re: Using ImportC to augment a big C project with D

2024-02-21 Thread Bastiaan Veelo via Digitalmars-d-learn
On Tuesday, 20 February 2024 at 18:33:42 UTC, Carl Sturtivant 
wrote:

2.
The C source calls exit() from C's stdlib, and D needs to 
terminate properly.


What do you mean by "need"? You can call 
https://dlang.org/phobos/core_stdc_stdlib.html#.exit from D:


```d
import std.stdio;

void main()
{
scope(exit) writeln("Bye");

import core.stdc.stdlib : exit;
exit(0);
}

shared static ~this()
{
writeln(__FUNCTION__);
}
```

Output:
```
onlineapp._sharedStaticDtor_L11_C1
```

So it does run module destructors, but not `scope(exit)` 
statements (which probably makes sense).


I would expect `exit()` called from the C source to have similar 
results.


--Bastiaan


Re: `static` function ... cannot access variable in frame of ...

2024-01-16 Thread Bastiaan Veelo via Digitalmars-d-learn
On Monday, 15 January 2024 at 23:06:00 UTC, Steven Schveighoffer 
wrote:

As a workaround, you can alias the outer function in the struct:

```d
struct S
{
alias foo = S_foo;
}
```

This might be less than ideal, but at least it works.


It does! And it's good enough for me. Thanks a lot!

-- Bastiaan.


Re: `static` function ... cannot access variable in frame of ...

2024-01-15 Thread Bastiaan Veelo via Digitalmars-d-learn

On Monday, 15 January 2024 at 18:43:43 UTC, user1234 wrote:

The two calls are not equivalent.



so what is passed as alias need to be static too.


Thanks all. I thought a static member function just isn't able to 
access the instance of the struct, but as I understand now it is 
static all the way.


What I am looking for is a way to have different structs that 
have a member function that has the same name in all of them, 
that is callable without a this pointer, and able to take an 
alias argument. That is probably asking too much.


-- Bastiaan.


`static` function ... cannot access variable in frame of ...

2024-01-15 Thread Bastiaan Veelo via Digitalmars-d-learn
Hey people, I can use some help understanding why the last line 
produces a compile error.


```d
import std.stdio;

struct S
{
static void foo(alias len)()
{
writeln(len);
}
}

void S_foo(alias len)()
{
writeln(len);
}

void main()
{

const five = 5;
S_foo!five; // Fine
S.foo!five; // Error
}
```

The error is
```
onlineapp.d(7): Error: `static` function 
`onlineapp.main.foo!(5).foo` cannot access variable `five` in 
frame of function `D main`

onlineapp.d(19):`five` declared here
onlineapp.d(21): Error: template instance 
`onlineapp.main.foo!(5)` error instantiating

```

It seems to me this should just work.

Thanks!

--Bastiaan.


Re: Returning a reference to be manipulated

2023-04-14 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 14 April 2023 at 00:50:31 UTC, kdevel wrote:

```
ref int foo (ref int i)
{
   return i;
}

ref int bar ()
{
   int i;
   return foo (i);
}

void main ()
{
   import std.stdio;
   auto i = bar;
   i.writeln;
}
```

Up to dmd v2.100.2 I am warned/get an error during compilation:

```
$ dmd returnref2.d
returnref2.d(3): Deprecation: returning `i` escapes a reference 
to parameter `i`
returnref2.d(1):perhaps annotate the parameter with 
`return`

$ dmd -dip1000 returnref2.d
returnref2.d(3): Error: returning `i` escapes a reference to 
parameter `i`
returnref2.d(1):perhaps annotate the parameter with 
`return`

```

With later dmd versions (up to including v2.102.2) the code 
compiles without complaints. Is this intended?


I think this is intended. Adding `@safe:` on top makes the 
complaint come back (in dmd  2.102 it is deprecated, in 2.103 it 
is an error).


-- Bastiaan.


Re: Traverse a DList and insert / remove in place?

2023-03-25 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 19 March 2023 at 13:15:58 UTC, Armando wrote:
I would like to do something like traversing a DList, operating 
on the current element, and potentially removing that element 
or inserting a new one before/after it - an easy operation if 
you code a DList yourself. Maybe I missed something?


This is one way to do that:
```d
import std;

struct MyType
{
int id;
// [...] other stuff
}

void main()
{
auto list = DList!MyType();

// Fill the list.
foreach (i; 0 .. 10)
list.insertBack(MyType(i));

// Traverse the list, conditionally remove one element.
for (auto range = list[]; !range.empty;)
if (range.front.id == 3)
list.popFirstOf(range);
else
range.popFront();

// Traverse the list, conditionally insert one element.
for (auto range = list[]; !range.empty;)
{
if (range.front.id == 6)
list.insertBefore(range, MyType(66));
range.popFront();
}

// Print modified list.
foreach (e; list)
writeln(e);

}
```

Output:
```
MyType(0)
MyType(1)
MyType(2)
MyType(4)
MyType(5)
MyType(66)
MyType(6)
MyType(7)
MyType(8)
MyType(9)
```

https://run.dlang.io/is/kk80FD

-- Bastiaan.


Re: toString best practices

2023-02-15 Thread Bastiaan Veelo via Digitalmars-d-learn
On Thursday, 9 February 2023 at 17:49:58 UTC, Paolo Invernizzi 
wrote:

```
import std.format, std.range.primitives;

struct Point(T)
{
T x, y;

void toString(W)(ref W writer, scope const ref 
FormatSpec!char f) const

if (isOutputRange!(W, char))
{
put(writer, "(");
formatValue(writer, x, f);
put(writer, ", ");
formatValue(writer, y, f);
put(writer, ")");
}
}

void main(){

import std.format : format;
assert( format("%s", Point!int(1,2)) == "(1, 2)");

import std.experimental.logger;
sharedLog.infof("%s", Point!int(1,2));
}
```


Pasting this into https://run.dlang.io/, it just works. That's 
for DMD 2.099, so it might be a regression -- or recent feature?


-- Bastiaan.


Re: How do you work with lst files?

2022-08-25 Thread Bastiaan Veelo via Digitalmars-d-learn
On Wednesday, 24 August 2022 at 22:29:51 UTC, Christian Köstlin 
wrote:
I want to ask around how you from the dlang community work with 
.lst coverage files?


No personal experience, but there are half a dozen options on 
https://code.dlang.org/search?q=Coverage


— Bastiaan.


Re: How to escape control characters?

2022-08-23 Thread Bastiaan Veelo via Digitalmars-d-learn

On Thursday, 31 March 2016 at 03:15:49 UTC, cy wrote:
This might be a dumb question. How do I format a string so that 
all the newlines print as \n and all the tabs as \t and such?


The easiest is this:

```d
import std.conv;
string str = `Hello "World"
line 2`;
writeln([str].text[2..$-2]); // Hello \"World\"\nline 2
```

I know this is an old post, but I felt this trick needed to be 
shared.


This takes advantage of the fact that `std.format` escapes the 
characters in an array of strings. So we create an array where 
`str` is the only element, and convert that to text. Without the 
`[2..$-2]` slicing the output would be `["Hello \"World\"\nline 
2"]`.


A slightly more efficient implementation is
```d
string escape(string s)
{
import std.array : appender;
import std.format : FormatSpec, formatValue;

FormatSpec!char f;
auto w = appender!string;
w.reserve(s.length);
formatValue(w, [s], f);
return w[][2 .. $ - 2];
}
```

And the inverse:
```d
string unescape(string s)
{
import std.format : FormatSpec, unformatValue;

FormatSpec!char f;
string str = `["` ~ s ~ `"]`;
return unformatValue!(string[])(str, f)[0];
}
```

Perhaps `escape()` and `unescape()` should be part of 
`std.format` so that they can be refactored to use 
`std.format.internal.write.formatElement` directly, eliminating 
the conversion to array.


-- Bastiaan.


Re: Null terminated character

2022-07-02 Thread Bastiaan Veelo via Digitalmars-d-learn

On Thursday, 23 June 2022 at 16:16:26 UTC, vc wrote:
I've try this '\0'*10 and didn't work, i want the results be 
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00


```d
string nulls = '\0'.repeat(10).array;
```

— Bastiaan.


Re: Why allow initializers of non-static members that allocate?

2022-06-11 Thread Bastiaan Veelo via Digitalmars-d-learn

On Saturday, 11 June 2022 at 10:52:58 UTC, Mike Parker wrote:
I agree with your initial assessment that it should be an 
error. It really only makes sense to allow the dynamic 
allocation if the fields are immutable and, in the case of 
arrays, the initializer is a literal.





Re: Why allow initializers of non-static members that allocate?

2022-06-11 Thread Bastiaan Veelo via Digitalmars-d-learn

On Saturday, 11 June 2022 at 01:52:58 UTC, Mike Parker wrote:
People getting bit by `new` in field initialization often 
enough that I think a warning would be helpful.


The problem is so much bigger because it is not just a case of 
being aware not to use `new` in member initialisers. As you see 
in my second example in 
https://forum.dlang.org/post/ogvubzgprghefclgl...@forum.dlang.org 
there is no `new` anywhere. In fact you could say an effort has 
been made to do the right thing in `struct A`  where the 
allocation has been moved to the constructor (a strategy that is 
not always available because structs don’t have default 
constructors) yet we fell into the same trap.


My point is that this problem can be buried deep down under 
multiple layers and you can’t really ever be sure that there 
isn’t a problem in your massive code base.


But any such warnings need to be enabled by default to be 
useful, and must have an off switch for people who don't need 
them. So the question in each case would be, where's the line 
between helpful and annoying?


So that’s why I used “why” in the title of this thread, which I 
haven’t seen an answer to yet. What is the practical case where 
that warning would be annoying? When would you actually want this 
behaviour?


— Bastiaan.




Re: Why allow initializers of non-static members that allocate?

2022-06-10 Thread Bastiaan Veelo via Digitalmars-d-learn
On Friday, 10 June 2022 at 14:56:24 UTC, Steven Schveighoffer 
wrote:

On 6/10/22 3:46 AM, Mike Parker wrote:
I think this is a case where having a warning that's on by 
default, and which can be explicitly disabled, is useful. 
"Blah blah .init blah blah. See link-to-something-in-docs. Is 
this what you intended?"


Here the language is being extremely unsafe.

Not only is the field shared between instances, it's shared 
across instances in *different threads*.


Discovered circa 2009: 
https://issues.dlang.org/show_bug.cgi?id=2947


Thanks for the pointer. #dbugfix 2947

It should be illegal to declare a field this way that has 
mutable references without being `shared`. End of story.





Re: Why allow initializers of non-static members that allocate?

2022-06-10 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 10 June 2022 at 07:49:43 UTC, Mike Parker wrote:

And it *is* documented:

Struct fields are by default initialized to whatever the 
Initializer for the field is, and if none is supplied, to the 
default initializer for the field's type.

The default initializers are evaluated at compile time.


https://dlang.org/spec/struct.html#default_struct_init


Yes, that section I find open for interpretation, because I don't 
think pointer values can be determined at compiler time. I assume 
S.init is constructed at program initialization, which is then 
blitted into any new instance of S.


-- Bastiaan.


Re: Why allow initializers of non-static members that allocate?

2022-06-10 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 10 June 2022 at 07:46:36 UTC, Mike Parker wrote:

On Friday, 10 June 2022 at 07:35:17 UTC, Bastiaan Veelo wrote:

Is there a use case where this makes sense? I would have much 
appreciated the compiler slapping me on the fingers, but it 
doesn't. I understand that it is safe and that the compiler 
can allow this, but why would anyone want that? D-scanner does 
not check for this either.


Any initialization of a member field is overriding the field's 
`.init` value for the type. If a dynamic allocation set a 
different value per instance, then you'd have inconsistent 
behavior with, e.g., `int a = 5`.


Yes, I understand that the compiler can't do what I was expecting 
it to do, it was a mistake.


I think a helpful error message would be: "Error: The 
initializer `A(5)` allocates memory that is shared among all 
instances of `S`. If you want that, make `S.a` `static`."


I understand that it's not something that people expect, but 
making it an error can't be the answer. And making it a static 
field is not the same thing.


It's not the same thing, therefore I was hoping to see a use case 
for it -- but just because I'm curious; Preventing the mistake is 
my main thing.


I think this is a case where having a warning that's on by 
default, and which can be explicitly disabled, is useful. "Blah 
blah .init blah blah. See link-to-something-in-docs. Is this 
what you intended?"


That would be fine too. By the way, if there is 
something-in-docs, I don't think it is prominent enough...



-- Bastiaan.


Why allow initializers of non-static members that allocate?

2022-06-10 Thread Bastiaan Veelo via Digitalmars-d-learn

I have been foolish enough to make a mistake like this:
```d
struct S
{
int[] arr = new int[](5);
}
```

This is terrible because
```d
S s1;
S s2;
s2.arr[0] = 42;
writeln(s1.arr[0]); // 42 Gotcha!
```

Of course there are less obvious variants of the same mistake:
```d
import std;

struct S
{
A a = A(5);
}

struct A
{
int[] arr;
this (int l)
{
arr.length = l;
}
}

void main()
{
S s1;
S s2;
s2.a.arr[0] = 42;
writeln(s1.a.arr[0]); // 42 :-(
}
```

Is there a use case where this makes sense? I would have much 
appreciated the compiler slapping me on the fingers, but it 
doesn't. I understand that it is safe and that the compiler can 
allow this, but why would anyone want that? D-scanner does not 
check for this either.


I think a helpful error message would be: "Error: The initializer 
`A(5)` allocates memory that is shared among all instances of 
`S`. If you want that, make `S.a` `static`."


-- Bastiaan.


Re: Library for image editing and text insertion

2022-04-27 Thread Bastiaan Veelo via Digitalmars-d-learn
On Wednesday, 27 April 2022 at 09:27:24 UTC, Alexander Zhirov 
wrote:
Now I would like to reduce the size of the executable file and 
it would be great at all!


Try the `-release` option to `dmd`. Or use LDC.

-- Bastiaan.


Re: Language server

2022-04-27 Thread Bastiaan Veelo via Digitalmars-d-learn

On Tuesday, 26 April 2022 at 18:15:57 UTC, Alain De Vos wrote:
In a perfect world there would be someone uploading a youtube 
video how to implement

neovim with a dlang language-server.
With function-completions-help where hints are given about the 
functions and libraries.

If anyone could do this , this would be nice to have.


I'm not a vim user, but there is this: 
https://wiki.dlang.org/D_in_Vim


If that is what you needed to get what you want, maybe make a 
YouTube video about it ;-)


-- Bastiaan.


Re: How to use Vector Extensions in an opBinary

2022-04-21 Thread Bastiaan Veelo via Digitalmars-d-learn

On Thursday, 21 April 2022 at 15:31:04 UTC, HuskyNator wrote:

On Sunday, 17 April 2022 at 17:04:57 UTC, Bastiaan Veelo wrote:
You might want to have a look at 
https://code.dlang.org/packages/intel-intrinsics


— Bastiaan.


This does not discuss core.simd or __vector type, or did I 
miss/mininterpret something?


It wraps `core.simd` with an eye on portability. I haven’t used 
it myself, but my impression is that if you’re interested in 
`core.simd`, intel-intrinsics may be a better option. I think 
there is also better documentation. There is a video of a DConf 
presentation that you may want to watch.


— Bastiaan.


Re: Can Enums be integral types?

2022-04-19 Thread Bastiaan Veelo via Digitalmars-d-learn

On Tuesday, 19 April 2022 at 01:25:13 UTC, Era Scarecrow wrote:

The 'integral' or numeric value is used for uniqueness, […]


There is nothing that requires enum values to be unique, though:
```d
import std;
void main()
{
enum E {Zero = 0, One = 0, Two = 0}
writeln(E.Two); // Zero!
}
```

— Bastiaan.


Re: Can Enums be integral types?

2022-04-17 Thread Bastiaan Veelo via Digitalmars-d-learn

On Saturday, 16 April 2022 at 11:39:01 UTC, Manfred Nowak wrote:
In the specs(17) about enums the word "integral" has no match. 
But because the default basetype is `int`, which is an integral 
type, enums might be integral types whenever their basetype is 
an integral type.


On the other hand the specs(7.6.5.3) about types say
| A bool value can be implicitly converted to any integral type,
| with false becoming 0 and true becoming 1.

This seems senseless, when the enum has no names defined for 
one of these values.


Not sure where the question is, but 
[6.5.3](https://dlang.org/spec/type.html#bool) makes that this 
works:

```d
int i = true; // 1
```
However this does not:
```d
enum E : int {Zero, One, Two}
E e1 = true; // Error: cannot implicitly convert expression 
`true` of type `bool` to `E`
E e2 = 1; // Error: cannot implicitly convert expression `1` of 
type `int` to `E`

```
The reason is in [17.1.5](https://dlang.org/spec/enum.html): 
“EnumBaseType types cannot be implicitly cast to an enum type.”


— Bastiaan.


Re: How to use Vector Extensions in an opBinary

2022-04-17 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 17 April 2022 at 11:16:25 UTC, HuskyNator wrote:
I recently found out there is [support for vector 
extensions](https://dlang.org/spec/simd.html)
But I have found I don't really understand how to use it, not 
even mentioning the more complex stuff. I couldn't find any 
good examples either.


You might want to have a look at 
https://code.dlang.org/packages/intel-intrinsics


— Bastiaan.




Re: package libs on windows

2022-02-01 Thread Bastiaan Veelo via Digitalmars-d-learn

On Tuesday, 1 February 2022 at 21:17:09 UTC, Abby wrote:
 I would like to know if there is a way to set path to lib to 
downloaded with package instead of harcoded.


That’s documented on the [package 
page](https://code.dlang.org/packages/d2sqlite3).


Are you trying to link with a separately downloaded version, or 
de included version? How have you configured your `dub.json`, and 
do you supply any options in the `dub` invocation?


— Bastiaan.


Re: std.signals: Why emit() not extist?

2021-12-30 Thread Bastiaan Veelo via Digitalmars-d-learn

On Thursday, 30 December 2021 at 19:13:10 UTC, Marcone wrote:
I get this error: Error: undefined identifier `emit`, did you 
mean function `exit`?


Did you `import std.signals`?

— Bastiaan.


Re: First time using Parallel

2021-12-26 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 26 December 2021 at 15:20:09 UTC, Bastiaan Veelo wrote:
So if you use `workerLocalStorage` to give each thread an 
`appender!string` to write output to, and afterwards write 
those to `stdout`, you'll get your output in order without 
sorting.


Scratch that, I misunderstood the example. It doesn't solve 
ordering. The example works because order does not matter for 
addition. Sorry for spreading wrong information.


-- Bastiaan.


Re: First time using Parallel

2021-12-26 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 26 December 2021 at 06:10:03 UTC, Era Scarecrow wrote:

[...]


```d
foreach(value; taskPool.parallel(range) ){code}
```


[...]


 Now said results are out of order


[...]

 So I suppose, is there anything I need to know? About shared 
resources or how to wait until all threads are done?


Have a look at `taskPool.workerLocalStorage`. I learned about 
this in [a post by data 
pulverizer](https://forum.dlang.org/post/ddgxqoitxoaljfwnl...@forum.dlang.org), who gives this example (slightly modified):

```d
import std.traits : isFloatingPoint;

auto dot(T)(T[] x, T[] y) if (isFloatingPoint!T)
in (y.length == x.length)
{
import std.range : iota;
import std.parallelism : parallel, taskPool;

auto sums = taskPool.workerLocalStorage(0.0L);
foreach (i; parallel(iota(x.length)))
sums.get += x[i] * y[i];
T result = 0.0;
foreach (threadResult; sums.toRange)
result += threadResult;
return result;
}

void main()
{
double[] x = [1, 2, 3, 4, 5];
double[] y = [6, 7, 8, 9, 10];
assert(dot(x, y) == 130);
}
```
(https://run.dlang.io/is/Ia8A0k)

So if you use `workerLocalStorage` to give each thread an 
`appender!string` to write output to, and afterwards write those 
to `stdout`, you'll get your output in order without sorting.


--Bastiaan.



Re: Why does is the RandomAccessInfinite interface not a valid RandomAccessRange?

2021-12-19 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 19 December 2021 at 09:19:31 UTC, D Lark wrote:

Do you know if there's a nightly version I can specify to use 
your fix?


Are you inheriting from `RandomAccessInfinite`? Then you can 
probably add

```d
static if (__VERSION__ < 2099)
enum bool empty = false;
```
to make it work.

— Bastiaan.


Re: DMD32 D Compiler v2.097.2-dirty ?

2021-09-08 Thread Bastiaan Veelo via Digitalmars-d-learn

On Monday, 6 September 2021 at 15:37:31 UTC, Paul wrote:
I like to write CLEAN code:)  Why does my DMD installation say 
v2.097.2-dirty?


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

I suppose it is due to how the scripts work that produce the 
compiler release. I guess these can be found online somewhere; 
Martin Nowak has been taking care of the releases for many years.


I agree that it would look better to “clean this up”, but knowing 
that it is just cosmetics most people have more pressing tasks at 
hand… It looks like it would be easy enough for anyone to fix, 
though :-)


— Bastiaan.


Re: Curious effect with traits, meta, and a foreach loop ... mystifies me.

2021-09-08 Thread Bastiaan Veelo via Digitalmars-d-learn
On Tuesday, 7 September 2021 at 17:24:34 UTC, james.p.leblanc 
wrote:


```d
/*…*/

   // this is fine (notice that 'val' is never used
   foreach( i, val ; u.tupleof ){
  ptr = u.tupleof[i].x.ptr;
  writeln("ptr: ", ptr);
   }

   // this fails with: "Error: variable 'i' cannot be read at 
compile time

   //
   // foreach( i ; 0 .. 3 ){
   //ptr = u.tupleof[i].x.ptr;
   //writeln("ptr: ", ptr);
   // }
}

```


As Adam mentioned `tupleof` only exists at compile time, and a 
`foreach` over a `tupleof` gets unrolled at compile time, akin to 
a `static foreach`. Consequently you can make your snippet work 
by prepending `static` (and fixing the range):


```d
static foreach (i; 0 .. u.tupleof.length) {
   ptr = u.tupleof[i].x.ptr;
   writeln("ptr: ", ptr);
}
```
https://run.dlang.io/is/T6jrjf

Not sure if that helps in what you’re trying to achieve though, 
as that isn’t clear to me.


—Bastiaan.



Re: implimenting interface function by inheriting from other class

2021-08-21 Thread Bastiaan Veelo via Digitalmars-d-learn

On Saturday, 21 August 2021 at 20:35:43 UTC, Alexey wrote:

Hello
```D
interface Int
{
void coolFunc();
}

class C1
{
void coolFunc()
{
return;
}
}

class C2 : C1, Int
{

}

void main()
{
auto c = new C2;
}
```
dmd says it's not Ok:
t.d(14): Error: class `t.C2` interface function `void 
coolFunc()` is not implemented


how to make dmd happy?


Not sure if this is the best way, but it does make dmd happy: 
https://run.dlang.io/is/44F3AE


```d

class C2 : C1, Int
{
override void coolFunc()
{
C1.coolFunc;
}
}
```

It looks lame, I admit.

— Bastiaan.


Re: simple (I think) eponymous template question ... what is proper idimatic way ?

2021-08-17 Thread Bastiaan Veelo via Digitalmars-d-learn

On Tuesday, 17 August 2021 at 20:29:51 UTC, james.p.leblanc wrote:

So, below
is my code:

import std.stdio;
import std.meta : AliasSeq;

template isAmong(T, S...) {
   static if (S.length == 0)
  enum isAmong = false;
   else
  enum isAmong = is(T == S) || isAmong(T, S[1..$]);
}

alias MyTypes = AliasSeq!(int, float);

auto myFunc(T)(T a, T b) if (isAmong!(T, MyTypes)) {
  writeln(" in myFunc ");
  return;
}

void main(){
  writeln("started ...");
   auto a = 1;
   auto b = 2;
   myFunc!(int)(a, b);
   return;
}


And, here are the error message:

(master) Notes > dmd recursive_template.d
recursive_template.d(9): Error: circular reference to variable 
`recursive_template.isAmong!(int, int, float).isAmong`
recursive_template.d(17): Error: template instance 
`recursive_template.isAmong!(int, int, float)` error 
instantiating
recursive_template.d(29):while looking for match for 
`myFunc!int`


Can anyone see what is going on?

Best Regards,
James


https://run.dlang.io/is/m5svQ2

The error was in line 8.
T (Teoh) forgot to take the first of `S` in `is(T == S[0])`. The 
error message improves after adding the `!` in `isAmong!(T, 
S[1..$])`, which, surprisingly, is optional!


— Bastiaan.


Re: Getting a working example of opIndexAssign using opSlice ... have troubles ...

2021-08-15 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 15 August 2021 at 20:41:51 UTC, james.p.leblanc wrote:

struct A
{
int opIndexAssign(int v);  // overloads a[] = v
int opIndexAssign(int v, size_t[2] x);  // overloads 
a[i .. j] = v
int[2] opSlice(size_t x, size_t y); // overloads i 
.. j

}

void test()
{
A a;
int v;

a[] = v;  // same as a.opIndexAssign(v);
a[3..4] = v;  // same as a.opIndexAssign(v, 
a.opSlice(3,4));

}

I have hacked at this trying to get a simple working example.


Not sure if this does enough of what you’re looking for, but this 
covers the minimal steps to get it working: 
https://run.dlang.io/is/m5svQ2


```d

import std;

struct A
{
int opIndexAssign(int v) // overloads a[] = v
{
writeln(__FUNCTION__);
return 42;
}
int opIndexAssign(int vh, size_t[2] x)  // overloads a[i .. 
j] = v

{
writeln(__FUNCTION__);
return 43;
}
int[2] opSlice(size_t x, size_t y) // overloads i .. j
{
writeln(__FUNCTION__);
return [44, 45];
}
}

void main()
{
A a;
int v;

a[] = v;  // same as a.opIndexAssign(v);
a[3..4] = v;  // same as a.opIndexAssign(v, a.opSlice(3,4));
}
```

— Bastiaan.




Re: D has the same memory model as C++

2021-08-11 Thread Bastiaan Veelo via Digitalmars-d-learn

On Wednesday, 11 August 2021 at 05:33:06 UTC, Tejas wrote:
On Tuesday, 10 August 2021 at 21:19:39 UTC, Bastiaan Veelo 
wrote:

On Tuesday, 10 August 2021 at 16:00:37 UTC, Tejas wrote:
Basically, what are the subtle gotcha's in the differences 
between C++ and D code that looks similar


The only gotcha that comes to my mind is that `private` means 
private to the module in D, not private to the aggregate.


— Bastiaan.


A few others that I know:

When importing one module(say ```m2```) into another (say 
```m1```), the symbols of ```m1``` aren't automatically visible 
in ```m2```. You must import ```m1``` in ```m2``` for that.


How is that different from C++? I think you meant to say that if 
`m1` imports `m2`, the symbols of `m2` don't automatically become 
visible by importing `m1`. Indeed you also have to import `m2` 
for that, *unless* `m1` `public`ly imports `m2`.


You can't just initialize variables willy-nilly in a module, 
you must do them inside ```static this()```


Or declare them with an initial value. I'm not aware of a rule 
that requires module level variables to be initialized in `static 
this()`, but if you require them to be initialized at startup 
with a value not known at compile time, then that is the place to 
do it. I don't think you can go about this willy-nilly in C++ 
either...


Method function pointers don't exist in D, equivalent 
functionality is achieved by using a delegate that captures the 
context of a class instantiated object.


To use a function pointer explicitly, you can't just write 
```(func)(arguments)```, it is ```()(arguments)```(thank 
you evilrat)


To take the address of a method (in order to assign it to a 
delegate) requires `&`, yes, but not when calling the delegate.


--Bastiaan.


Re: D has the same memory model as C++

2021-08-10 Thread Bastiaan Veelo via Digitalmars-d-learn

On Tuesday, 10 August 2021 at 18:13:17 UTC, Tejas wrote:
On Tuesday, 10 August 2021 at 18:07:35 UTC, Bastiaan Veelo 
wrote:

On Tuesday, 10 August 2021 at 16:00:37 UTC, Tejas wrote:
there's casting away const, a clearly seperate language 
feature which has no equivalent in D;


You *can* cast away `const` in D: 
https://run.dlang.io/is/sWa5Mf


— Bastiaan.


Yes, but it is UB, not defined and supported by the 
standard/implementation.


OK, strictly speaking casting away `const` is in the language, 
but modifying after that is UB.

https://dlang.org/spec/const3.html#removing_with_cast

— Bastiaan.


Re: D has the same memory model as C++

2021-08-10 Thread Bastiaan Veelo via Digitalmars-d-learn

On Tuesday, 10 August 2021 at 16:00:37 UTC, Tejas wrote:
Basically, what are the subtle gotcha's in the differences 
between C++ and D code that looks similar


The only gotcha that comes to my mind is that `private` means 
private to the module in D, not private to the aggregate.


— Bastiaan.




Re: D has the same memory model as C++

2021-08-10 Thread Bastiaan Veelo via Digitalmars-d-learn

On Tuesday, 10 August 2021 at 16:00:37 UTC, Tejas wrote:
there's casting away const, a clearly seperate language feature 
which has no equivalent in D;


You *can* cast away `const` in D: https://run.dlang.io/is/sWa5Mf

— Bastiaan.




Re: Error when compile with DMD using -m64?

2021-08-10 Thread Bastiaan Veelo via Digitalmars-d-learn

On Tuesday, 10 August 2021 at 17:13:31 UTC, Marcone wrote:
On Tuesday, 10 August 2021 at 15:55:42 UTC, Bastiaan Veelo 
wrote:
Use `size_t` and `ptrdiff_t` instead to make your program 
compile in both 32 bit and 64 bit modes.


https://dlang.org/spec/type.html#aliased-types

-- Bastiaan.


Thank you very much! Your information was very precious! It 
worked very well! Now I can create x32 or x64 compatible 
programs without creating two codes.


You’re welcome :-)

— Bastiaan.


Re: Error when compile with DMD using -m64?

2021-08-10 Thread Bastiaan Veelo via Digitalmars-d-learn

On Tuesday, 10 August 2021 at 01:29:04 UTC, Marcone wrote:

Solved converting long and int.


Use `size_t` and `ptrdiff_t` instead to make your program compile 
in both 32 bit and 64 bit modes.


https://dlang.org/spec/type.html#aliased-types

-- Bastiaan.


Re: How Add Local modules mymodule.d using DUB?

2021-08-09 Thread Bastiaan Veelo via Digitalmars-d-learn

On Monday, 9 August 2021 at 16:32:13 UTC, Marcone wrote:

My main program need import a local module called mymodule.d.
How can I add this module using DUB? Thank you.


Let’s assume you just created a dub project in `myproject` with 
`dub init`. Place `mymodule.d` alongside `app.d` in 
`myproject/source`. Now you can `import mymodule` in `app.d`. Dub 
takes care of the linking.


— Bastiaan.


Re: writef, compile-checked format, pointer

2021-08-09 Thread Bastiaan Veelo via Digitalmars-d-learn

On Monday, 9 August 2021 at 22:01:18 UTC, Patrick Schluter wrote:

On Monday, 9 August 2021 at 19:38:28 UTC, novice2 wrote:

format!"fmt"() and writef!"fmt"() templates
with compile-time checked format string
not accept %X for pointers,

but format() and writef() accept it

https://run.dlang.io/is/aQ05Ux
```
void main() {
import std.stdio: writefln;
int x;
writefln("%X", );  //ok
writefln!"%s"();  //ok
//writefln!"%X"();  //compile error
}
```

is this intentional?


Yes. %X is to format integers.


It is to format pointers as well, according to the last table on 
https://dlang.org/phobos/std_format.html.


|Type|Format character|Formatted as|
|-|-|-|
|Pointer|	's'	|A null pointer is formatted as 'null'. All other 
pointers are formatted as hexadecimal numbers with the format 
character 'X'.|

| |'x', 'X' |Formatted as a hexadecimal number.|

It looks like a bug to me.

— Bastiaan.




Re: Exit before second main with -funittest

2021-07-30 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 30 July 2021 at 05:51:41 UTC, Brian Tiffin wrote:

[... interesting account of the D experience ...]


**Kudos team and contributors.**

Can't really suggest that many improvements to resources needed 
for learning D, as a hobbyist not on a clock, being new still 
and low enough to not know what detail interactions might be 
less approachable.  So far, very approachable.  Not confusing, 
but tantalizing caves to explore and integrate into knowing 
about potentials, super powers, and dark corners that may need 
to be accounted for.


And friendly people to pester with random brain train new here 
questions.


Have good, make well, and thanks.


I enjoyed reading all of that.

-- Bastiaan.


Re: how to make D program footprint smaller ?

2021-07-10 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 9 July 2021 at 03:07:04 UTC, dangbinghoo wrote:
as questioned in the previous thread, I need to find out 
something like `--as-needed` options available for D.


You are probably looking for the 
[-i](https://dlang.org/dmd-osx.html#switch-i%5B) compiler option. 
As far as I know `dub` is not devised to work with that, so 
making use of it can be finicky. I have managed to get it to work 
on a `sourceLibrary` that we control, not sure how applicable it 
is on a third party package.


— Bastiaan.


Re: Can I get the time "Duration" in "nsecs" acurracy?

2021-07-09 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 9 July 2021 at 21:13:02 UTC, rempas wrote:

On Friday, 9 July 2021 at 20:54:21 UTC, Paul Backus wrote:

On Friday, 9 July 2021 at 20:43:48 UTC, rempas wrote:
I'm reading the library reference for 
[core.time](https://dlang.org/phobos/core_time.html#Duration) 
and It says that the duration is taken in "hnsecs" and I 
cannot understand if we can change that and choose the 
precision. Does anyone know if we can do that?


It is stored internally in "hnsecs", but you can convert it to 
other units using the `total` method [1]; for example, 
`myDuration.total!"nsecs"`.


[1] https://dlang.org/phobos/core_time.html#.Duration.total


It doesn't work for me. I have the following code:

```
MonoTime start = MonoTime.currTime();
// Doing stuff
MonoTime end = MonoTime.currTime();
Duration dur = end - start;
dur = dur.total!"nsecs";
```

and I get the following error message:

"Error: cannot implicitly convert expression \`dur.total()\` of 
type \`long\` to \`Duration`"


You cannot change the precision of `Duration`, it always counts 
in multiples of 100 nsecs. You can count how many multiples of 
other units fit into the same `Duration` using `total`, but it 
will just return a number, not a “converted” `Duration`.


`toString` will produce an easy readable string (more or less), 
as in https://run.dlang.io/is/baqKLG, where “hnsec” is the 
smallest unit. If you think hectonanosecond is a weird unit, then 
[you are not 
alone](https://forum.dlang.org/post/pwotyniksrskdzmea...@forum.dlang.org), and it [has been pointed out](https://forum.dlang.org/post/khppfxsyfefjksvri...@forum.dlang.org) that it does not comply with SI.


— Bastiaan.


Re: Is there an alias for standard libraries to use in import statement?

2021-07-04 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 4 July 2021 at 07:40:44 UTC, BoQsc wrote:
I just started with a fresh look at the D language and would 
like to be able to rewrite this code:



import std;
void main()
{
writeln("Hello D");
}


Into more readable standard library name:


import system;
void main()
{
writeln("Hello D");
}


That is [easy](https://run.dlang.io/is/af8dMY), just define the 
`system` module and publicly `import std`:


--- test.d
```d
import system;
void main()
{
writeln("Hello D");
}
```

--- system.d
```d
module system;
public import std;
```

But like Mike, I advise against this. It will confuse every D 
programmer that is trying to read your code. What is most natural 
depends heavily on your background and what language you are 
coming from. `std` is perfectly natural if you're coming from C++.


Fun fact (but equally ill advised): You can hide the entire 
import from view like this:

```d
void main()
{
writeln("Hello D");
}

/* Lean on Enter for a while */

import std;
```

-- Bastiaan.


Re: Printing Tuple!(...)[] using for loop?

2021-07-02 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 2 July 2021 at 04:21:24 UTC, Kirill wrote:

I have a `Tuple!(string, ..., string)[] data`


If there are only strings in the tuple, it could be simplified by 
making it a static array of strings instead. The compile-time 
index issue would go away.


—Bastiaan


Re: How to call stop from parallel foreach

2021-06-24 Thread Bastiaan Veelo via Digitalmars-d-learn

On Thursday, 24 June 2021 at 20:56:26 UTC, Ali Çehreli wrote:

On 6/24/21 1:33 PM, Bastiaan Veelo wrote:

> distributes the load across all cores (but one).

Last time I checked, the current thread would run tasks as well.

Ali


Indeed, thanks.

— Bastiaan.


Re: How to call stop from parallel foreach

2021-06-24 Thread Bastiaan Veelo via Digitalmars-d-learn

On Thursday, 24 June 2021 at 21:05:28 UTC, Bastiaan Veelo wrote:

On Thursday, 24 June 2021 at 20:41:40 UTC, seany wrote:
Is there any way to control the number of CPU cores used in 
parallelization ?


E.g : take 3 cores for the first parallel foreach - and then 
for the second one, take 3 cores each -> so 3 + 3 * 3 = 12 
cores out of a 16 core system? Thank you.


There might be, by using various `TaskPool`s with a smaller 
number of work threads: 
https://dlang.org/phobos/std_parallelism.html#.TaskPool.this.2. 
But I cannot see the benefit of doing this. It will just 
distribute the same amount of work in a different way.


Actually, I think this would be suboptimal as well, as the three 
outer threads seem to do no real work.


— Bastiaan.



Re: How to call stop from parallel foreach

2021-06-24 Thread Bastiaan Veelo via Digitalmars-d-learn

On Thursday, 24 June 2021 at 20:41:40 UTC, seany wrote:

On Thursday, 24 June 2021 at 20:33:00 UTC, Bastiaan Veelo wrote:

By the way, nesting parallel `foreach` does not make much 
sense, as one level already distributes the load across all 
cores (but one). Additional parallelisation will likely just 
add overhead, and have a net negative effect.


— Bastiaan.


Okey. So consider :

foreach(array_elem; parallel(an_array)) {
  dothing(array_elem);
}


and then in `dothing()` :

foreach(subelem; array_elem) {

  dootherthing(subelem);
}

- Will this ALSO cause the same overhead?


You can nest multiple `foreach`, but only parallelise one like so:
```d
foreach(array_elem; parallel(an_array))
  foreach(subelem; array_elem)
  dootherthing(subelem);
```
So there is no need to hide one of them in a function.

Is there any way to control the number of CPU cores used in 
parallelization ?


E.g : take 3 cores for the first parallel foreach - and then 
for the second one, take 3 cores each -> so 3 + 3 * 3 = 12 
cores out of a 16 core system? Thank you.


There might be, by using various `TaskPool`s with a smaller 
number of work threads: 
https://dlang.org/phobos/std_parallelism.html#.TaskPool.this.2. 
But I cannot see the benefit of doing this. It will just 
distribute the same amount of work in a different way.


— Bastiaan.


Re: How to call stop from parallel foreach

2021-06-24 Thread Bastiaan Veelo via Digitalmars-d-learn

On Thursday, 24 June 2021 at 18:23:01 UTC, seany wrote:
I have seen 
[this](https://forum.dlang.org/thread/akhbvvjgeaspmjntz...@forum.dlang.org).


I can't call break form parallel foreach.

Okey, Is there a way to easily call .stop() from such a  case?


Yes there is, but it won’t break the `foreach`:
```d
auto tp = taskPool;
foreach (i, ref e; tp.parallel(a))
{
// …
tp.stop;
}
```
The reason this does not work is because `stop` terminates the 
worker threads as soon as they are finished with their current 
`Task`, but no sooner. `parallel` creates the `Task`s before it 
presents a range to `foreach`, so no new `Task`s are created 
during iteration. Therefore all elements are iterated.



outer: foreach(i, a; parallel(array_of_a)) {
   foreach(j, b; parallel(array_of_b)) {


By the way, nesting parallel `foreach` does not make much sense, 
as one level already distributes the load across all cores (but 
one). Additional parallelisation will likely just add overhead, 
and have a net negative effect.


— Bastiaan.




Re: Financial Library

2021-06-13 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 13 June 2021 at 12:46:29 UTC, Financial Wiz wrote:
What are some of the best Financial Libraries for D? I would 
like to be able to aggregate as much accurate information as 
possible.


Thanks.


I am not into financials, but these libs show up in a search: 
https://code.dlang.org/search?q=Decimal. Perhaps you know some 
other relevant terms to search for.


One of the [sponsors](https://dlang.org/foundation/sponsors.html) 
of dlang is Symmetry Investments, who run a hedge fund. Their use 
of D is pretty advanced, and includes many libs and utilities 
that are not limited to financial applications. These are the 
ones that I know of: https://code.dlang.org/search?q=Mir, 
https://code.dlang.org/packages/dpp, 
https://code.dlang.org/packages/pegged,

https://code.dlang.org/packages/excel-d,
https://github.com/symmetryinvestments.

— Bastiaan.


Re: Inclusion of Parenthesis on Certain Functions

2021-06-13 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 13 June 2021 at 15:45:53 UTC, Justin Choi wrote:
I've tried looking through the documentation but can't find an 
explanation for why you can use it without parenthesis.


https://dlang.org/spec/function.html#optional-parenthesis

(Some exceptions regarding delegates and function pointers exist.)

—Bastiaan


Re: coreutils with D trials, wc, binary vs well formed utf

2021-05-24 Thread Bastiaan Veelo via Digitalmars-d-learn

On Monday, 24 May 2021 at 16:58:33 UTC, btiffin wrote:
[...]
Just bumped into 
https://dlang.org/blog/2020/01/28/wc-in-d-712-characters-without-a-single-branch/


[...]

Is there a(n easy-ish) way to fix up that wc.d source in the 
blog to fallback to byte stream mode when a utf-8 reader fails 
an encoding?


Welcome, Brian.

I have allowed myself to use exception handling and `filter`, 
which I regard to be no longer branch free. But it does (almost) 
produce the same output as gnu wc:

```d
Line toLine(char[] l) pure {
import std.utf : UTFException, byChar;
import std.ascii : isWhite;
import std.algorithm : filter;
try {
return Line(l.byCodePoint.walkLength, 
l.splitter.walkLength);

}
catch (UTFException) {
return Line(l.length, l.byChar.splitter!(isWhite).
  filter!(w => w.length > 
0).walkLength);

}
}
```
The number of chars can be returned in O(0) by the `.length` 
property. Use of `byChar.splitter!(isWhite)` considers the ASCII 
values of the chars, but without the `filter` it counts too many 
words. The reason is that a mix of different white space 
characters causes problems (https://run.dlang.io/is/QzjTN0):

```d
writeln("Hello \t D".splitter!isWhite); // ["Hello", "", "", 
"D"]

writeln("Hello \t D".splitter); // ["Hello", "D"]
```
This surprises me, could be a bug.

So `filter!(w => w.length > 0)` filters out the "words" with zero 
length...


Compared to gnu wc this reports one line too many for me, though.

There may be more elegant solutions than mine.

-- Bastiaan.


Re: Struct initialization extra comma - should it compile

2021-04-25 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 25 April 2021 at 13:39:54 UTC, JN wrote:

struct Foo
{
int x, y, z;
}

void main()
{
 Foo bar = Foo(1,);
}

This compiles without syntax errors, is this expected?


Yes, the 
[specification](https://dlang.org/spec/declaration.html#StructInitializer) is like this:

```
StructMemberInitializers:
StructMemberInitializer
StructMemberInitializer ,
StructMemberInitializer , StructMemberInitializers
```

— Bastiaan.


Re: When should I use SortedRange.release?

2021-04-23 Thread Bastiaan Veelo via Digitalmars-d-learn
On Friday, 23 April 2021 at 21:34:39 UTC, Steven Schveighoffer 
wrote:
`SortedRange` itself is kind of a kludge of "policy" that isn't 
fit for function.


I use release to get the original data type out (via 
r.save.release), but that's about it.


See my rant about it 
[here](https://forum.dlang.org/post/r7ia94$19uo$1...@digitalmars.com)


-Steve


Understood, thanks.

--Bastiaan.


Re: When should I use SortedRange.release?

2021-04-23 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 23 April 2021 at 18:35:25 UTC, Paul Backus wrote:

On Friday, 23 April 2021 at 17:35:13 UTC, Bastiaan Veelo wrote:

What happens when a range is released?
What happens if a range is not released?
What happens if a range is released more than once?

And what does "controlled" imply here? In what way has 
`SortedRange` control over the underlaying data? What can I do 
and what can't I do to the underlying data as long as 
`SortedRange` has control?


I had to look at the source to figure this out. Fortunately, 
the source is pretty simple:


https://phobos.dpldocs.info/source/std.range.d.html#L10833

Turns out, it just calls `core.lifetime.move`. So I guess when 
the docs say "control", what they are really talking about is 
ownership.


Practically speaking, this means that in generic code, we 
should avoid using a `SortedRange` after calling `release`, 
since we do not know whether the range is owning or non-owning 
w.r.t. the underlying data.


Thanks. There is no word in the documentation about when 
`SortedRange` would or would not be owning data, though, and 
hence when `release` would be appropriate to call. To me 
`release` seems to be calling `std.algorithm.mutation.move` , but 
it is probably very similar to `core.lifetime.move`.


In case the underlying data is a slice, I think we end up at 
https://phobos.dpldocs.info/source/std.algorithm.mutation.d.html#L1459, which I can't see accomplishes anything in [this example](https://dlang.org/phobos/std_algorithm_sorting.html#.sort) (except returning the slice that went in):

```d
int[] array = [ 1, 2, 3, 4 ];

// sort in descending order
array.sort!("a > b");
writeln(array); // [4, 3, 2, 1]

// sort in ascending order
array.sort();
writeln(array); // [1, 2, 3, 4]

// sort with reusable comparator and chain
alias myComp = (x, y) => x > y;
writeln(array.sort!(myComp).release); // [4, 3, 2, 1]
```

-- Bastiaan.


When should I use SortedRange.release?

2021-04-23 Thread Bastiaan Veelo via Digitalmars-d-learn
For reference, `SortedRange.release` is 
[documented](https://dlang.org/phobos/std_range.html#.SortedRange) as such:


"Releases the controlled range and returns it."

Wow thanks! I love functions that are named exactly as what they 
do ;-) Seriously though, I still don't know what it is that it 
does, and why and when it should be done, and when not.


What happens when a range is released?
What happens if a range is not released?
What happens if a range is released more than once?

And what does "controlled" imply here? In what way has 
`SortedRange` control over the underlaying data? What can I do 
and what can't I do to the underlying data as long as 
`SortedRange` has control?


My failure to understand this function makes me fear I don't 
understand `SortedRange` at all, and thereby don't understand how 
to use `algorithm.sorting` properly.


Thanks!

-- Bastiaan.


Re: Range Error

2021-04-11 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 11 April 2021 at 19:45:30 UTC, Ruby The Roobster wrote:

What am I doing wrong here? Is it the 'for' loop?


Yes, there is a `7` where there should be an `i` on this line:
```d
   for(int i=7;7>=0;i--)
```
This will go on forever, so you get a range error as soon as `i < 
0`.


—Bastiaan.


Re: Example for Mir-Random fails

2021-04-03 Thread Bastiaan Veelo via Digitalmars-d-learn

On Saturday, 3 April 2021 at 19:02:34 UTC, Brad wrote:
I just do not know enough about the D libraries to figure out 
what is wrong.  I know it is a case of type mismatch.  The 
example appears on the Mir-Random page as listed under DUB:

https://code.dlang.org/packages/mir-random

[...]


I think you are seeing conflicts between Phobos and Mir: they 
both provide unpredictableSeed and Random. If you want to use the 
ones from Mir, be sure to not import std or std.random, or use 
fully qualified names.


— Bastiaan.


Re: C++/D class interop example crashes

2021-03-27 Thread Bastiaan Veelo via Digitalmars-d-learn

On Saturday, 27 March 2021 at 15:09:20 UTC, Jan wrote:

I just tried to get this example to work:
https://dlang.org/spec/cpp_interface.html#using_d_classes_from_cpp

It kept crashing for me with a 'privileged instruction' error 
when the function 'bar' was executed. Finally I removed the 
call to writefln and voilà it finally works.


So why does it fail? I assumed the standard library functions 
should all work.
I'm compiling with "dmd -shared -m64 -debug" and link against a 
C++ DLL that was built with VS2019. Should the D DLL not 
contain everything to be self-sufficient to use it's entire 
runtime functionality?

And if not, what other functions might be problematic?


The example links objects statically. You may be experiencing 
additional challenges with crossing DLL boundaries. I have not 
yet used DLLs, but did you initialise the D runtime?


— Bastiaan.



Re: Contributing CDF bindings to Deimos

2021-03-25 Thread Bastiaan Veelo via Digitalmars-d-learn

On Thursday, 25 March 2021 at 04:00:33 UTC, Chris Piker wrote:
As an aside, software developers at NASA Goddard have now heard 
of D which is nice.  They were pleased to see that it was 
supported by gcc. (Hat tip to the GDC team)


That’s cool. I’d love to see NASA on 
https://dlang.org/orgs-using-d.html one day.


— Bastiaan.


Re: Why are enums with base type string not considered strings?

2021-03-14 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 14 March 2021 at 16:09:39 UTC, Imperatorn wrote:

On Sunday, 14 March 2021 at 10:42:17 UTC, wolframw wrote:

enum BoolEnum   : bool   { TestBool   = false }
enum CharEnum   : char   { TestChar   = 'A' }
enum StringEnum : string { TestString = "Hello" }

pragma(msg, isBoolean!BoolEnum);   // true
pragma(msg, isSomeChar!CharEnum);  // true
pragma(msg, isSomeString!StringEnum);  // false

Why does isSomeString not return true for an enum with base 
type string


May be a regression?

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


Indeed: https://run.dlang.io/is/liSDBZ

It regressed in 2.079.1. Seems to be worth an issue report.

—Bastiaan.


Re: Dlang spec

2021-03-13 Thread Bastiaan Veelo via Digitalmars-d-learn

On Thursday, 11 March 2021 at 19:38:01 UTC, Imperatorn wrote:
I created some PDFs (on request) of the dlang spec mobi-file 
and uploaded them here:

https://gofile.io/d/ijctZt

Different converters were used, hence multiple files.

Maybe someone can upload a good version on dlang.org and link 
to it?


The spec is written in ddoc format, and I thought that ddoc was 
able to output in PDF (at least at one point). It didn’t look 
very good and I’m not sure if the functionality is still there. I 
was only able to find an old initiative [1] and two old threads 
discussing the idea [2][3]. I didn’t read all that now.


Regarding uploading, the way this usually goes is that you submit 
a PR against the website. But I’m not sure it will be accepted if 
the process cannot be automated so that the PDFs stay in sync 
with any future changes in the spec without manual intervention.


In my opinion the way to produce quality PDF is through LaTeX. 
Maybe something can be based on adrdox to produce useful LaTeX, 
that would be an interesting project.


— Bastiaan.

[1] https://forum.dlang.org/post/dhq4k6$12tp$1...@digitaldaemon.com
[2] https://forum.dlang.org/post/i9fco2$i05$1...@digitalmars.com
[3] https://forum.dlang.org/post/kc883a$1b8p$1...@digitalmars.com


Re: D's Continous Changing

2021-03-04 Thread Bastiaan Veelo via Digitalmars-d-learn

On Wednesday, 3 March 2021 at 23:30:20 UTC, harakim wrote:
Contrast to me trying to figure out how to format a number in 
binary. format!"%b"(number) does not work but is very similar 
to what is suggested in the documentation. I was able to figure 
out it's format("%b", number) but it took a few minutes.


This works for me:
 rdmd --eval="writeln(format!`%b`(5));"
 101
 rdmd --eval="writeln(__VERSION__);"
 2096

-- Bastiaan.


Re: D's Continous Changing

2021-03-04 Thread Bastiaan Veelo via Digitalmars-d-learn

On Wednesday, 3 March 2021 at 23:30:20 UTC, harakim wrote:
Every time I come back to a D program I wrote over a year ago, 
it seems like there are numerous breaking changes and it takes 
me a while to get it to compile again.


I am porting a large code base from Extended Pascal to D and I 
know that there will be changes in the language in the future 
that will take an effort to adapt to. Yet, I am still in the camp 
of wanting these changes to happen because we don't want to port 
from a dead language to another dead language, we need the 
language to be alive.


The way I deal with this is to lock down version numbers with the 
revision number of our code base. By having dub.selections.json 
under revision control we make sure that the same version of 
dependencies are used every time until we upgrade, and by having 
this in dub.json:


```
"toolchainRequirements": {
"frontend": "==2.096"
},
```

we ensure that the code simply refuses to compile with any other 
language version.


So, if two years from now we were to check out a revision that 
was two years old, yes we would have to downgrade the compiler 
but it would still work. Upgrading to a newer language version or 
dependency version can be done outside of the main development 
branch, where it can be properly tested before merging.


Ideally I want the build system to automatically install and/or 
activate the compiler specified in the code base so that a 
toolchain upgrade becomes just like a regular feature commit, 
possibly using one of the existing compiler version managers [1, 
2] or by extending dub itself. Then, fellow developers will 
hardly notice compiler upgrades, the build farm doesn't need 
attention, and bisecting revisions to pin down the occurrence of 
a regression can be done without complications.


I think it is important that warts in the language and standard 
library are removed, and luckily we have a proper deprecation 
mechanism. My advice is, if you pick up a two-year old project 
and don't want to deal with breakages, you just continue with the 
versions from that time; Until you choose to use newer features, 
but you can plan for the work that this requires.


-- Bastiaan.

[1] https://dlang.org/install.html
[2] https://code.dlang.org/packages/dvm


Re: Minimize GC memory footprint

2021-02-05 Thread Bastiaan Veelo via Digitalmars-d-learn

On Wednesday, 3 February 2021 at 13:37:42 UTC, frame wrote:
I have to deal with GC as long I want to use other libraries 
that are relying on it or even just phobos.


Conclusion so far (for Windows):

32bit:
- GC just doesn't work at all


?? Do you mean no collections happen? 32bit GC should just work.


64bit:
- Collections are rare. It can be necessary to call 
GC.collect() manually.
- Scope guards to explicit clean up / free memory at function 
exit have no deep impact on most cases.
- If your application should save memory call GC.minimize() 
when it's appropriate.



It seems that calling GC.enable() if it's already enabled just 
disables the automatic GC again? Is this a bug? I cannot 
reproduce it outside my application yet since it's not clear 
when the GC starts collecting, but it always shows the same 
behaviour:



// GC.enable();

Case A: The app is very kind in memory usage (~20 MB)


GC.enable();

Case B: The app is consuming huge amount of memory (~900 MB)


GC.disable();
GC.enable();

Case A again


GC.disable();
GC.enable();
GC.enable();

Case B again


That looks like a bug indeed.


I also have to struggle what the specs' text actually mean:

This function is reentrant, and must be called once for every 
call to disable before automatic collections are enabled.


I think it means that you need to make sure that enable() is 
called as many times as disable() is called before collection can 
happen automatically.


— Bastiaan.


Re: Using the Standard Library with C++ Interop

2021-02-05 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 5 February 2021 at 21:40:29 UTC, wolfiesnotfine wrote:
In any case, I'm unsure how I would runtime init from C++. Is 
there a specific function I should call?


https://dlang.org/phobos/core_runtime.html#.rt_init

Could this be done at compile time in a consteval or constexpr 
function?


This being the runtime, I presume it should be called at run time 
:-) I haven’t used it, but searching for rt_init should give you 
some pointers.


—Bastiaan



Re: writeln and write at CTFE

2021-01-13 Thread Bastiaan Veelo via Digitalmars-d-learn
On Wednesday, 13 January 2021 at 09:11:53 UTC, Guillaume Piolat 
wrote:

On Wednesday, 13 January 2021 at 08:35:09 UTC, Andrey wrote:

Hello all,
Tell me please how can I "writeln" and "write" in function 
that is used in CTFE?

At the moment I get this:
import\std\stdio.d(4952,5): Error: variable impl cannot be 
modified at compile time


Or may be exist some other ways to do it?


pragma(msg, );


This may however not do what you wish it to do: 
https://forum.dlang.org/post/mailman.4526.1499573493.31550.digitalmars-d-le...@puremagic.com


— Bastiaan.


Re: Using a betterC dub package in ordinary D

2021-01-08 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 8 January 2021 at 18:28:36 UTC, Ferhat Kurtulmuş wrote:

On Friday, 8 January 2021 at 15:40:12 UTC, Bastiaan Veelo wrote:

Hi,

When I use earcutd [1] in an ordinary D project, I get a link 
error for the __D7earcutd12__ModuleInfoZ symbol.

[...]


Dear Bastiaan,

I am not an expert in dub system, but I have just pushed a 
modification in dub.json. I am not sure if it solves your 
problem. My modification is


"configurations": [
{
"name": "default",
"targetType": "library"
},
{
"name": "betterC",
"targetType": "library",
"dflags": ["-betterC"]
}
]

now client projects must explicitly pass the subConfiguration 
parameter to compile it with betterC.


Much appreciated Ferhat! This works like a charm. I am kind of 
surprised that it does, as I expected dvector to need the same 
treatment. Excellent support by the way, thanks!


Off topick, the original js implementation is documented to not 
generate results that are guaranteed to be correct. I could not 
find information on what the conditions are that cause 
deviations, and how large these then can be. Do you have an idea 
about this or experience with accuracy of the algorithm? I am 
looking into whether earcutd can replace GLU tesselation. We use 
the result for engineering purposes (not only visualisation) and 
correctness is important to us.


Thanks!
Bastiaan.


Using a betterC dub package in ordinary D

2021-01-08 Thread Bastiaan Veelo via Digitalmars-d-learn

Hi,

When I use earcutd [1] in an ordinary D project, I get a link 
error for the __D7earcutd12__ModuleInfoZ symbol. This is because 
the earcutd dub.json has `"dflags": ["-betterC"]`. I think this 
is in error, my understanding of betterC code is that it can be 
compiled with "-betterC", but does not need to (and must not when 
used in D context).


Am I right? What are the best practices for betterC dub packages?

Thanks,
Bastiaan.


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


Re: Writing a really fast lexer

2020-12-12 Thread Bastiaan Veelo via Digitalmars-d-learn

On Saturday, 12 December 2020 at 18:15:11 UTC, vnr wrote:
On Saturday, 12 December 2020 at 16:43:43 UTC, Bastiaan Veelo 
wrote:
Have you looked at Pegged [1]? It will give you the lexer and 
parser in one go. I'd be very interested to see how it 
performs on that kind of input.


-- Bastiaan.

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


Yes, I know Pegged, it's a really interesting parser generator 
engine, nevertheless, the grammar of what I would like to 
analyse is not a PEG. But I am also curious to know the 
performances of this tool for very large inputs.


Are you able to share the grammar? Since you plan to parse using 
recursive descent, I think there is a good chance that the 
language can be defined as a PEG. I am using it to parse Pascal, 
whose grammar was defined long before PEG was a thing.


— Bastiaan.


Re: Writing a really fast lexer

2020-12-12 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 11 December 2020 at 19:49:12 UTC, vnr wrote:
For a project with good performance, I would need to be able to 
analyse text. To do so, I would write a parser by hand using 
the recursive descent algorithm, based on a stream of tokens. I 
started writing a lexer with the d-lex package 
(https://code.dlang.org/packages/d-lex), it works really well, 
unfortunately, it's quite slow for the number of lines I'm 
aiming to analyse (I did a test, for a million lines, it lasted 
about 3 minutes). As the parser will only have to manipulate 
tokens, I think that the performance of the lexer will be more 
important to consider. Therefore, I wonder what resources there 
are, in D, for writing an efficient lexer.


Have you looked at Pegged [1]? It will give you the lexer and 
parser in one go. I'd be very interested to see how it performs 
on that kind of input.


-- Bastiaan.

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



Re: Pass enum variable as const ref arg

2020-12-04 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 4 December 2020 at 12:54:25 UTC, Andrey wrote:

Hello,


void test(const ref string[3] qazzz) { qazzz.writeln; }

void main()
{
enum string[3] value = ["qwer", "ggg", "v"];
test(value);
}


Gives errors:


It works if you pass `-preview=rvaluerefparam` to the compiler.

But the other suggestions are better IMO.

—Bastiaan.


Re: Is garbage detection a thing?

2020-11-29 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 29 November 2020 at 16:05:04 UTC, Mark wrote:

Hi,

can I ask you something in general? I don't know anyone whom I 
could ask. I'm a hobbyist with no science degree or job in 
computing, and also know no other programmers.


I have no good understanding why "garbage collection" is a big 
thing and why "garbage detection" is no thing (I think so).


In order to detect garbage, you need extensive run-time 
instrumentation, the difficulties of which you have indicated 
yourself. In addition comes that detection depends on 
circumstance, which is an argument against the debug/release 
strategy you proposed. There is no guarantee that you’ll find all 
problems in the debug build. Garbage collection also comes at a 
runtime cost, but strategies exist to minimise those, and in 
addition a GC enables valuable language features. One such 
strategy is to minimise allocations, which improves performance 
in any memory management scheme.


[...]
What I don't understand is, when today there exist tools for 
C++ (allocator APIs for debugging purposes, or 
Address-Sanitizer or maybe also MPX) to just detect that your 
program tried to use a memory address that was actually freed 
and invalidated,


why did Java and other languages not stop there but also made a 
system that keeps every address alive as long as it is used?


Elimination of memory problems is much more valuable than 
detection. Recovering from memory errors at run time is 
unreliable.


One very minor criticism that I have is: With GC there can be 
"semantically old data" (a problematic term, sorry) which is 
still alive and valid, and the language gives me the feeling 
that it is a nice system that way. But the overall behavior 
isn't necessarily very correct, it's just that it is much 
better than a corrupted heap which could lead to everything 
possibly crashing soon.


At least in D, you can avoid old data to hang around for too 
long. See core.memory.


Or maybe I could use the safe-c subset in D? But I believe it 
uses garbage collection. I know nothing about it, sorry.


@safe D is not a sub-set, indeed it uses garbage collection. Fact 
is that there are very few domains where this is a problem. Not 
all garbage collectors are equal either, so if you think garbage 
collection is bad in one language, this may not directly apply in 
another. In D the garbage collector is even pluggable, various 
implantations exist. Have you seen the GC category on the 
blog?https://dlang.org/blog/2017/03/20/dont-fear-the-reaper/


BetterC is a subset of D, it does not use garbage collection.

You may be interested in current work being done in static 
analysis of manual memory management in D: 
https://youtu.be/XQHAIglE9CU


The advantage of D is that all options are open. This allows the 
following approach:
1) Start development without worrying about memory. Should 
collection cycles be noticeable:
2) Profile your program and make strategic optimisations 
https://youtu.be/dRORNQIB2wA. If this is not enough:
3) Force explicit collection in idle moments. If you need to go 
further:
4) Completely eliminate collection in hot loops using @nogc 
and/or GC.disable. When even this is not enough:

5) Try another GC implementation. And if you really need to:
6) Switch to manual memory management where it matters.

This makes starting a project in D a safe choice, in multiple 
meanings of the word.


— Bastiaan.


Re: Can't pass [] to extern function object method

2020-11-18 Thread Bastiaan Veelo via Digitalmars-d-learn

On Wednesday, 18 November 2020 at 10:50:12 UTC, frame wrote:
I found the "bug". It was caused by a debug {} statement within 
a struct method. I assume that the debug symbol is just 
incompatible called from the DLL context.


Were the DLL and main program built in different modes 
(debug/release)? Then this problem is understandable. Otherwise I 
find this surprising, and probably worth a bug report?


— Bastiaan.


Re: How can execute method in new Thread?

2020-11-15 Thread Bastiaan Veelo via Digitalmars-d-learn

On Saturday, 14 November 2020 at 17:21:15 UTC, Marcone wrote:
Error: 
D:\dmd2\windows\bin\..\..\src\phobos\std\parallelism.d(516): 
Error: struct `Fruit` does not overload ()


I think you need to pass the this pointer somehow. This works:


import std;

struct Fruit {
string name;

static void printmyname(Fruit thisFruit)
{
writeln(thisFruit.name);
}

void showname()
{
 task!printmyname(this).executeInNewThread;
}
}


void main()
{
Fruit f = Fruit("Banana");
f.showname();
}


This does too:


import std;

struct Fruit
{
string name;

void printmyname()
{
writeln(name);
}

void showname()
{
task!((Fruit 
me){me.printmyname;})(this).executeInNewThread;

}
}


void main()
{
Fruit f = Fruit("Banana");
f.showname();
}


—Bastiaan.


Re: App hangs, GC.collect() fixet it. Why?

2020-09-29 Thread Bastiaan Veelo via Digitalmars-d-learn
On Monday, 28 September 2020 at 21:58:31 UTC, Steven 
Schveighoffer wrote:

On 9/28/20 3:28 PM, Bastiaan Veelo wrote:
I’m leaning towards ditching the memory mapped I/O on the D 
end, and replace it by regular serialisation/deserialisation. 
That will be a manual rewrite though, which is a bit of bummer 
as memory mapped files are widely used in our Pascal code. But 
this will probably give the best end result.


2 things:

1. I agree this is the answer. If you ever ditch the old Pascal 
code, then you can reactivate the memory-mapped code.
2. You can possibly do the translation outside of your 
programs. That is, it wouldn't be entirely impossible to simply 
have a process running that ensures the "D view" and the 
"Pascal view" of the same file is kept in sync. Then you can 
keep the memory mapped code the same, and just define sane 
structures in your D code.


If you aren't required to have both Pascal and D programs 
reading and writing the file at the same time, this shouldn't 
be a problem.


There is no need to run both versions concurrently. The issue is 
that design offices typically maintain a library of past designs 
for as long as they are in existence, to build new designs off 
of. So being able to read or import the files that were written 
with an ancient version of our software is very valuable. Our old 
compiler offered two alternatives for file i/o: one where all 
elements are of the same type, the other one (memory mapped 
files) being the "only" option for files of mixed type. Ideally, 
the structs that are used for i/o do not have any pointers in 
them, and certainly in the more recent file versions that would 
be the case. In older versions that might not be the case; then 
the pointers obviously would be given meaningful values after the 
structs would have been read back in. These cases we would be 
able to work around, though, by converting the old structs to new 
ones upon import.


BTW, one further thing I don't understand -- if this is memory 
mapped data, how come it has issues with the GC? And what do 
the "pointers" mean in the memory mapped data? I'm sure there's 
good answers, and your actual code is more complex than the 
simple example, but I'm just curious.


The main problem is that the transpiler doesn't know which 
structs are used for i/o and would need 1-byte alignment, and 
which structs have pointers into GC memory and must not be 1-byte 
aligned. The alternative to switching to 
serialisation/deserialisation is to stay with the automated 
translation of the memory mapped file implementation, not 
automatically 1-byte align every struct but manually align the 
ones that are used in i/o. This is however sensitive to mistakes, 
and the translated mmfile implementation has a bit of a smell to 
it. It is also not portable, as it uses the WinAPI directly. 
Still, it may be the quickest route to get us back on track.


I am very glad to have identified the problem, and there being 
ways to deal with it. I just hope this will be the last big 
hurdle :-)


-Bastiaan.


Re: App hangs, GC.collect() fixet it. Why?

2020-09-28 Thread Bastiaan Veelo via Digitalmars-d-learn
On Monday, 28 September 2020 at 15:44:44 UTC, Steven 
Schveighoffer wrote:

On 9/28/20 8:57 AM, Bastiaan Veelo wrote:

I am glad to have found the cause of the breakage finally, but 
it won't be easy to find a generic solution...


Obviously, this isn't a real piece of code, but there is no way 
around this. You have to align your pointers. The other option 
is to not use the GC and use manual memory management.


If this is a compatibility thing between D and Pascal, and you 
absolutely have to have the same layout, is there a way to 
adjust the structure in Pascal? Like put the elements that 
misalign the pointers at the end of the structure?


Another totally drastic approach would be to supply your own 
even-more-conservative GC which will scan misaligned pointers. 
Probably going to hurt performance quite a bit. You might be 
able to get away with marking only certain blocks as having 
misaligned pointers, but you will have to scan all the stacks 
with this assumption.


Some more information about the setup you are using might help 
(I'm assuming D and Pascal are using the same memory in the 
same process, otherwise this wouldn't be a problem). In 
particular, where does the data come from, and how malleable is 
it in your system? Are there times where references to the D 
data only exist in Pascal?


-Steve


Thanks a lot for thinking with me. I’m not linking any Pascal 
objects, so I don’t need to maintain binary compatibility in 
memory; Only compatibility of data files. The problem arises when 
those files are read using memory mapped files, from which 
structs are memcpy’d over. This is of course the result of 
machine translation of the current Pascal implementation.


Manual memory management is an option and would be 
straightforward in principle, as we’ve done that for ages. The 
only thing is that this memory cannot contain other allocations 
on the GC heap, such as strings or other slices, unless they are 
both aligned and their root is registered.


Fixing the alignment in Pascal is possible in principle, but any 
old files would then need to first be processed by the last 
Pascal version of the programs, which we then would need to keep 
around indefinitely. There would also be issues when we port from 
32 bit to 64 bit.


Another option could be to use 1-byte aligned structs for I/O, 
and copy the members over in default aligned versions. But this 
cannot be part of the automated transcompilation.


Thanks for suggesting a custom gc, which I had not thought of.

I’m leaning towards ditching the memory mapped I/O on the D end, 
and replace it by regular serialisation/deserialisation. That 
will be a manual rewrite though, which is a bit of bummer as 
memory mapped files are widely used in our Pascal code. But this 
will probably give the best end result.


-Bastiaan.


Re: App hangs, GC.collect() fixet it. Why?

2020-09-28 Thread Bastiaan Veelo via Digitalmars-d-learn
On Friday, 5 June 2020 at 21:20:09 UTC, Steven Schveighoffer 
wrote:
This kind of sounds like a codegen bug, a race condition, or 
(worst case) memory corruption.


I think it must have been memory corruption: I had not realized 
that our old Pascal compiler aligns struct members on one byte 
boundaries, and also uses ubyte as the base type for enumerations 
(or ushort if required) instead of uint. When using memory mapped 
files this binary incompatibility likely caused the corruption.


But, after correcting that mistake, suddenly things broke that 
had been working for a long time. Having no idea what could be 
wrong this time, I spent quite some time dustmiting (thanks 
Vladimir!) and manually reducing the code. Voilà:



import std.stdio;
import core.memory;

struct Nothing
{
}

struct Info
{
align(1):
  ubyte u;
  Nothing*[2] arr;
}

Info* info;

void main()
{
  info = new Info;
  writeln("1");
  GC.collect();
  info.arr[0] = new Nothing;
  writeln("2");
  GC.collect();
  info.arr[1] = new Nothing;
  writeln("info.arr[0]  = ", info.arr[0]);
  writeln("info.arr[1]  = ", info.arr[1]);
  assert(info.arr[0] != info.arr[1], "Live object was 
collected!");

}


(The assert triggers on Windows, not on run.dlang.org.) 
Unfortunately for me, I cannot blame this on the compiler. It 
violates the requirements from the spec:


  "Do not misalign pointers if those pointers may point into the 
GC heap" (https://dlang.org/spec/garbage.html)


I am glad to have found the cause of the breakage finally, but it 
won't be easy to find a generic solution...


-Bastiaan.


Re: Why Pegged action dont not work in this case ?

2020-06-11 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 19 April 2020 at 16:47:06 UTC, Basile B. wrote:
I 've started experimenting Pegged action. Quickly i got 
blocked by this problem. The start action works where I use the 
rule but not directly in the rule.


I don't understand the difference between how you use "where" and 
"directly in".


Note that semantic actions are executed during the parsing 
process, even in branches that eventually fail, before the parser 
back tracks. They are not a substitute for traversing the final 
parse tree, rather, they are a method for manipulating the 
parsing process as it happens.


That's why `endResultRecord` is executed directly after `(',' 
Result)*` succeeds, and `beginResultRecord` is executed directly 
after `ResultRecord` succeeds (even if `'(gdb)'` would not match).



Test program:

[...]
ResultRecord< {beginResultRecord} Token? '^' 
ResultClass (',' Result)* {endResultRecord}


Remove the space between "<" and "{", then it works.

Also I'd like to report that actions dont work with partially 
specialized templates:


---
T handleResultRecord(bool end,  T)(T t);
// then you use handleResultRecord!true and 
handleResultRecord!false in the PEG.

---


That fails for the same reason as `handleResultRecord!true(1)` 
fails to instantiate.


-- Bastiaan.


App hangs, GC.collect() fixet it. Why?

2020-06-05 Thread Bastiaan Veelo via Digitalmars-d-learn
I've been tracking down a hang in our pilot app. Using writeln, 
it appears to hang at newing a slice. After many hours of trying 
things, I discovered that program flow would continue past that 
point when I inserted a call to `GC.collect()` just before. Then 
it stalled again at a call to Win32 `SetMenu()`. Again, inserting 
`GC.collect()` before that made the problem go away.


This band-aid isn't going to scale in the long run. I feel I'm 
treating symptoms, and wonder what the cause is. Any ideas?


I know the GC is not disabled somehow because if I print 
`GC.profileStats()`, I see that there are collections even 
without my explicit calls to `GC.collect()`.


Thanks,

Bastiaan.


Re: Postblit segfault.

2020-06-01 Thread Bastiaan Veelo via Digitalmars-d-learn

On Monday, 1 June 2020 at 09:42:44 UTC, Boris Carvajal wrote:

On Monday, 1 June 2020 at 06:35:36 UTC, MaoKo wrote:

Hello, I don't understand why this code segfault on


Reduced to:

import std.stdio;

struct S {}

void main() {
  S[1] s;
  writeln(s);
}


This used to work up to dmd 2.084.1. It fails since 2.085.1. 
Please file a regression report at 
https://issues.dlang.org/enter_bug.cgi?product=D


— Bastiaan.


Re: CT BitArray

2020-04-02 Thread Bastiaan Veelo via Digitalmars-d-learn
On Thursday, 1 November 2018 at 08:50:38 UTC, Bastiaan Veelo 
wrote:

On Thursday, 1 November 2018 at 00:01:04 UTC, Stefan Koch wrote:
On Wednesday, 31 October 2018 at 23:14:08 UTC, Bastiaan Veelo 
wrote:
Currently, BitArray is not usable at compile time, so you 
cannot do

```
enum e = BitArray([1, 1, 1, 0]);
```
This gives

/dlang/dmd/linux/bin64/../../src/phobos/std/bitmanip.d(1190): Error: `bts` 
cannot be interpreted at compile time, because it has no available source code


[]


meanwhile use module level BitArrays like
```
immutable BitArray e;
static this()
{
e = BitArray([1, 1, 1, 0]);
}
```


Note to self: when this occurs, the above error message does not 
offer a trace to the place where this originates. To get that, 
temporarily insert the following at the indicated line in 
bitmanip.d:

```
if(__ctfe) assert(false, "trap");
```

--Bastiaan.


Re: New with alias

2020-03-10 Thread Bastiaan Veelo via Digitalmars-d-learn

On Tuesday, 10 March 2020 at 06:09:23 UTC, tcak wrote:

I write a code as below:

auto result = new char[4];

It allocates memory as expected.


This is a slice of four chars, which can be used as a dynamic 
array.



Later I define an alias and do the above step:

alias Pattern = char[4];


This is an alias for a static array with a fixed length of four 
chars.



auto result = new Pattern;

But compiler says:
Error: new can only create structs, dynamic arrays or class 
objects, not `char[4]`'s


Is this a bug, or `alias` doesn't work how I was thinking?


It is not a bug. You cannot new static arrays. You can do this, 
though:


Pattern pattern; // One static array of four chars.
auto patterns = new Pattern[3]; // A slice with three static 
arrays of four chars.



--Bastiaan.



Re: Specify dmd or ldc compiler and version in a json dub file?

2020-01-20 Thread Bastiaan Veelo via Digitalmars-d-learn

On Tuesday, 8 August 2017 at 09:17:02 UTC, data pulverizer wrote:
I would like to know how to specify dmd or ldc compiler and 
version in a json dub file.


Update: you can at least specify these in the toolchain 
requirements section: 
https://dub.pm/package-format-json.html#toolchain-requirements


I myself am looking for ways to satisfy these automatically, 
using a tool like dvm (https://code.dlang.org/packages/dvm) in 
preBuildCommands.


Bastiaan.


Re: Slice/Substr [0..?lastIndexOf(".")] How refer itself without create a variable?

2019-12-05 Thread Bastiaan Veelo via Digitalmars-d-learn

On Thursday, 5 December 2019 at 11:28:51 UTC, Marcone wrote:

Simple example:

writeln("Hi\nHow are 
you?\nGood".splitLines()[0][0..?lastIndexOf(r"\")]);


How to refer to this string in lastIndexOf() without create a 
variable?


Thank you.


.splitLines[0] already just produces "Hi", containing no "\", so 
this example is a bit broken.


  writeln("#", "Hi\nHow are you?\nGood".splitLines()[0], "#"); // 
#Hi#


You could write a function to work around having to declare a 
variable:


  string upto(string input, string delim)
  {
  return input[0 .. input.countUntil(delim)];
  }

  void main()
  {
  writeln(upto("Up to colon: skip this", ":")); // Up to colon
  writeln("Up to colon: skip this".upto(":")); // Up to colon
  }

You can use a function literal or lambda, but it isn't pretty:

  writeln((string s){return s[0..s.countUntil(":")];}("Up to 
colon: skip this")); // Up to colon
  writeln((s => s[0..s.countUntil(":")])("Up to colon: skip 
this")); // Up to colon


Bastiaan.


Re: const and immutable values, D vs C++?

2019-12-04 Thread Bastiaan Veelo via Digitalmars-d-learn
On Wednesday, 4 December 2019 at 14:44:43 UTC, Ola Fosheim 
Grøstad wrote:
When is there a noticable difference when using const values 
instead of immutable values in a function body? And when should 
immutable be used instead of const?


f(){
  const x = g();
  immutable y = g();
  ... do stuff with x and y …
}


There is a difference I guess if g() returns a reference type and 
is an inout function. immutable y will only work if the reference 
returned is immutable.


Const is a promise to the rest of the code that you will never 
mutate it. Immutable is a promise by the rest of the code that it 
will never mutate.


Immutable is more powerful, allowing data sharing in overlapping 
slices and between threads without locks. Const is more 
versatile, allowing references to data regardless of its 
mutability.


So if g() always returns immutable, it’s best to receive it as 
such, not const. If it can be either, it must be received as 
const.



I'm comparing D to C++ and I get the following mapping:


Does that make sense at all? D’s const is transitive, C++’s is 
not.


Bastiaan.



Re: Unexpected aliasing

2019-11-12 Thread Bastiaan Veelo via Digitalmars-d-learn

On Tuesday, 12 November 2019 at 08:15:20 UTC, Basile B. wrote:


I'm curious to know what is the equivalent in Pascal that your 
transpiler fails to translate since Pascal records don't have 
constructors at all. Maybe you used an old school 'Object' ?


Note that Extended Pascal is not exactly Pascal. An example:

  TYPE Ints(upperBound) = ARRAY [1 .. upperBound] of Integer;
   MyRecord = RECORD
  integers : Ints(5);
  END;
   SchematicRecord(num) = RECORD
  integers : Ints(num);
  END;
   IntsPtr = ^Ints;

  PROCEDURE myProcedure(PROTECTED VAR someArr : Ints);
  BEGIN
  writeln(someArr.upperBound);
  END;

  PROCEDURE proc;
  VAR dynamicInts : IntsPtr;
  rec : MyRecord;
  BEGIN
  dynamicInts = new(10);
  myProcedure(dynamicInts^);
  myProcedure(rec.integers);
  END;

In this case, only the upper bound of Ints is parameterized, but 
the lower bound could be parameterized as well. Records can also 
be schematized. Procedure arguments can take schemas that are 
undiscriminated, they carry their schemaparameters as properties.


Bastiaan.


Re: Unexpected aliasing

2019-11-12 Thread Bastiaan Veelo via Digitalmars-d-learn
On Monday, 11 November 2019 at 21:52:12 UTC, Jonathan M Davis 
wrote:
On Monday, November 11, 2019 12:17:37 PM MST Bastiaan Veelo via 
Digitalmars- d-learn wrote:


[...]

I could use some help in rewriting the code below so that arr1 
and arr2 each have their own data; ideally with minimal 
changes so that I can make the transcompiler do the right 
thing.


Thanks!
Bastiaan.

void main()
{
  import std.stdio;

  WrapIntegerArray arr1;
  arr1[0] = 42;

  WrapIntegerArray arr2;

  writeln(arr2[0]); // 42, not 0.
  writeln("arr1.wrap.arr.ptr = ", arr1.wrap.arr.ptr);
  writeln("arr2.wrap.arr.ptr = ", arr2.wrap.arr.ptr); // 
identical

  assert(arr2[0] == 0); // fails
}

struct IntegerArray
{
  int[] arr;
  alias arr this;
  this(int l)
  {
  arr = new int[l];
  }
}

struct WrapIntegerArray
{
  auto wrap = IntegerArray(5); // This is CTFE! :-(
  alias wrap this;
}


All struct and class members which are directly initialized 
must have their values known at compile-time. For structs, 
that's what goes in the init value for the type. A side effect 
of this is that it's usually a bad idea to directly initialize 
dynamic arrays which are member variables. You need to do the 
initialization in a constructor. And for structs, if you need a 
no-arg constructor, then you'll need to use a factory function 
(since structs can't have no-arg constructors). e.g.


struct WrapIntegerArray
{
IntegerArray wrap;
alias wrap this;

this(int len)
{
wrap = IntegerArray(len);
}
}

or

struct WrapIntegerArray
{
IntegerArray wrap;
alias wrap this;

static make()
{
WrapIntegerArray retval;
retval.wrap = IntegerArray(5);
return retval;
}
}

So, you could then have something like

auto arr1 = WrapIntegerArray(5);
arr1[0] = 42;

or

auto arr1 = WrapIntegerArray.make();
arr1[0] = 42;

but if you use the init value (which is what you get if you let 
the type be default-initialized), then you'll have to first do 
something to allocate the dynamic array if you want to be able 
to index it, since if you don't give it a value at 
compile-time, it's null (and you don't want to give it a value 
at compile-time, because then every default-initialized struct 
of that type will refer to the same dynamic array). Of course, 
you could always just append values, and the dynamic array will 
be allocated and grow accordingly, but that's obviously not the 
same as allocating it up front to have a specific length.


- Jonathan M Davis


Thank you Jonathan. A factory function seems to be what I need, 
then. It'll be an interesting challenge to have my transpiler 
detect when a factory function is needed, and making sure that 
they are called at the right places. But this might escalate 
since structs can have members that are structs that have a 
factory function. So the enclosing struct also needs a factory 
function. And so forth.


My problem is the translation of so called schematic arrays, a 
type that I have only seen in Extended Pascal. A schematic array 
is a type in which the length of the array is a parameter of the 
type. Extended Pascal does not have dynamic arrays, so schematic 
arrays are its attempt at improving a bit on just plain static 
arrays. The length parameter can be constant, in which it behaves 
akin to templates (which it doesn't have either), but it can also 
be set at run time during initialization (so I can't translate it 
to a template).


Maybe I can omit the translation of schematic arrays 
(IntegerArray in this case) altogether and instead detect where 
and how they are instantiated. Then replace them with a static 
array whenever the length is known at compile time, and a dynamic 
array otherwise. A static array is not nice, but at least they 
can be members of structs without a factory function. Either way, 
my transpiler needs to smarten up...


Bastiaan.


Re: Unexpected aliasing

2019-11-12 Thread Bastiaan Veelo via Digitalmars-d-learn

On Monday, 11 November 2019 at 20:05:11 UTC, Antonio Corbi wrote:
Defining and using a constructor for WrapIntegerArray seems to 
work:


void main()
{
import std.stdio;

WrapIntegerArray arr1 = WrapIntegerArray(5);
arr1[0] = 42;

WrapIntegerArray arr2 = WrapIntegerArray(5);

writeln(arr2[0]); // 42, not 0.
writeln("arr1.wrap.arr.ptr = ", arr1.wrap.arr.ptr);
	writeln("arr2.wrap.arr.ptr = ", arr2.wrap.arr.ptr); // 
identical

assert(arr2[0] == 0); // fails
}

struct IntegerArray
{
int[] arr;
alias arr this;
this(int l)
{
arr = new int[l];
}
}

struct WrapIntegerArray
{
this (int v) {
  wrap = IntegerArray(5);
}

IntegerArray wrap;
alias wrap this;
}

Hope this helps.
Antonio


Thanks, Antonio. My problem is that the length of the array 
should be a built-in property of WrapIntegerArray (immutable in 
this case); what I'd actually want is a constructor without 
arguments. Jonathan's suggestion of using a factory function 
comes closest to that.


Bastiaan.


Unexpected aliasing

2019-11-11 Thread Bastiaan Veelo via Digitalmars-d-learn
Recently I got my first surprise with our use of D. The symptom 
was that two local variables in two different functions appeared 
to be sharing data.


A simplified example is shown below (the original was machine 
translated from Pascal and involved templates and various levels 
of indirection). What I did not know is that the initial value of 
struct members is a compile time feature, apparently. What I 
suspect is happening is that the array lives in the static data 
segment (or is created in the module constructor?) and that the 
slices inside arr1 and arr2 get initialised to point to that same 
array.


I could use some help in rewriting the code below so that arr1 
and arr2 each have their own data; ideally with minimal changes 
so that I can make the transcompiler do the right thing.


Thanks!
Bastiaan.

void main()
{
import std.stdio;

WrapIntegerArray arr1;
arr1[0] = 42;

WrapIntegerArray arr2;

writeln(arr2[0]); // 42, not 0.
writeln("arr1.wrap.arr.ptr = ", arr1.wrap.arr.ptr);
writeln("arr2.wrap.arr.ptr = ", arr2.wrap.arr.ptr); // identical
assert(arr2[0] == 0); // fails
}

struct IntegerArray
{
int[] arr;
alias arr this;
this(int l)
{
arr = new int[l];
}
}

struct WrapIntegerArray
{
auto wrap = IntegerArray(5); // This is CTFE! :-(
alias wrap this;
}



Re: Saving and loading large data sets easily and efficiently

2019-10-03 Thread Bastiaan Veelo via Digitalmars-d-learn

On Monday, 30 September 2019 at 20:10:21 UTC, Brett wrote:
[...]
The way the data is structured is that I have a master array of 
non-ptr structs.


E.g.,

S[] Data;
S*[] OtherStuff;

then every pointer points to an element in to Data. I did not 
use int's as "pointers" for a specific non-relevant reason [...]


I would seriously consider turning that around and work with 
indices primarily, then take the address of an indexed element 
whenever you do need a pointer for that specific non-relevant 
reason. It makes I/O trivial, and it is safer too.


size_t[] OtherStuff;
size_t[int] MoreStuff;

Bastiaan.


Re: How to use #pragma omp parallel for collapse(n) in dlang?

2019-08-15 Thread Bastiaan Veelo via Digitalmars-d-learn

On Tuesday, 13 August 2019 at 08:41:07 UTC, ijet wrote:

How to use #pragma omp parallel for collapse(n) in dlang?


I don’t understand the question.

Bastiaan.


Re: 1 new

2019-08-03 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 2 August 2019 at 18:25:28 UTC, jmh530 wrote:
When I navigate to https://forum.dlang.org/ I have a message 
that says "1 new reply" to "your posts." Normally, I click on 
that "1 new reply" and find the post that's new, go to it, and 
the message disappears. However, it doesn't seem to go away 
anymore. I tried looking at many different old posts without 
luck. At one point it was up to "2 new replies," but I viewed 
that other post and it went back down to "1 new reply." Does 
anyone else have this?


I always have “2 new replies” on that page, no matter how often I 
take a look. The feature seems a bit broken to me.


Bastiaan.


Re: How to get name of my application (project)

2019-08-03 Thread Bastiaan Veelo via Digitalmars-d-learn

On Saturday, 3 August 2019 at 09:26:03 UTC, Andrey wrote:
Hello, how to get name of my application (project) that we 
write in dub.json? Is there any compile-time constant like 
__MODULE__?


The name of an application is not a compile time constant: you 
can rename the executable at any time. Like Rémy said, 
thisExePath.baseName will get you the name at run time.


Bastiaan.


Re: Help me decide D or C

2019-08-02 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 2 August 2019 at 13:45:17 UTC, Alexandre wrote:

On Friday, 2 August 2019 at 12:30:44 UTC, berni wrote:

On Wednesday, 31 July 2019 at 18:38:02 UTC, Alexandre wrote:

[...]


In my oppinion C should have been deprecated about 50 years 
ago and it's not worth while to learn it if you are not 
interested in the history of programming or you have to learn 
it, because you need to maintain software which is allready 
written in C. But that's my oppinion; others may have a 
different sight.


[...]


Could you elaborate more about C being a burden? I have read so 
many people saying C gives a great foundation and should be 
everyone's first language. Now I am confused.


One example is this recent post: 
https://forum.dlang.org/post/yjgkatpbkdyyksldg...@forum.dlang.org


“[...] recently all the problems I am having with D are because D 
is actually superior to C and some assumptions I still have 
because of C should be uninstalled from my brain.”


If you plan on ending up with D anyway, I think that learning C 
first is an unnecessary detour and can be counter productive in 
some ways. And if your objective is to have fun, I would 
recommend against C (except for a masochistic kind of fun).


Don’t take the detour, take the D tour! :-)

Bastiaan.


Re: Help me decide D or C

2019-08-02 Thread Bastiaan Veelo via Digitalmars-d-learn
On Thursday, 1 August 2019 at 20:02:08 UTC, Aurélien Plazzotta 
wrote:

[...]
But don't fool yourself, D is not for beginners. Ali Çehreli is 
a very skilled programmer, ergo, he can't reason like a 
new/starting programmer anymore, regardless of his patience and 
kindness.


I am sorry, but this is very strange reasoning. Would you 
recommend a book on programming written by someone who is not a 
skilled programmer himself in any language? I certainly would not.


Besides, the OP has already expressed his appreciation for Ali’s 
writing.


Bastiaan.



Re: 1 - 17 ms, 553 ╬╝s, and 1 hnsec

2019-05-17 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 17 May 2019 at 18:36:00 UTC, ag0aep6g wrote:
I'd suggest "17 ms, and 553.1µs" for a better default (1 hns is 
0.1 µs, right?). No weird "hnsecs", no false precision, still 
all the data that is there.


I was going to propose the same. Hns is weird.

Bastiaan.


Re: Windows / redirect STDERR to see assert messages

2019-05-14 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 12 May 2019 at 13:39:15 UTC, Robert M. Münch wrote:

When developing Windows GUI applications I use:

 // detach from console and attach to a new one, works for 
x86 and x86_64

 FreeConsole();
 AllocConsole();

 freopen("CONIN$", "r", stdin);
 freopen("CONOUT$", "w", stdout);
 freopen("CONOUT$", "w", stderr);

so that the GUI app opens a console for writeln() output etc. I 
assumed this should work for assert() messages as well. But it 
seems it doesn't. If an assert fails, I don't see any output. 
Is assert using something else? What's wrong about this 
approach?


Are you sure the last call to freopen doesn't return NULL? You 
are opening the same file twice and I'm not sure that works. Test 
with `stderr.writeln("test")`.


Bastiaan.


Re: CTFE in imported static initializers

2019-05-14 Thread Bastiaan Veelo via Digitalmars-d-learn
On Monday, 13 May 2019 at 20:39:57 UTC, Steven Schveighoffer 
wrote:

Why? I can't even use it at compile time...

pragma(msg, moddata.length);


Is that a good test or "usable at compile time", though? Isn't 
pragma(msg) done at an earlier stage than CTFE? I think that was 
the argument for ctfeWriteln.


(We both know that I'm out of my league here, but anyway :))

Bastiaan.


Re: Compile time mapping

2019-05-12 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 12 May 2019 at 18:47:20 UTC, Bogdan wrote:

On Sunday, 12 May 2019 at 17:53:56 UTC, Bastiaan Veelo wrote:
If I understand your question correctly, you have two enums of 
equal length, and you want to convert members across enums 
according to their position, right?


My question was very vague, sorry about that.

In my use case I'd like to map SDL2 keyboard scan codes to my 
own game input keyboard codes. The two enums would look 
something like this:


```
enum SDL_Scancode
{
SDL_SCANCODE_UNKNOWN = 0,
SDL_SCANCODE_A = 4,
SDL_SCANCODE_B = 5,
SDL_SCANCODE_C = 6,
SDL_SCANCODE_D = 7,
}

enum MY_Scancode
{
  KEY_A,
  KEY_B,
  KEY_C,
  KEY_D,
}
```

The two enums are not of equal length, so in the end I just 
decided to create an immutable array of type My_Scancode[] 
where the index is an SDL_Scancode and the value is the 
corresponding MY_Scancode enum member. I'm ok with using some 
memory for this, as long as it's as fast as possible.


If the only difference is the extra _UNKNOWN member, you can 
still use the static foreach approach. Just make it a 
non-template function and rip out the checks, and add a +1 in the 
right place.


  1   2   3   >