### Re: How is opEquals used in toHash

```
On Tuesday, 18 May 2021 at 10:14:26 UTC, PinDPlugga wrote:
But what I do not understand is why opEquals is necessary and
where in the implementation of toHash it plays its role? Since
area1 and area2 have different static arrays of Points I
understand why `typeid(points).getHash()` would produce
different values for each, but it seems like the opEquals
should play a part in making them produce the same hash.

opEquals plays no part in how toHash does its thing, but it's
important for how AAs work. When there's a hash collision, the
colliding items are placed in a bucket, which is generally
iterated linearly to find the matching element, using opEquals.
Example code:

```d
struct S {
int i;
size_t toHash() const nothrow @safe { return 3; }
bool opEquals(ref const S rhs) const { return i == rhs.i;
}

}

unittest {
int[S] a;
a[S(1)] = 3;
a[S(2)] = 4; // Hash collision - both return 3
assert(a.length == 2); // But they're both there
assert(S(1) in a);
assert(S(2) in a);
int b = a[S(1)];
int c = a[S(2)];
assert(b == 3);
assert(c == 4);
}
```

And pseudocode for how an AA works:

```d
struct AA(K, V) {
import std.typecons : Tuple;
alias Pair = Tuple!(K, "key", V, "value");
alias Bucket = Pair[];

Bucket[] buckets;

this(int bucketCount) {
buckets.length = bucketCount;
}

void opIndexAssign(V value, K key) {
// Use hash to find correct bucket
size_t hash = key.toHash();
size_t index = hash % buckets.length;
Bucket bucket = buckets[index];

foreach (e; bucket) {
if (e.key == key) { // Check for duplicates with
opEquals

e.value = value; // Overwrite existing
return;
}
}

bucket ~= Pair(key, value);
// Array could reallocate when appended to,
// so assign it back to the bucket list
buckets[index] = bucket;
}

V opIndex(K key) {
// Use hash to find correct bucket
size_t hash = key.toHash();
size_t index = hash % buckets.length;
Bucket bucket = buckets[index];

foreach (e; bucket) {
if (e.key == key) { // Check with opEquals
return e.value;
}
}
}
}

unittest {
AA!(S, int) a = AA!(S, int)(24);
a[S(1)] = 3;
a[S(2)] = 4;
assert(a[S(1)] == 3);
assert(a[S(2)] == 4);
}
```

This omits plenty of details, but should give some idea how AAs
work.

--
Simen

```

### Re: type of functions

```
On Monday, 10 May 2021 at 10:37:51 UTC, Alain De Vos wrote:
Can I say that the compiler is intelligent enough to add the
attributes "pure nothrow @nogc @safe" ?

Yes, in those cases (and some others). The functionality is
described here:

https://dlang.org/spec/function.html#function-attribute-inference

--
Simen

```

### Re: Dlang equivalent of #define/#ifdef : not... version

```
On Tuesday, 20 April 2021 at 18:57:46 UTC, ichneumwn wrote:

So my questions:
- is there a module-crossing equivalent of "version"?

mw covered this. There's more documentation here:
https://dlang.org/spec/version.html#version

https://dlang.org/dmd-windows.html#switch-version

- if not, is there some way I could test for the existence of
the enum can_i_test_for_this? A SymbolExists!() or
ModuleHasSymbol!() or ModuleHasMember!() ?

__traits(hasMember, features, "i_am_not_a_feature")

This is actually what std.traits.hasMember does, but for some
reason it can't take a module as its first argument.

--
Simen

```

### Re: How can I allocate a int[] array on stack?

```
On Friday, 26 March 2021 at 14:27:58 UTC, Jack wrote:

On Friday, 26 March 2021 at 06:45:39 UTC, Daniel Kozak wrote:
On Fri, Mar 26, 2021 at 7:36 AM Daniel Kozak
wrote:

On Fri, Mar 26, 2021 at 7:31 AM Daniel Kozak
wrote:

On Fri, Mar 26, 2021 at 6:50 AM Jack via Digitalmars-d-learn
< digitalmars-d-learn@puremagic.com> wrote:

What's the equivalent of C's VLA in D? scoped from
std.typecons doesn't seem to work with arrays. Should I use
alloca() for my array or is there something else?

https://dlang.org/library/std/array/static_array.html

You can use allocator:

import std.experimental.allocator.showcase;
import std.experimental.allocator;
import std.stdio;

StackFront!4096 stackAlloc;

void main() {
int[] a = stackAlloc.makeArray!int(2);
writeln(a);
}

I thought this was going to use alloca() but it seems to be
using malloc() internally?

Basically, StackFront is an allocator that allows any size
allocation, but prefers to put things in its memory block on the
stack. If there's no space left on the stack, it puts things on
the heap. Not quite what you're asking for, in other words.

StackFront is basically this:

struct StackFront(size_t size) {
ubyte[size] memory;
size_t used;
T allocate(T)() {
if (used + T.sizeof > size) return
*cast(T*)malloc(T.sizeof);

auto result = *cast(T*)[used];
used += T.sizeof;
return result;
}
}

With more bells and whistles, but it's a fixed-size block of
memory on the stack that falls back to heap allocation when
there's no more room in the block.

alloca is probably your best bet if you need dynamic-size stack
allocation. That said, it's a "you're on your own" kind of
solution. Use it if you know it's the best solution for your
problem.

--
Simen

```

### Re: Opaque type (struct) with a static immutable fails to compile without constructor - why?

```
On Thursday, 4 March 2021 at 13:58:48 UTC, frankp wrote:

Hi all,

I want to make an opaque type that simply contains an integer
with some immutable constants and toString pretty printing.
Like this:

struct Foo_t
{
private long foo;
alias foo this;
static immutable long Inf = long.max; //1)

void toString(...){}
}

On dmd 2.092.1 this fails with:
1) Error: cannot implicitly convert expression 9223...L of
type immutable(long) to Foo_t

I simply want to initialize an immutable long with long.max.
Why the conversion to Foo_t ?

private this(long f)
{
foo = f;
}

It compiles but according to code coverage this constructor is
never called.

What's going on?

I tried compiling your code locally on DMD 2.094.1, and had no
issues. Again with 2.095.0, no issues. On run.dlang.io, with all
dmd compilers from 2.060, and it just plain works.

Now, that's after removing ... from toString. With that present,
it fails with some variation of 'Error: undefined identifier
'__va_list_tag''.

Most likely, you have shortened your program for clarity, and
removed the issue you're experiencing in the process. Can we have
another one, with the issue still there?

--
Simen

```

### Re: Templated delegate as template argument for structs

```On Saturday, 20 February 2021 at 09:16:46 UTC, Simon van Bernem
wrote:

I have the following struct declaration:

struct Hash_Table(Key, Value, u32 delegate(ref Key)
custom_hash_function = null)

[snip]
I take it from the error that the problem is not actually the
delegate that I am passing, but the fact that the delegate type
has another template parameter as the argument type. Can
template arguments in D not reference previous template
arguments? Is there some way I can get around this?

The D way would be an alias parameter:

struct Hash_Table(Key, Value, alias custom_hash_function) {
// ...
}

struct Hash_Table(Key, Value, alias custom_hash_function)
if (is_valid_hash_function!(Key, custom_hash_function))
{
// ...
}

// Check if the hash function can be called with a Key
// as argument, and the result be assigned to a u32
enum is_valid_hash_function(Key, alias fn) = __traits(compiles,
(Key k){ u32 u = fn(k); });

D lets you refer to other template parameters in the same
template parameter list in three cases, as far as I know:

1) A type may be a subtype of an earlier parameter:

class C {}
struct S(TBase, TDerived : TBase) {}
S!(Object, C) a;

2) A type parameter with a type specialization followed by
template parameter list:

struct Fn(U) {}
struct S(T: Fn!Arg, Arg) {}
S!(Fn!int) a;

3) Following a type parameter, a value parameter of that type may
appear:

struct S(T, T value) {}
S!(int, 4) a;

The first two can also be combined:

struct Fn(U) {}
struct S(T1, T2: Fn!T3, T3 : T1) {}
S!(int, Fn!int) a;

However, it seems 3) only works with that specific type, modulo
storage classes. No Foo!T, no void delegate(T). At any rate, the
alias parameter is the way it's generally done, and is more
flexible, so just leave it at that.

--
Simen

```

### Re: Creating 1000 instances

```
On Friday, 19 February 2021 at 10:02:05 UTC, Siemargl wrote:
On Friday, 19 February 2021 at 08:29:36 UTC, Ferhat Kurtulmuş
wrote:

Since classes are reference types all instances of files will
be the same reference of "new File()", which you probably
don't want.

Is any differences between x and y definitions?

MyClass [] x, y;
x = new MyClass[7];

y= new MyClass[](8);

The only part of the documentation I've found that talks about
this is here:

https://dlang.org/spec/expression.html#new_expressions

The main difference I know of comes with multidimensional arrays:

auto a = new int[4][4];
pragma(msg, typeof(a)); // Prints int[4][]
auto b = new int[][](4,4);
pragma(msg, typeof(b)); // Prints int[][]

Since the former is a dynamic array of static arrays, the first
size parameter cannot be passed at runtime:

auto n = 4;
// Error: variable n cannot be read at compile time
auto c = new int[n][n];

But must be a compiletime constant:

enum N = 4;
auto d = new int[N][n];
pragma(msg, typeof(d)); // Prints int[4][]

The other syntax however, can take runtime values, but does not
encode the size in the type:

auto e = new int[][](n,n);
pragma(msg, typeof(e)); // Prints int[][]

The other big thing about the []() syntax is it actually
initializes the arrays of arrays for you:

assert(e[0].length == n);

If you were to use new int[][n], you would need to initialize
each array of arrays manually:

auto f = new int[][n];
assert(f[0].length == 0); // it's empty
foreach (i; 0..n) {
f[i] = new int[n]; // Have to do this yourself.
}

--
Simen

```

### Re: Two "references" to dynamic array, why not change both when reallocating?

```
On Wednesday, 11 November 2020 at 10:17:09 UTC, zack wrote:
I am new to D. Appending to an array can lead to reallocation,
that's clear. But why is the "reference" b not changed
accordingly to the new position and still points to "old"
memory? Why is b not also changed when reallocating array a and
the old data getting invalid/freed?

auto a = [55,10,20];
auto b = a;
a ~= [99,99,99,99,99,99];
a[0] = 1;
assert(b[0] == 1); // could fail

(similar to p.103-104 in "The D Programming language")

The short answer is 'because that's how we've chosen to define
it'. A more involved answer is that changing every reference is
prohibitively expensive - it would require the equivalent of a GC
collection on every reallocation, as references to the array
could exist anywhere in the program, be that on the stack, heap,
even on other threads. That's the performance side of it.

Another heavy argument is 'can you make it behave the other way?'
Currently, that's simple: use a pointer to a slice (T[]*), and
share that around. I don't see how I would get the current
behavior if reallocation caused reassignment of all references

Next up: does b, ending on the same element as a, refer to the
whole length of a (i.e. should b's length be reassigned when a is
reallocated?), or is it a slice only referencing the first three
elements? Either choice is going to be unexpected in some cases.

All in all, there's many reasons to choose the behavior D has
chosen. There are some drawbacks, but I feel it's the right
choice.

--
Simen

```

### Re: How add class or struct member after construction?

```
On Thursday, 5 November 2020 at 22:48:38 UTC, Marcone wrote:
How add class or struct member after construction? Is it
possible in D? How?

This depends a lot on what you mean. The short answer is no - you
cannot. However, given some limitations, it is possible. What
sort of members do you need to add, and how will you be using
them?

For instance, this works:

struct S {
import std.variant;
Variant[string] members;

Variant opDispatch(string name)() {
return members[name];
}
Variant opDispatch(string name, T)(T value) {
return members[name] = value;
}
}

unittest {
S s;
s.foo = 13;
assert(s.foo == 13);
}

--
Simen

```

### Re: this T / variadic template and interfaces

```
On Monday, 26 October 2020 at 11:14:47 UTC, frame wrote:

Did not find this topic:

I have an interface and some wrapper classes that use it. The
wrapper's methods should accept variadic arguments. The runtime
should only work with the interface, trying casting to a
wrapper is not an option, because it's a plugin design.

- defining a variadic template in wrapper does not work,
because we are working with the interface only and compiler
complains method is not callable with argument X

- defining a variadic template without body in interface causes
linker errors, which makes sense somehow

- defining a variadic template with body in interface could
work if the compiler would get the right "this" type but sadly,
"this" refers to interface and also "this T" refers to
interface too.

Is there any way to get this working? I know, I could use a
known object to feed the arguments and use that instead - but I
want to keep things simple as possible.

Templates can't be virtual, so even if they can be defined in an
interface, you can't override them in a class that implements
said interface - the implementation needs to be in the interface
itself.

This makes sense if you consider that the user of the interface
has no knowledge of the types that implement it, and vice versa:
the implementing class has no idea which instantiations to make,
and the user has no idea which implementing classes to create
instantiations for. Templates require that the user have full
knowledge of the templates to be instantiated.

There are some workarounds of sorts, but they depend heavily on
what you're trying to achieve. Can you use an array of
std.variant.Variant, for instance?

--
Simen

```

### Re: Call method of object variable

```
On Friday, 16 October 2020 at 08:12:59 UTC, Andrey wrote:

Hi,
I have got:

struct Qaz
{
wstring hear() {return "";} }

void main()
{
// ...
static if(some_condition) alias method = Qaz.hear;

// ...
Qaz qaz;

qaz.method(); // ???
}

How to call alias "method" on object "qaz"?

https://dlang.org/spec/traits.html#child

The resulting code would be:

__traits(child, qaz, method)(/*arguments go here*/);

--
Simen

```

### Re: Why is "delete" unsafe?

```
On Wednesday, 23 September 2020 at 04:15:51 UTC, mw wrote:
It's there because there _are_ times when it makes sense and
is useful, but it's definitely not safe, so you have to be
careful and know what you're doing.

What do you mean by saying "it's definitely not safe" here?

I mean: if I'm careful and know what I'm doing, e.g. remove all
the reference to  any part of the `object` before call
core.memory.GC.free(object), is there still any inherit
"unsafe" side of `free` I should be aware of?

FYI: I just described my use case here:

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

If there are no lingering references, the function calling free()

--
Simen

```

### Re: Why private methods cant be virtual?

```
On Tuesday, 22 September 2020 at 13:19:10 UTC, Daniel Kozak wrote:
So final private functions can be overriden? It seems not, but
the sentence is definitely confusing if not just plain wrong.

Yeah. I've seen this called hiding, shadowing and overwriting
earlier, but never overriding - that's always been reserved for
the polymorphic kind.

I'd argue the documentation should use one of those other terms.

And yes compiler probably could findout that method could be
non-virtual but I am not sure how easy is this and how it would
slow down

compilation times

Steve showed a few posts up one example that would make it
basically impossible. Other language features make it even worse:

class A { private void fun() {} }
class B(string s) : A { mixin(s); }

--
Simen

```

### Re: Why is dtor called for lazy parameter?

```On Friday, 18 September 2020 at 14:14:31 UTC, Andrey Zherikov
wrote:
It seems that dtor is called at exit from lazy delegate, not at
exit form create():

==
create()
.do_something()
.do_lazy()
.do_something();
==
Output:
==
-> void test.main()
-> test.do_lazy(lazy S s)
-> test.create()
1 S test.S.this(int n)
<- test.create()
-> 1 test.do_something(S s)
<- 1 test.do_something(S s)
1 void test.S.~this()
===-1
<- test.do_lazy(lazy S s)
-> 1703096 test.do_something(S s)
<- 1703096 test.do_something(S s)
<- void test.main()
==

This doesn't even allow me to copy the value of 's' in
do_lazy().

You're right, I missed a step: do_lazy() takes a S, not a
scoped!S, so the conversion from scoped!S to S happens after
create() has returned and before the value is used in do_lazy.
This explains my confusion earlier.

D's lazy is essentially the same as a delegate or function, so
you could* rewrite to this (writelns omitted for clarity):

S do_lazy(S function() s) {
return s();
}

void main() {
(() => cast(S)create()) // Here
.do_lazy()
.do_something();
}

On the marked line, the cast from scoped!S to S happens, the
scoped!S goes out of scope and the destructor is called.

*There may be differences, but for this discussion these are not
important.

--
Simen

```

### Re: Why is dtor called for lazy parameter?

```On Friday, 18 September 2020 at 12:32:49 UTC, Andrey Zherikov
wrote:

==
The output is:
==
-> void test.main()
-> test.do_lazy(lazy S s)
-> test.create()
1 S test.S.this(int n)
<- test.create()
1 void test.S.~this()
===-1  (2)
<- test.do_lazy(lazy S s)
-> 1703096 test.do_something(S s)
<- 1703096 test.do_something(S s)
<- void test.main()
==

As you can see, dtor is called before writeln on (1) and s1.i
is -1 (2)

Indeed. As we can see from the output, first do_lazy() is called
from test.main, then create() is called (this happens inside
do_lazy, as s is lazy). When create() returns, the scoped!S you
created goes out of scope and is destroyed. scoped's destructor
overwrites the memory with S.init, which is why s.i is -1 at that
point. Then the memory is overwritten by subsequent function
calls, as that stack space is now considered vacant. That's why
the output changes from -1 to 1703096.

A bit interesting is the fact that <- test.create() is printed
before ~this(). I expected the order to be opposite, but there
may be sensible reasons why it's not.

scoped!S is only valid inside the scope its variable exists in,
and when that scope is exited, it refers to random stack data.
It's a lot like this code:

int* fun() {
int a;
int* p =
return p;
}

Note that return  does not compile, with a warning about
escaping a reference to a local variable. That's exactly the same
thing that's happening with scoped!S, but since scoped is more
complex, the compiler has a hard time keeping track of things,
and code that in a perfect world would not compile, does. It may
be that D's scope tracking functionality has become good enough
to catch this error now, if the functions are properly marked.
Even if this is the case, then they are obviously not properly
marked. :p

Now, this begets the question: *when* should I use scoped!T?

1) When the lifetime of one object needs to be a strict subset of
another. That is, the class instance you created only exists as
long as the function create() is on the stack. When scoped!T is a
member of another class or struct, it continues to live as long
as that object exists. In most cases, you don't mind that it
stays around for longer, and can let the GC handle the cleanup.
If you really do care, you can use scoped!T, or explicitly
destroy the object when you're done with it.

2) scoped!T may be used as a performance hack, letting you avoid
the GC. If you have instrumented your code and found that this is
the culprit, scoped!T might help. Even if GC is the problem,
you'll still need #1 to be true.

There may be other cases, but I believe those are the main two
reasons to use scoped!T.

--
Simen

```

### Re: Why is dtor called for lazy parameter?

```On Friday, 18 September 2020 at 10:43:47 UTC, Andrey Zherikov
wrote:
Why is dtor called before returning from do_lazy function - see
(1)? It seems cause uninitialized parameter in do_something
call after it in (2)-(3).

As ikod mentions, it's because of scoped!S. As for why it does
this, yeah, this is kinda egregious. The documentation[0] of
scoped mentions this issue:

This facility is unsafe; it is the responsibility of the user
to not escape a reference to the object outside the scope.

As the name implies, scoped!T limits the valid scope of a
reference to the scope of the variable holding it. You're putting
it on the stack, so the moment the variable goes off the stack
(when do_lazy returns), the reference is destructed.

--
Simen

[0]: https://dlang.org/library/std/typecons/scoped.html

```

### Re: Type inference for constructors

```On Friday, 18 September 2020 at 05:43:56 UTC, data pulverizer
wrote:
I’d like to know if constructors of classes and structs can
have type inference. So far, I am using a separate function for
this purpose, for example:

```
import std.stdio: writeln;

struct Pair(T, U)
{
T first;
U second;
this(T first, U second)
{
this.first = first;
this.second = second;
}
}

Pair!(T, U) pair(T, U)(T first, U second)
{
return Pair!(T, U)(first, second);
}

void main()
{
auto mp = pair("Michael", 32);//standard function inference
works
//auto m0 = Pair("Michael", 32); //I’d like to be able to do
this

writeln("pair: ", mp);
}
```

That's issue 1997: https://issues.dlang.org/show_bug.cgi?id=1997

D's templates are turing complete, and there may be arbitrary
amounts of logic obscuring the mapping between type template
parameters and the specific argument types of the type's
constructor, so the problem is intractable in the general case.
E.g:

template Foo(T) {
static if (is(T == int)) {
struct Foo {
this(int i) {}
// int-specific code
}
} else {
struct Foo {
this(T t) {}
// generic code
}
}
}

The above example is a simple one, yet mapping from a constructor
call to the correct template parameters is difficult.

[I] wondered what `this` in the code below does:

```
auto ref opIndex(this X, D...)(auto ref D i) { return a[i]; }
```

That's a template this parameter
(https://dlang.org/spec/template.html#template_this_parameter).
It takes on the type of 'this' at the point of instantiation.
That is:

struct S {
void fun(this T)() { pragma(msg, T); }
}

unittest {
S s;
const S sc;
immutable S si;
shared S ss;
s.fun();  // prints S
sc.fun(); // prints const(S)
si.fun(); // prints immutable(S)
ss.fun(); // prints shared(S)
}

This allows the return type to have the same constness as 'this',
or for specific code to be executed when operating on e.g. a
non-mutable instance, where lazy initialization couldn't be
performed. In many cases, this is better served by using inout:

https://dlang.org/spec/function.html#inout-functions

--
Simen

```

### Re: another question on hidden mixin names

```
On Thursday, 17 September 2020 at 21:05:59 UTC, 60rntogo wrote:

struct V
{
int x;

mixin assign!"+";
// mixin assign!"-";
}

However, if I uncomment the second mixin, there is an error "v
is not a scalar, it is a V". I guess I somehow need to merge
these overloads, but I don't know how.

Usually, that would be:

struct V {
int x;

mixin assign!"+" a;
mixin assign!"-" b;
alias opOpAssign = a.opOpAssign;
alias opOpAssign = b.opOpAssign;
}

However, I can't seem to get that working. It seems to be an
instance of this issue:

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

Note that explicitly calling the methods does work:

v.opOpAssign!"-"(v);
v.opOpAssign!"+"(v);

I don't know any good workarounds for this, you'll probably have
to write a separate opOpAssign method for V that performs the
forwarding to the mixed-in methods. This is, to put it very
nicely, not an optimal solution.

btw, I'm somewhat surprised by your use of a template this
parameter
(https://dlang.org/spec/template.html#template_this_parameter).
Generally this will work, but you're probably better off with

ref auto opOpAssign(string op)(typeof(this) rhs) if (op ==
op_)

--
Simen

```

### Re: enum and const or immutable ‘variable’ whose value is known at compile time

```
On Thursday, 17 September 2020 at 10:56:28 UTC, Mike Parker wrote:

On Thursday, 17 September 2020 at 09:44:20 UTC, claptrap wrote:

Seriously how it's implemented is irrelevant.

And to be clear, my point wasn't about how it's implemented. My
point was that:

enum { foo = 10; }

and

enum foo = 10;

Are effectively the same thing, whether it's implemented that
way or not. So why on earth would a new keyword be necessary?

I could imagine some new users may think in

enum foo = someTemplate!();

someTemplate could evaluate to a list of values like a 'normal'
enum. That's just conjecture, though. The one thing I dislike
about enum like this is that we have another keyword that's able
to handle manifest constants when tickled correctly, and which
doesn't evoke the image of an enumerated list of values:

import std.meta : Alias;
alias foo = Alias!([1,2,3]);
alias bar = Alias!9;
alias baz = Alias!someFunc;

Some of the above may be doable without Alias!(), but not all. I
don't know if you remember the discussions when bracketless enums
were introduced back in 2007ish, but alias was the prime
contender back then, and is slowly gaining the power that was
requested at the time (the ability to alias values as above was

To quote Bill Baxter from way back when
(https://forum.dlang.org/post/fjdc4c\$2gft\$1...@digitalmars.com):

> Why does:
> final int x = 3;
> make any more intuitive sense than:
> enum int x = 3;
> ?

There are these things called "words".  And they have
"meanings"...

enum: (short for "enumeration", the noun form of "enumerate")
"to specify one after another : list"
final:
"not to be altered or undone "

To be clear: I don't mind 'enum' being used this way, but if I
were to do things over again, I would have used 'alias'.

--
Simen

```

### Re: Neater "not version (...)" ?

```On Wednesday, 16 September 2020 at 19:04:24 UTC, Vladimirs
Nordholm wrote:
On Wednesday, 16 September 2020 at 18:54:45 UTC, Jacob Carlborg
wrote:

version (Windows)
enum windows = true;
else
enum windows = false;

static if (!windows)
{
// ... my code
}

Ah, I guess it boils down to this then. Doesn't really make it
"neater", but thank you for the tip!

I wrote this helper a little while back:

struct Version {
template opDispatch(string name) {
mixin("version ("~name~") enum opDispatch = true; else
enum opDispatch = false;");

}
}

static if (Version.Windows) pragma(msg, "Windows machine");
static if (Version.linux) pragma(msg, "Linux machine");

Note that it only works for global versions, and those defined in
the same module as Version.

--
Simen

```

### Re: Why does compose from std.functional return a templated function

```
On Wednesday, 16 September 2020 at 09:59:59 UTC, Jan Hönig wrote:
I have toyed with the compose template in std.functional and
ran into some problems.

rikki_cattermole on discord helped me a lot to solve my problem.

However, what still remains (for me) to understand is why.

Source code for `compose`:
https://github.com/dlang/phobos/blob/master/std/functional.d#L1161

`compose` pipes together given functions. And returns a
TEMPLATED function.
Why does it return a templated function? At compile-time,
compose definitly knows, what kinds of function it composes
together. So with std.traits, it could put there a definitve
type, depending on the given function(s).

I somewhat see, that inside compose itself, this probably
solves some issues with casting (maybe).
However, the last composition, i.e. the one which is returned,
does not need to be templated, since it is known, what
parameter has the last function.

In my case, I failed to understand, that it returns a
non-initialized template function, which lead into compile
problems.

In general I can imagine that this leads to weird compile
errors, which are hard to understand. (types, casting, etc.)

My main question is why? Is there something, which I am
missing, that explains, why it is beneficial to return a
templated function?

(maybe, because I might want to compose together templated
non-initialized functions?)

It's perfectly possible to compose templated functions without
wanting to specify the template parameters, and not allowing this
would significantly hamper compose's usability.

The other complication is overloads. Here's a version of compose

__traits(parent, fn), __traits(identifier, fn), true))) {
__traits(parent, fn), __traits(identifier, fn), true);

} else {
}
}

template compose(funs...) if (funs.length > 0) {
auto compose(Args...)(Args args) {
static if (funs.length == 1) {
} else {
return funs[0](.compose!(funs[1..\$])(args));
}
}
} else {
import std.traits : Parameters;
static if (funs.length == 1) {
} else {
return funs[0](.compose!(funs[1..\$])(args));
}
}
}
}
}

As you can see, this is *a lot* more complex than the version in
std.functional. The benefit is you can take the address of it
easily. Here's how you can do the same with
std.functional.compose:

import std.functional : compose;
import std.meta : Instantiate;

unittest {
auto sun = !(compose!(fun, gun), int);
sun(3);
}

void fun(T)(T t) {
}

int gun(int t) {
return t;
}

I will argue the latter is an acceptable cost of avoiding the
dense, bug-prone monstrosity of the former.

--
Simen

```

### Re: Get enum value name as string at compile time?

```On Monday, 14 September 2020 at 03:48:51 UTC, Steven
Schveighoffer wrote:

Consider the enum:

enum Foo { a, b }

Foo.a.stringof => "a"
enum x = Foo.a;
x.stringof => "cast(Foo)0"

Is there another way I can take an enum value that's known at
compile time (but not the actual identifier), and get the name
of it? I know I can use a switch, or to!string. But I was
hoping this was easy for the compiler to figure out some way
without involving CTFE.

It is a bit weird that x.stringof doesn't simply return the name
like Foo.a.stringof does. Anyways, this works:

template enumName(alias a) {
import std.meta : staticIndexOf, staticMap;

alias T = typeof(a);
enum getValue(string name) = __traits(getMember, T, name);
alias enumValues = staticMap!(getValue, __traits(allMembers,
T));

enum enumName = __traits(allMembers, T)[staticIndexOf!(a,
enumValues)];

}

enum Foo { a = 2, b = 19 }

enum x = Foo.a;
pragma(msg, enumName!x); // "a"

--
Simen

```

### Re: sending the address of a struct

```
On Sunday, 6 September 2020 at 09:58:54 UTC, Johann Lermer wrote:

pointer. The error message says:

std.concurrency.MessageMismatch@std/concurrency.d(237):
Unexpected message type: expected 'shared(Env*)', got
'shared(test.Env)*'

The error message gives you all the information you need - notice
the position of the asterisk inside the parens on one, outside on
the other? The pointer itself is not shared, only the pointee -
the data pointed to. This works:

--
Simen

```

### Re: tupleof seems to break encapsulation

```
On Friday, 4 September 2020 at 10:16:47 UTC, 60rntogo wrote:

Consider the following code.

foo.d
---
module foo;

struct Foo
{
private int i;
}
---

main.d
---
void main()
{
import std.stdio;
import foo;

auto x = Foo();
writeln(x);
// ++x.i;
++x.tupleof[0];
writeln(x);
}
---

As expected, the commented line does not compile. If I
uncomment it, I get the error "no property i for type foo.Foo".
However, the rest of the code compiles just fine and outputs:

---
Foo(0)
Foo(1)
---

This appears to defeat the purpose of declaring i private. What
am I missing?

It's a known issue: https://issues.dlang.org/show_bug.cgi?id=19326

There are some very good reasons to allow some access to private
fields, though it should be more limited than is currently the
case.

--
Simen

```

### Re: Tuple poilerplate code

```
On Tuesday, 1 September 2020 at 02:08:54 UTC, JG wrote:
Is there anyway to remove the boilerplate code of dealing with
tuples:

I find myself having to write things like this fairly often

auto someRandomName  = f(...); //where f returns a tuple with
two parts

auto firstPart = someRandomName[0];
auto secondPart = someRandomName[1];

Is to possible to write something so that the above is
essentially equivalent to:

assignTuple!(firstPart,secondPart) = f(...);

The closest I can produce is using a template mixin so that I
would have to write:

mixin AssignTuple!(()=>f(...),"firstPart","secondPart");

When you know the types, this works:

import std.typecons : tuple;
import std.meta : AliasSeq;

int firstPart;
string secondPart;

AliasSeq!(firstPart, secondPart) = tuple(1, "foo");

assert(firstPart == 1);
assert(secondPart == "foo");

I know Timon Gehr worked on a DIP for improved tuples, which I
think would include the syntax `auto (firstPart, secondPart) =
tuple(1, "foo");`, but I don't know what's happened to that idea
lately.

I also feel it's worth pointing out that Paul Backus' code looks
elegant when used outside a map as well:

tuple(1, "foo").unpack!((i, s) {
writeln("i (", typeof(i).stringof, "): ", i,
", s (", typeof(s).stringof, "): ", s);
});

Will print:
i (int): 1, s (string): foo

--
Simen

```

### Re: Wrong selection of opEquals for objects.

```On Friday, 28 August 2020 at 13:35:43 UTC, Alexandru Ermicioi
wrote:

On Friday, 28 August 2020 at 12:29:20 UTC, Simen Kjærås wrote:

Seems that these methods should be rooted out from Object, and
placed in respective interfaces like:

-
interface Equatable(T) {
bool opEquals(T value);
}
-

Then it would be a lot more simple. People who want equality
check, will implement interface with right type, for example
Equatable!Object.

Yup, it's been proposed, but nothing's come of it yet. Here's
Andrei's DIP on ProtoObject, which apparently is untouched for
over two years now:
https://github.com/andralex/DIPs/blob/ProtoObject/DIPs/DIP.md

The main problem with solving this issue is doing so will break
all code that uses the current system. This is clearly suboptimal.

--
Simen

```

### Re: Wrong selection of opEquals for objects.

```On Friday, 28 August 2020 at 10:42:09 UTC, Alexandru Ermicioi
wrote:
No that is not a solution at all, in template code that
requires safety. You basically will have to sacrifice safety
for rest of types, such as structs, unions & enums for the sake
of objects being able to compare.

Yup. There's a reason I'm saying it's suboptimal. FWIW, you can
limit the taint by using @trusted lambdas.

One of the reasons this hasn't been fixed is idiomatic D code
very rarely uses classes, but that does not mean they're always
the wrong tool.

Could we just template that opEquals in this manner:
---
bool opEquals(T : Object, X : Object)(T lhs, X rhs)
{
if (lhs is rhs) return true;

if (lhs is null || rhs is null) return false;

if (!lhs.opEquals(rhs)) return false;

if (typeid(lhs) is typeid(rhs) ||
!__ctfe && typeid(lhs).opEquals(typeid(rhs)))
{
return true;
}

return rhs.opEquals(lhs);
}
---

That would at least allow us to define an overload which is
safe and would be picked up by new implementation.

I'm wondering why it wasn't done yet, are there any reasons for
that?

The template solution may look like it solves every problem, but
it really doesn't. Consider this code:

class A {
bool opEquals(A) { return false; }
}
class B : A {
bool opEquals(B) { return true; }
}

unittest {
B b1 = new B();
B b2 = new B();
A a1 = b1;
A a2 = b2;
assert(b1 == b2);
assert(a1 != a2); // WTF?
}

With the template solution, the function in B would be ignored
when stored in a variable with static type A. This solution would
sometimes do the right thing, other times it would silently do
the wrong thing.

Also, why it is limited to just objects? It seems that this
function enforces symmetry between two objects. What about rest
of the possible types, such as structs, unions?

That's an issue. The spec clearly states

2. [T]he expressions a.opEquals(b) and b.opEquals(a) are tried.
If both resolve to the same opEquals function, then the
expression is rewritten to be a.opEquals(b).
3. If one is a better match than the other, or one compiles and
the other does not, the first is selected.

4. Otherwise, an error results.

This is clearly not the case:

struct S1 {
bool opEquals(S2 a) {
return true;
}
}
struct S2 {
bool opEquals(S1 a) {
return false;
}
}

unittest {
S1 a;
S2 b;
assert((a == b) == (b == a)); // Fails
}

I didn't find a bugzilla entry on this, but I'm pretty sure there
is one.

As for why there's no global function like for classes, that's
because there's no need - there is no disconnect between the
static and dynamic types of non-class variables (or, if there is,
it's explicitly programmed in, like in std.variant.Variant).

--
Simen

```

### Re: Wrong selection of opEquals for objects.

```On Friday, 28 August 2020 at 08:16:01 UTC, Alexandru Ermicioi
wrote:

Hi everyone,

there is https://issues.dlang.org/show_bug.cgi?id=21180 bug,
anyone knows how to avoid it?

Test case:
-
import std;

class Silly {
bool opEquals(const Silly silly) const @safe {
return silly is this;
}

alias opEquals = Object.opEquals;
}

bool comp(T)() @safe {
return new T() == new T();
}

void main()
{
comp!Silly.writeln;
comp!(const Silly).writeln;
comp!(immutable Silly).writeln;
}
-

It always tries to call Object.opEquals, when narrower overload
should've been selected.

- Alex.

Essentially, this boils down to the issues described in
https://issues.dlang.org/show_bug.cgi?id=1824, and a host of
other bugzilla issues.

When you do a == b with a and b being class objects, it's lowered
to object.opEquals(a, b)[0], which casts both a and b to Object
before doing the comparison. So, you'll need to override
Object.opEquals to have the right function called:

class Silly {
int field;
this(int f) {
field = f;
}
override bool opEquals(Object o) {
auto silly = cast(Silly)o;

// If cast returns null, it's not a Silly instance
if (!silly) return false;

// Compare Silly objects
return field == silly.field;
}
}

unittest {
Silly a = new Silly(1);
assert(a == new Silly(1));
assert(a != new Silly(2));
}

That takes care of choosing the correct overload, but as you may
have noticed, there's another issue: your @safe function comp()
can't call the @system function object.opEquals. Since
object.opEquals operates on Object instances, not your specific
subclass, it has to assume the worst, and is @system. There's no
real good solution to that in the language as of now, and some of
us have been pulling our hair for years because of it.

What you'll need to do is mark every function that does compare
two class objects with == as @trusted or @system.

--
Simen

[0]:
https://github.com/dlang/druntime/blob/master/src/object.d#L166

```

### Re: Can a call to pragma(msg, __FILE__, ...) be mixin templatized?

```
On Tuesday, 18 August 2020 at 08:05:20 UTC, Per Nordlöw wrote:

On Tuesday, 18 August 2020 at 08:03:04 UTC, Per Nordlöw wrote:
Forgot to mention that I want to support variadic arguments to
`ctLog` similar to what is done with

And these arguments should be of any template argument kind,
not only a compile-time string.

I'm not a fan of string mixins (ask Adam how they're the scourge
of good programming, a wart on D's behind, and so on :p), but I
found no good way to do this without them:

string ctLog(Args...)(string file = __FILE__, size_t line =
__LINE__) {

import std.conv : to;
string result = `pragma(msg, "`~file~`(", `~line.to!string~`,
"): "`;

static foreach (e; Args) {
result ~= `, `~e.stringof;
}
return result~`);`;
}

mixin(ctLog!("This ", "is ", "module ", "scope."));
unittest {
mixin(ctLog!"function scope");
}
struct S {
mixin(ctLog!"Struct scope");
}

--
Simen

```

### Re: Can a call to pragma(msg, __FILE__, ...) be mixin templatized?

```
On Monday, 17 August 2020 at 21:18:41 UTC, Per Nordlöw wrote:

I'm using

pragma(msg, __FILE__, "(", __LINE__, ",1): Debug: ", "A
useful debug message");

to print compile-time information formatted as standard
compiler diagnostics.

These are picked up by Emacs Flycheck and overlayed in the
editor and listen in the *Flycheck errors* buffer. Very
convenient. When I want to get the type of something at
compile-time.

In order to not having to repeat oneself I'm now looking for a
way to extract this into a `mixin template`. Is this possible
somehow and still preserve the instantiation site values of
`__FILE__` and `__LINE__`?

mixin template ctLog(string msg, string file = __FILE__, size_t
line = __LINE__) {

pragma(msg, file, "(", line, "): ", msg);
}

mixin ctLog!"Module scope";
unittest {
mixin ctLog!"function scope";
}
struct S {
mixin ctLog!"Struct scope";
}

This works for me.

--
Simen

```

### Re: Template: get function name

```
On Monday, 17 August 2020 at 08:07:32 UTC, novice3 wrote:

Hello.
I have wrapping Windows API functions, wich return 0 on success
and erroro code on failure.

I copy wenforce template as:
```
private T denforce(T, S)(T value, lazy S msg = null, string
file = __FILE__, size_t line = __LINE__)

{
import core.sys.windows.winerror: NO_ERROR;
import std.conv: to;
if (value != NO_ERROR)
throw new WindowsException(value, to!string(msg), file,
line);

return value;
}
```

and use it:
```
DhcpEnumServers(0, null, servers, null,
null).denforce("DhcpEnumServers");

Then windows api - extern (Windows)DhcpEnumServers - return
error, then Windows exception throwed with name of failed api
"DhcpEnumServers".

Can we change template to avoid api name dublicate?
Can denforce template obtain "DhcpEnumServers" function name to
format message "DhcpEnumServers api failed"?

Thanks.

Take the function as an alias parameter and wrap the entire call:

auto denforce(alias fn, string file = __FILE__, size_t line =
__LINE__, Args...)(Args args) {

import core.sys.windows.winerror: NO_ERROR;
auto value = fn(args);
if (value != NO_ERROR) {
throw new WindowsException(value, __traits(identifier,
fn)~" api call failed.", file, line);

}
return value;
}

unittest {
denforce!DhcpEnumServers(0, null, servers, null, null);
}

For bonus points, you could also get the error message for the
returned error code:

string convertErrorCode(uint code) {
FORMAT_MESSAGE_FROM_SYSTEM, FORMAT_MESSAGE_IGNORE_INSERTS,
FORMAT_MESSAGE_FROM_HMODULE;

wchar[512] buf;

auto written = FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,

null,
code,
0,
buf.ptr, buf.length,
null);

if (!written) {
if (inst) {
written = FormatMessage(FORMAT_MESSAGE_FROM_HMODULE |
FORMAT_MESSAGE_IGNORE_INSERTS,

inst,
code,
0,
buf.ptr, buf.length,
null);
}
}
if (written) {
import std.conv : to;
return buf.ptr.to!string;
} else {
import std.format : format;
return format("An unknown error occured: %x", code);
}
}

unittest {
import core.sys.windows.winerror : ERROR_INVALID_FUNCTION;

import std.stdio;
writeln(convertErrorCode(ERROR_INVALID_FUNCTION));
writeln(convertErrorCode(1234567891));
}

--
Simen

```

### Re: Cannot call @system funciton (stdout)

```
On Saturday, 15 August 2020 at 23:59:36 UTC, Joel wrote:
../../JMiscLib/source/jmisc/base.d(176,2): Error: @safe
call @system function
std.stdio.makeGlobal!"core.stdc.stdio.stdout".makeGlobal
/Library/D/dmd/src/phobos/std/stdio.d(4837,20):
std.stdio.makeGlobal!"core.stdc.stdio.stdout".makeGlobal is
declared here

I got around it by avoiding 'stdout'.

First, what's wrong with using writeln and friends instead of
directly mucking about with stdout? :p

stdout is __gshared, so it's available on any thread at any time.
That's not @safe, so it's @system.

If you know you're not using stdout from multiple threads, or
don't care (it might be perfectly safe even though it's possible
to misuse), you can use this code:

@property File trustedStdout() @trusted
{
return stdout;
}

That's a @trusted wrapper that you can call from @safe code. It's
not actually safe though, as multiple threads could be using
trustedStdout at the same time. In many use cases, this is
unlikely to matter, but it's wroth keeping in mind.

--
Simen

```

### Re: can't access an alias created inside an if statement

```
On Wednesday, 5 August 2020 at 09:32:58 UTC, Flade wrote:
Thanks! You see it should work but the thing is. I'm using it
inside a function. I'm checking for one of the function's
parameter (if parameter == false) and it says that "the
variable `parameter` cannot be read at compile time. Do you
know if there is a way to fix this?

As the error message says, the value must be known at compile
time. Most likely, you can simply pass it as a template parameter:

void fun(bool parameter)(int arg1, string arg2) {
static if (parameter) {
}
}

void main() {
fun!true(1, "foo");
fun!false(19, "bar");
}

--
Simen

```

### Re: can't access an alias created inside an if statement

```
On Wednesday, 5 August 2020 at 09:05:36 UTC, Flade wrote:
I have used an if-else statement to create an alias to avoid
code duplication but it doesn't let me access it outside the if
statement. Is there a way to solve this?

You're probably looking for static if:

static if (useAlias) {
alias myAlias = getAlias!();
}

myAlias foo = getFoo();

What happens is a regular if statement introduces a scope, so
anything declared inside it is unavailable outside. static if
does not introduce a new scope, and so its contents can be
accessed.

static if only works with compile-time constant conditions, but
aliases are also compile-time constructs, so this should not pose
a problem.

--
Simen

```

### Re: miscellaneous array questions...

```On Tuesday, 21 July 2020 at 13:42:15 UTC, Steven Schveighoffer
wrote:

On 7/21/20 8:34 AM, Adam D. Ruppe wrote:

The others aren't wrong about stack size limits playing some
role, but the primary reason is that it is a weird hack for
@safe, believe it or not.

...
I don't recall exactly when this was discussed but it came up
in the earlier days of @safe, I'm pretty sure it worked before
then.

I think this was discussed, but was not the reason for the
limitation. The limitation exists even in D1, which is before
@safe: https://digitalmars.com/d/1.0/arrays.html#static-arrays

I have stressed before that any access of a pointer to a large
object in @safe code should also check that the base of the
object is not within the null page (this is not currently
done). This is the only way to ensure safety.

It seems the limitation was introduced in DMD 0.123, in May 2005:
https://forum.dlang.org/post/d61jpa\$1m0l\$1...@digitaldaemon.com
Walter gives some justification in the post immediately following:

1) Gigantic static arrays are often either the result of a typo
or are a

newbie mistake.
2) Such require a lot of memory for the compiler to handle.
Before the OS
officially runs out of memory, it goes to greater and greater
lengths to
scavenge memory for the compiler, often bringing the computer
to its knees

in desperation.
3) D needs to be a portable language, and by capping the array
size a

program is more likely to be portable.
4) Giant arrays are reflected in a corresponding giant size for
the exe

file.
5) There simply isn't a need I can think of for such arrays.
There shouldn't

be a problem with allocating them dynamically.

I admit I thought it was an old optlink limitation, but it seems
it's basically arbitrary.

--
Simen

```

### Re: What's the point of static arrays ?

```
On Friday, 10 July 2020 at 10:13:23 UTC, wjoe wrote:
However stack memory needs to be allocated at program start. I
don't see a huge benefit in allocation speed vs. heap
pre-allocation, or is there?
I mean 1 allocation vs 2 isn't going to noticeably improve
overall performance.

You seem to still be thinking of static arrays as the same kind
of "thing" as a dynamic array. They're (usually) more like ints
or structs than containers: they're generally small, they're
often parts of other structures or classes, and they're fairly
often the element type of a larger dynamic array. For instance, a
bitmap image could be a byte[4][][], with dynamic dimensions
3840x2160. If instead of byte[4] we used byte[], not only would
things grind to a halt immediately, we'd also be using massively
more memory.

When you're using a static array on the stack, it's usually just
because it's more convenient to say `int[16] buffer;` than `auto
buffer = new int[16];`. The fact it may be faster is mostly a
side benefit. Also, even if you did preallocate such a buffer,
there's the overhead of remembering how to get to it, the work of
setting it up, probably a function call on use, etc. The
alternative is terser, built-in, more obvious to maintainers,
pretty unlikely to overflow the stack, and very unlikely to be
slower. Allocating a multi-MiB static array on the stack is a
sign that you're using your screwdriver as a hammer, and there
are probably better ways to do what you're trying to do.

a[]

What happens here exactly ?

It creates a dynamic array that points to the data in the static
array. It's just shorthand for a[0..\$]:

unittest {
int[4] a = [1,2,3,4];

auto b = a[];
assert(b.length == 4);
assert(b.ptr == [0]);

auto c = a[0..\$];
assert(b is c);
}

--
Simen

```

### Re: What's the point of static arrays ?

```
On Thursday, 9 July 2020 at 12:12:06 UTC, wjoe wrote:
I'm not considering supposed performance benefits/penalties
because these need to be profiled.

Considering the many downsides why would I ever want to choose
a static over a dynamic array ?

Simply put: static arrays are not dynamic arrays, and if you try
to use one as the other you're going to be disappointed.

Usually, you use static arrays when you interface with something
else that does it - generally a file format or a C library. For
the most part you're right, you should probably use a dynamic

- Can neither grow nor shrink them
- Can't append elements
- Can't remove elements

These are the same as the first point.

- Can't slice them
- Can't range them

Sure you can:

unittest {
import std.stdio;
import std.algorithm;
int[10] a = [1,2,3,4,5,6,7,8,9,10];

// Note I'm slicing the static array to use in range
algorithms:

writeln(a[].map!(b => b+2));

// Slicing works:
auto b = a[3..6];
b[] = 7;
writeln(a);
}

- Assignment copies the whole array, as in int[5] a; auto b = a;

This is often a factor in choosing a static array. It's not
better or worse, just different. And sometimes it's different in
exactly the way you need.

- Size is limited by stack
- Stack overflow issues

So allocate your static array on the heap if this is a problem?

Some of the cons could be considered a feature.
Also GC but it's possible to make a dynamic array
implementation which avoids the GC.

Basically none of the drawbacks you refer to are actual
drawbacks, but instead part of what makes static arrays useful.
Static arrays are not a poor man's dynamic arrays, they're a
different beast, doing different things.

--
Simen

```

### Re: Progress printing with threads?

```
On Wednesday, 1 July 2020 at 07:52:28 UTC, AB wrote:
Hello. I am unsure how to proceed about printing progress in my
program.

Suppose the program is processing a very big file and is
iterating the file's bytes using a for loop. The processing
takes several minutes and I want a progress percentage be
printed every 2 seconds in this manner:

Progress: 0.40%
Progress: 3.20%
Progress: 5.73%

Is it a good idea to std.concurrency.spawn a new thread and
pass to it

cast(float)i * 100 / fileSize
somehow? If not, what's a better way to do this?

This example code shows my situation:

MmFile  input   = new MmFile(/* ... */);
ulong   fileSize= input.length;

for (ulong i = 0; i < fileSize; ++i)
{
// ...
}

If doing the update in the same thread that does the processing
is somehow not an option, this works for me:

import std.concurrency;
import std.stdio;
import core.time;

void main() {
ulong filesize = 1234;
ulong i = 0;
Tid progress = spawn((shared const(ulong)* p, ulong f){
while (!receiveTimeout(2000.msecs, (int i){ })) {
writeln(*p, "/", f, ": ", *p*100.0/f, "%");
}
}, cast(shared), filesize);
for (; i < filesize; ++i) {
// Process
}
progress.send(0); // Stop
}

There's a cast to shared there which may be suboptimal, but since
the progress thread is only reading it, I would say it's ok.

--
Simen

```

### Re: Generating struct members from c structs

```
On Wednesday, 1 July 2020 at 07:26:44 UTC, Anthony wrote:
When doing interop with a c library, is there a way to
automatically generate the fields that are needed for a struct?

[snip]

Is there an easier way though?

Dstep is probably what you're looking for:
https://github.com/jacob-carlborg/dstep

It eats C header files and creates appropriate D files from them.

--
Simen

```

### Re: scope guard question

```On Tuesday, 30 June 2020 at 12:18:14 UTC, Steven Schveighoffer
wrote:
I can see where it would be confusing, and it could probably
contain an example and clarification.

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

```

### Re: How to implement Canceleable spawn() from parent

```
On Tuesday, 30 June 2020 at 13:44:38 UTC, aberba wrote:

On Tuesday, 30 June 2020 at 12:48:32 UTC, Simen Kjærås wrote:

On Tuesday, 30 June 2020 at 08:15:54 UTC, aberba wrote:

On Tuesday, 30 June 2020 at 00:33:41 UTC, Ali Çehreli wrote:

On 6/29/20 4:34 PM, aberba wrote:

> So with this, without the Thread.sleep() to block main from
exiting, the
> spawned thread  will terminate immediately.

So I tried that initially but my (){ writeln(...) } wasn't
printing anything in console. Could that be related to stdout
buffering? The program kept running though.

So I guess the error is elsewhere, but I'm not sure where and
how.

try something and forgot to change it back.

Jeez, I hate myself.

Thanks.

library user doesn't have to type it themselves in main() ? I
don't see how that can be done.

__gshared Tid mainTid;
static this() {
if (mainTid.tupleof[0] is null) {
mainTid = thisTid;
}
}
static ~this() {
if (thisTid == mainTid) {
}
}

The above code does the trick.

So, what does it do? __gshared means 'this variable is accessible
it gets to store its Tid in mainTid, and every other thread will
see a populated mainTid and leave it alone. In the module
destructor, which runs after main(), we call thread_joinAll() iff

Now, why should you not do this? Well first, instead of getting a
tidy crash you get a process that doesn't end. Second, there's
the race conditions described below. Third, there's the principle
of least astonishment. D programmers expect that when main()
returns, the program will exit shortly(ish), while this zombie
could continue running indefinitely.

--
Simen

*I'm pretty sure this is possibly wrong, if a module constructor
spawns a new thread. There's also a possible race condition where
newly spawned modules may conceivably not see a properly
initialized mainTid.

```

### Re: How to implement Canceleable spawn() from parent

```
On Tuesday, 30 June 2020 at 08:15:54 UTC, aberba wrote:

On Tuesday, 30 June 2020 at 00:33:41 UTC, Ali Çehreli wrote:

On 6/29/20 4:34 PM, aberba wrote:

> So with this, without the Thread.sleep() to block main from
exiting, the
> spawned thread  will terminate immediately.

So I tried that initially but my (){ writeln(...) } wasn't
printing anything in console. Could that be related to stdout
buffering? The program kept running though.

Seems weird. This works great on my machine:

import core.time : Duration, msecs;
import std.concurrency : spawn, Tid, send, receiveTimeout;
import std.stdio : writeln;

private struct IntervalStop {}

Tid setInterval(Duration dur, void function() fn) {
return spawn((Duration d, void function() f){
f();
}
}, dur, fn);
}

void stopInterval(Tid tid) {
tid.send(IntervalStop());
}

void main() {
auto a = setInterval(1000.msecs, (){ writeln("Hello from

// Stop it before it happens
stopInterval(a);

auto b = setInterval(1000.msecs, (){ writeln("Hello from

// Let this one run a little
stopInterval(b);

auto c = setInterval(1000.msecs, (){ writeln("Hello from
// Sending the wrong message doesn't make it happen or stop
prematurely

c.send("Stop this at once!");
stopInterval(c);

}

So I guess the error is elsewhere, but I'm not sure where and how.

--
Simen

```

### Re: Unused template arguments; what type to use?

```
On Friday, 26 June 2020 at 13:21:25 UTC, drathier wrote:
How can I tell the compiler that I will never create a value of
type X, while still being able to write code that uses it?
Using void as a template parameter is where I started, but I
still need to be able to declare variables inside this
unreachable function, like `T foo;` even when `T == void`. Can
I get any closer to what I want than an empty struct?

Depends on what you care about, I guess. A final abstract class
has been my go-to on a few occasions. I'd argue the empty struct
is better in most cases, and a forward-declared struct with no
implementation might work in some cases.

--
Simen

```

### Re: Flagging special conditions on return from a function call

```
On Tuesday, 23 June 2020 at 04:01:45 UTC, Denis wrote:
(1) Assign an unused value for the flag (e.g. -1 when the
function returns an int), and return the combined value/flag.

This happens in some Phobos algorithms, and might be the most
common on this list.

(2) Return a tuple with the value and the flag
(3) Return a struct or tuple with named value and flag members

Would certainly work, but I don't think it's common in D.

(4) Set the function return value normally, and put the flag in
an "out" variable passed as an argument to the function
(5) Return the flag, and put the value in an "out" variable
passed to the function (i.e. the reverse of #4)

Both of these happen. I don't know which is more common. In C#
these are probably the most common way (except for exceptions) to
signal these cases.

(6) Use two separate functions, one that returns the value, and
another that can be called afterwards to check the flag (like
eof(), for example)

(7) Use a side effect and set a designated global variable

Global variables are frowned upon, so probably not this. :p

One thing I feel is missing here (perhaps because
std.variant.Algebraic is egregious):

(8) Return a Maybe!T or Algebraic!(T, ErrorCode)

It's what I personally would prefer, but I have only rarely seen
it in D code. Given a properly written Maybe, this could enforce
proper handling of the error case, either by throwing on trying
to get at Maybe!T.getValue when it's holding None, or by
presenting an interface that only compiles when both cases are
covered, like fun().match((T t) => t, () => Error()).

--
Simen

```

### Re: Parallel array append using std.parallelism?

```
On Thursday, 18 June 2020 at 14:43:54 UTC, H. S. Teoh wrote:
I have an array of input data that I'm looping over, and, based
on some condition, generate new items that are appended onto a
target array (which may already contain data). Since the
creation of new items is quite expensive, I'm thinking to
parallelize it with parallel foreach.

To avoid data races, my thought is for each generated item to
be appended to thread-specific temporary arrays, that after the
parallel foreach get sequentially appended to the target array.
Something like this:

Item[] targetArray = ...; // already contains data
foreach (elem; input.parallel) {
if (condition(elem)) {
auto output = expensiveComputation(elem);
}
}
foreach (a; tmp)
targetArray ~= a;

Is there an easy way to achieve this with std.parallelism?  I
looked over the API but there doesn't seem to be any obvious
way for a task to know which thread it's running in, in order
to know which tmp array it should append to.  If possible I'd

There's an example of exactly this in std.parallelism:

In short:

Item[] targetArray = ...; // already contains data
foreach (elem; input.parallel) {
if (condition(elem)) {
auto output = expensiveComputation(elem);
// Use workerIndex as index
}
}
foreach (a; tmp)
targetArray ~= a;

--
Simen

```

### Re: Should a parser type be a struct or class?

```
On Wednesday, 17 June 2020 at 11:50:27 UTC, Per Nordlöw wrote:
Should a range-compliant aggregate type realizing a parser be
encoded as a struct or class? In dmd `Lexer` and `Parser` are
both classes.

In general how should I reason about whether an aggregate type
should be encoded as a struct or class?

The heuristic I use is 'do I need polymorphism?' If no, it's a
struct. Another thing that may be worth considering is reference
semantics. The latter is easy to do with a struct, while
polymorphism is generally a class-only thing (but check out
Tardy, which Atila Neves recently posted in the Announce group).

I would say I basically never use classes in D - pointers and
arrays give me all the reference semantics I need, and
polymorphism I almost never need.

--
Simen

```

### Re: `this` template params for struct not expressing constness.

```
On Monday, 8 June 2020 at 09:08:40 UTC, adnan338 wrote:

On Monday, 8 June 2020 at 08:10:19 UTC, Simen Kjærås wrote:

On Monday, 8 June 2020 at 07:35:12 UTC, adnan338 wrote:

Self* searchTree(this Self)(auto in ref T item) const {
if ( is null)
return null;
if (this.item == item)
return
return (this.item < item) ?
this.right.searchTree(item) :
this.right.searchTree(item);
}

This method is const, which means 'this' is const, while Self
is not. What you're looking for here is inout
(https://dlang.org/spec/function.html#inout-functions):

auto searchTree()(auto in ref T item) inout {
if ( is null)
return null;
if (this.item == item)
return
return (this.item < item) ?
this.right.searchTree(item) :
this.right.searchTree(item);
}

--
Simen

Thank you. Few followup questions, if you don't mind.

1. What does that blank template parameter mean?

Just forces the function to be a template. The only reason for
this is it's required for auto ref to work, which you may or may
not need on that function.

2. Since `inout` acts as a wildcard for
immutable/const/non-const qualifiers, what should I do to have
the compiler ensure that my method does not mutate a non-const
tree inside the body?

Inside inout functions, `this` is treated as const - any attempt
to modify it should give a compile error. Since D const is
transitive, anything reachable from `this` is also treated as
const.  If you're able to mutate a non-const tree inside the
body, there's a bug in the compiler.

--
Simen

```

### Re: `this` template params for struct not expressing constness.

```
On Monday, 8 June 2020 at 07:35:12 UTC, adnan338 wrote:

Self* searchTree(this Self)(auto in ref T item) const {
if ( is null)
return null;
if (this.item == item)
return
return (this.item < item) ?
this.right.searchTree(item) :
this.right.searchTree(item);
}

This method is const, which means 'this' is const, while Self is
not. What you're looking for here is inout
(https://dlang.org/spec/function.html#inout-functions):

auto searchTree()(auto in ref T item) inout {
if ( is null)
return null;
if (this.item == item)
return
return (this.item < item) ?
this.right.searchTree(item) :
this.right.searchTree(item);
}

--
Simen

```

### Re: how to append (ref) int[] to int[][]?

```
On Monday, 8 June 2020 at 06:13:36 UTC, mw wrote:

Hi,

I have this program:

import std.stdio;

void f(ref int[] arr) {
arr ~= 3;
}

void main() {
int[][] arrs;
int[] arr;
foreach (i; 0 .. 3) {
arr = new int[0];
arrs ~= arr; //(a) [[], [], []]
f(arr);
// arrs ~= arr; //(b) [[3], [3], [3]]
}

writeln(arrs);
}

This program will print out [[], [], []].

If I comment out (a), and use (b), it will print out [[3], [3],
[3]]

So based on this behavior, looks like "~=" will append a copy
of `arr`; but what I really want in (a) is append `ref arr` and
output [[3], [3], [3]], i.e. the real `arr` be appended instead
of its copy.

I have to say this semantics surprised me.

I tried to change arrs' decl to:

(ref (int[]))[] arrs;  // the intended semantics I want

But I got compiler error out: "found ( when expecting function
literal following ref".

1) I'm wondering how to achieve what I want? and
2) why "~=" here will append a copy rather than the real `arr`
itself to arrs?

Arrays (technically, slices) in D are essentially this struct:

struct Array(T) {
T* ptr;
size_t length;
}

So when you have int[][], each element of the outer array is an
Array!int. These, as simple structs, are copied about, so that
changing one does not change another.

The simple solution here is to call f not on arr, but on
arrs[\$-1] (the last element of arrs). If that is not possible you
will need arrs to be an int[]*[].

--
Simen

```

### Re: Fastest way to check using if identifier has already been defined, using static if or similar?

```
On Wednesday, 3 June 2020 at 15:25:51 UTC, Paul Backus wrote:

On Wednesday, 3 June 2020 at 13:24:17 UTC, Basile B. wrote:
This is because the template parameter must be resolved to a
valid symbol or type.

This version other version bypass the problem:

---
enum Exists(string s) = is(typeof(mixin(s)));

void main()
{
static if (!Exists!"foo")
int foo;
foo = 42;
}
---

Fails if the symbol in question is the name of a type.

struct Foo {}
enum Exists(string s) = is(typeof(mixin(s)));
static assert(Exists!"Foo"); // false

What you actually want is something like this:

enum Exists(string s) = __traits(compiles, { mixin("alias _
= ", s, ";"); });

And they both fail if the thing you refer to isn't available in
the scope where Exists is defined. I believe this covers most
cases, but there may very well be corner cases I haven't
considered:

string exists(string s) {
return "__traits(compiles, { mixin(\"alias _ = "~s~";\"); })";
}

// Handles values:
int global;
unittest {
int local;
{
int outOfScope;
}
static assert(mixin("local".exists));
static assert(mixin("global".exists));
static assert(!mixin("outOfScope".exists));
}

// And types:
struct Global {}
unittest {
struct Local {}
{
struct OutOfScope;
}
static assert(mixin("Global".exists));
static assert(mixin("Local".exists));
static assert(!mixin("OutOfScope".exists));
}

// But not expressions:
static assert(!mixin("1+2".exists));
// Correctly fails for missing declarations:
static assert(!mixin("nowhere".exists));

Like Stefan said though, we're quite a bit off from the original
request - the above certainly shouldn't be faster than drathier's
original code. The only advantage I see is that it might read a
little clearer.

--
Simen

```

### Re: Fastest way to check using if identifier has already been defined, using static if or similar?

```
On Wednesday, 3 June 2020 at 09:39:34 UTC, Basile B. wrote:

You can use this template:

enum Exists(alias T) = is(typeof(T));

I don't know if there's a faster way bu this technic is used,
notatbly in phobos, to workaroud issues of double declaration
in `static foreach`

enum Exists(alias T) = is(typeof(T));
static assert(!Exists!bar); // undefined identifier bar

--
Simen

```

### Re: Unable to access a variable declared inside an if statement (Error: is shadowing variable)

```
On Wednesday, 27 May 2020 at 11:03:51 UTC, BoQsc wrote:
I'm lacking knowledge on how to achieve what I want and getting
an error.
What is the correct way to do what I tried to achieve in this
code?
Everything was intuitive until I started to add notice variable
to the writeln. Rdmd says  variable `notice` is shadowing
variable.

if (driveLetter.exists){
auto directory = "/Backup";
if ((driveLetter ~ directory).exists){
auto notice = "Backup directory exists.";

}
writeln(driveLetter, notice);
}

Variables only live in a specified scope, starting from where
they are declared, and ending when they reach the '}' indicating
the end of said scope.

In you case, 'notice' only lives inside the if ((driveLetter ~
directory).exists) scope, and doesn't exist outside. In order to
fix this, you will need to declare it outside:

if (driveLetter.exists) {
auto directory = "/Backup";
auto notice = "Backup directory does not exist.";
if ((driveLetter ~ directory).exists) {
notice = "Backup directory exists.";
}
writeln(driveLetter, notice);
}

This also makes it clearer what value 'notice' will have when the
backup directory doesn't exist - in your case you haven't
assigned it any value in that case.

--
Simen

```

### Re: opEquals @safe is ignored

```
On Sunday, 24 May 2020 at 08:57:28 UTC, Luis wrote:

dmd ignores @trusted or @safe on opEquals, throwing this error :

onlineapp.d(27): Error: @safe function
onlineapp.__unittest_L24_C7 cannot call @system function
object.opEquals

An override @system or @trusted function can't be @safe, or I
it a bug ?

Also, how will this be affected by DIP1028 ?

Looking at the output, it's actually druntime's opEquals that
can't be called. That's the global function that ensure opEquals
is called on both sides of the comparison, and it's not @safe.
This makes classes even worse to use in D than, and I'm not sure
how to properly handle this. If we make it @trusted, suddenly I
can call @system opEquals from @safe functions without issue.

Root cause is, classes in D all inherit from Object, which has
some defaults that aren't always what you want. It seems DIP1028
will make your code automatically compile, along with this:

class C {
override bool opEquals(Object o) @system {
*cast(int*)123456 = 3;
return true;
}
}

@safe void mySafeFunction() {
assert(new C() == new C());
}

--
Simen

```

### Re: Assignment of tuples

```On Wednesday, 20 May 2020 at 13:51:05 UTC, Steven Schveighoffer
wrote:

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

--
Simen

```

### Re: Bug?

```
On Monday, 11 May 2020 at 12:44:45 UTC, Jack Applegame wrote:

On Monday, 11 May 2020 at 12:30:22 UTC, Adam D. Ruppe wrote:
UFCS is only defined to work with global scope functions. A
restricted import (module : symbol, symbols) puts things in
local scope so ufcs doesn't apply.

But in this case the error should be displayed for lines 4 and
5, not 11.

Line 11 contains a call to a member function, not UFCS.

assert(rng.front() == '1');

You're right, and it absolutely seems the call on lines 4 and 5
work correctly. Instead, the compiler is confused by the presence
of two different overloads for front in Range!T, and doesn't
attempt to call the one it can call. We get the exact same
behavior here:

struct S {
int gun()(int i) { return 0; }
alias fun = gun;
int fun() { return 1; }
}

static assert(S().fun == 1);

Filed here: https://issues.dlang.org/show_bug.cgi?id=20821

--
Simen

```

### Re: What could this be?

```
On Monday, 11 May 2020 at 11:20:51 UTC, Joel wrote:
I'm gotten stuck with this error - "..is not visible from
module.."

Without some code it's hard to say exactly, but this generally
means you're referencing a private symbol in a different module:

module foo;
private struct S {}

module bar;
import foo;
foo.S s; // foo.S is not visible from module bar

--
Simen

```

### Re: How does a free list work?

```
On Saturday, 9 May 2020 at 19:54:44 UTC, Pavel Shkadzko wrote:
https://wiki.dlang.org/Memory_Management and found an example
of a free list (pattern?): "Free lists are a great way to
type.".

Here is the example of free list:
---
class Foo
{
static Foo freelist; // start of free list
Foo next; // for use by FooFreeList

static Foo allocate()
{
Foo f;

if (freelist)
{
f = freelist;
freelist = f.next;
}
else
f = new Foo();
return f;
}

static void deallocate(Foo f)
{
f.next = freelist;
freelist = f;
}
}
---

Do I understand correctly that by switching between static and
non-static Foo we keep the object from being garbage collected
by the GC? So in a situation when I need to create an object
and then discard it, I can implement this pattern to use memory
more efficiently.

Also, it's a little strange that since both f and freelist are
null we are basically doing null = null in first if condition.

The GC keeps a list of roots - that is, objects that are known to
be active and should not be collected. The static freelist is one
of those - since it's static it should of course never be
collected.

From these roots, the GC scans all referenced objects
recursively, and finally releases all memory that has not been
scanned (and that thus have no path of pointers leading from a
root to that memory).

Since any call to new will check if memory is available, and
potentially trigger a GC collection, it can be expensive, so if
you can avoid allocating and deallocating objects a lot, it's an
easy optimization.

To more clearly show this, here's some code that prints what it
does:

import std.stdio : writeln;

class Foo {
static Foo freelist;

Foo next;
string name;
this(string name) {
this.name = name;
}
~this() {
writeln("GC collecting ", name);
}

static Foo allocate(string name) {
if (freelist) {
auto f = freelist;
freelist = f.next;
writeln("Fetching ", f.name, " from freelist,
changing name to ", name);

f.name = name;
return f;
}
writeln("Nothing in freelist, allocating new ", name);
return new Foo(name);
}

static void deallocate(Foo f) {
writeln("Adding ", f.name, " to freelist, freelist.next
points to ",

freelist ? freelist.name : "(null)");
f.next = freelist;
freelist = f;
}
}

unittest {
Foo a = Foo.allocate("A");
Foo b = Foo.allocate("B");
Foo c = Foo.allocate("C");
Foo.deallocate(a);
Foo.deallocate(b);
a = null;
b = null;
c = null;

import core.memory;
GC.collect();
// For some reason I need to call this twice for C to be
collected?

GC.collect();

Foo d = Foo.allocate("D");
Foo e = Foo.allocate("E");
Foo f = Foo.allocate("F");
}

The above code creates this output:

Nothing in freelist, allocating new A
Nothing in freelist, allocating new B
Nothing in freelist, allocating new C
Adding A to freelist, freelist.next points to (null)
Adding B to freelist, freelist.next points to A
GC collecting C
Fetching B from freelist, changing name to D
Fetching A from freelist, changing name to E
Nothing in freelist, allocating new F
1 unittests passed
GC collecting E
GC collecting D
GC collecting F

Here's what it does in more words:

For the first call to allocate(), the freelist is null, and a new
Foo is created in the 'else' path, before being returned. Nothing
is assigned to freelist or next.

The second and third call does the exact same thing, since
nothing has been assigned to the freelist.

We then deallocate a, which assigns it to the freelist. Next we
deallocate b, which sets b's 'next' field to point at a, and sets
freelist to point at b. We then set a, b, and c to null, so those
references will no longer keep the Foos alive.

Then we call GC.collect, which finds that the Foo previously
stored in b is now in freelist, and thus will be kept. The Foo
that was in a is referenced by freelist.next, and will also live.
The foo in c, however, is no longer referenced anywhere, and will
be collected.

This shows the main point of the freelist - to ensure the objects
aren't collected by the GC - but what happens afterwards?

When we allocate d, freelist points at the Foo that used to be
stored in b, so it is returned from allocate(), and the freelist
is changed to point to the Foo that used to be in a.

Allocating e there's still something in freelist, so it is
returned. At this point the freelist is empty, and allocating f
creates a new Foo, just like when we allocated a, b, and c.

--
```

### Re: XMM Intrinsics

```
On Friday, 8 May 2020 at 13:09:49 UTC, kinke wrote:

On Friday, 8 May 2020 at 12:49:00 UTC, Simen Kjærås wrote:
How would I go about calling _mm_* functions in D in a way
that is portable between D compilers?

You would use core.simd:

Nope one wouldn't, because that horrible interface isn't
supported by LDC, and I guess GDC neither.

The intel-intrinsics dub package aims to provide a
compiler-independent layer:
https://code.dlang.org/packages/intel-intrinsics

TIL, thanks! :)

--
Simen

```

### Re: XMM Intrinsics

```
On Friday, 8 May 2020 at 12:38:51 UTC, Marcio Martins wrote:

Hi,

I am building a CRC32C implementation using SSE for D, because
I couldn't find any readily available :[

However, I am unable to find any documentation regarding which
SSE instructions are available and how I could use them in D. I
can see core.simd can't seem to make any use of it.

How would I go about calling _mm_* functions in D in a way that
is portable between D compilers?

You would use core.simd:

https://dlang.org/library/core/simd.html

Sadly, the supported instructions are not documented on that
page, and you'll need to look at the source to get at them:

https://github.com/dlang/druntime/blob/master/src/core/simd.d#L85-L384

(I'll file a bug on this)

https://dlang.org/spec/simd.html

--
Siomen

```

### Re: Is there a way to benchmark/profile portably?

```
On Thursday, 7 May 2020 at 10:21:07 UTC, Dukc wrote:
Is there some way to measure the performance of a function so
that the results will be same in different computers (all x86,
but otherwise different processors)? I'm thinking of making a
test suite that could find performance regressions
automatically.

I figured out Bochs[1] could be used for that, but it seems an
overkill for me to install a whole virtual operating system
just to benchmark functions. Does anybody know more lightweight
way?

[1] http://bochs.sourceforge.net/

If I understand correctly, you want to measure how many cycles
pass, rather than clock time?

If so, it seems perf can do that:
https://perf.wiki.kernel.org/index.php/Tutorial

--
Simen

```

### Re: variant visit not pure?

```
On Thursday, 7 May 2020 at 09:22:28 UTC, learner wrote:

Good morning,

Is there a reason why std.variant.visit is not inferring pure?

```
void test() pure {
Algebraic!(int, string) alg;
visit!( (string) => 0, (int) => 0)(alg);
}

Error: pure function test cannot call impure function
test.visit!(VariantN!(16LU, int, string)).visit

```

std.variant.Algebraic is essentially a std.variant.Variant in
different clothes. Variant is very flexible, and this comes at a
cost (and isn't used in Algebraic, meaning you pay for things you
don't use). Like Dukc said, you might be better off with
Taggedalgebraic or SumType
(https://code.dlang.org/packages/sumtype).

Variant uses runtime type information to hold *any* type. Since
Algebraic specifically only holds a few types, all the framework
that's in place for Variant is wasted on Algebraic, and makes it
less useful and less performant.

--
Simen

```

### Re: Bug?

```
On Tuesday, 5 May 2020 at 04:02:06 UTC, RazvanN wrote:

truct K
{
~this() nothrow {}
}

void main()
{
static class C
{
this(K, int) {}
}

static int foo(bool flag)
{
if (flag)
throw new Exception("hello");
return 1;
}

try
{
new C(K(), foo(true));
}
catch(Exception)
{
}
}

Result:

object.Exception@test.d(18): hello

If the destructor of K is not marked nothrow the code does not
throw an exception. Is this a bug or am I missing something?

Surely the above code, which silently discards the exception,
does not print "hello"?

Regardless, I ran your code with writeln inside the catch(), and
without the try-catch entirely, with and without nothrow on K's
destructor. I am unable to replicate the issue on my computer
with DMD 2.091.0, as well as on run.dlang.io. Is something

--
Simen

```

### Re: Aliasing current function template instance

```
On Friday, 1 May 2020 at 20:28:58 UTC, Jean-Louis Leroy wrote:
Is it possible, inside a function template, to create an alias
to the instantiated function? IOW the equivalent of
__FUNCTION__, but yielding an alias?

The closest I came is:

import std.string;
import std.traits;

void foo(T)(lazy T)
{
mixin(
"alias thisFunction = ",
__FUNCTION__[0..__FUNCTION__.lastIndexOf('.')],
";");
pragma(msg, Parameters!thisFunction);
}

void main()
{
foo(0);
foo("");
}

dmd -c aliasthisfunction.d
(lazy int)
(lazy string)

...but (unsurprisingly) this fails in presence of overloads.
I.e. if I throw in:

void foo(T)(int, T);

...then I get:

aliasthisfunction.d(6): Error: template
`aliasthisfunction.foo` matches more than one template
declaration:

aliasthisfunction.d(4): `foo(T)(lazy T)`
and
aliasthisfunction.d(20): `foo(T)(int, T)`
...

Something I have overlooked? Any ideas?

This should work:

alias context(alias a) = __traits(parent, a);

void fun() {
alias ctx = context!({})();
}

{} becomes a lambda inside fun(), so it's parent is fun(). The
same could be done by introducing a symbol explicitly, but that
pollutes the namespace. This template works inside functions,
methods, lambdas, modules, structs, classes and interfaces.

--
Simen

```

### Re: Can't recreate a range?

```
On Thursday, 30 April 2020 at 13:23:25 UTC, Paul Backus wrote:

On Thursday, 30 April 2020 at 13:04:47 UTC, Casey wrote:

Here's a minimal code example that duplicates the issue:

import std.array, std.range, std.stdio, std.traits, std.string;

auto readStream(Range)(auto ref Range r) if
(isInputRange!(Unqual!Range))

{
struct StreamRange(Range)
{
alias R = Unqual!Range;
R _input;

auto buff = appender!string;

Using a default value like this means that it will be shared
among all instances of the struct. Instead, you should set
`buff = appender!string` in the constructor, so that each
struct will have its own appender.

Yup, that's the one. No need to assign it at all, in fact - the
line can be replaced with

Appender!string buff;

And things just work.

--
Simen

```

### Re: Can't recreate a range?

```
On Wednesday, 29 April 2020 at 20:43:20 UTC, Casey wrote:

void popFront()
{
}

I mean, it might be you messed up in posting this, but having an
empty popFront and expecting it to do something is a tad
optimistic.

Apart from that, it seems like the code should do what you want
it to. What's the value of count when the code asserts? I'm
afeared we'll need some code that actually compiles and shows off
the issue to give any more answers.

--
Simen

```

### Re: Can’t use UFCS to create InputRange?

```
On Wednesday, 29 April 2020 at 09:16:58 UTC, user1234 wrote:
The static checker doesn't see your free funcs because to do so
it would have to import the whole module. (is it possible to do
that ? no idea.)

Of course it's possible! :) We can find the context of R (in this
case, the module) with __traits(parent), and import that:

mixin("import "~__traits(parent, R).stringof["module
".length..\$]~";");

However, doing that in isInputRange doesn't help much. First, all
other range functions would have to do it, and second, just
importing into function scope doesn't enable UFCS lookup.

Also your signature for the primitives are quite unusual (i.e
not idiomatic). Usually they dont take param. Usually we pass a
type that contains the member funcs matching to IsIntputRange.

You can see a good counterexample to this in
https://dlang.org/library/std/range/primitives/pop_front.html,
which defines popFront for regular arrays. However, that is the
one and only counterexample I know of.

Of course, nothing stops us from defining our own front, popFront
and friends that combine the two approaches above:

template front(R) {
auto front(R r) {
return __traits(getMember, __traits(parent, R),
"front")(r);

}
}
template popFront(R) {
auto popFront(R r) {
return __traits(getMember, __traits(parent, R),
"popFront")(r);

}
}
template empty(R) {
auto empty(R r) {
return __traits(getMember, __traits(parent, R),
"empty")(r);

}
}

We could conceivably add these to std.range.primitives (probably
adding some constraints first), and suddenly UFCS ranges are
possible! (I am as of yet not convinced that we should, though)

--
Simen

```

### Re: Can’t use UFCS to create InputRange?

```
On Wednesday, 29 April 2020 at 08:34:53 UTC, Ogi wrote:

struct R {}
int front(R r) { return 42; }
void popFront(R r) {}
bool empty(R r) { return false; }

void main() {
import std.range.primitives : isInputRange;
static assert(isInputRange!R);
}

Error: static assert:  `isInputRange!(R)` is false

What’s going on here?

The template IsInputRange is in the std.range.primitives module,
and thus can't see the front, popFront and empty definitions in

--
Simen

```

### Re: How convert String to Hex?

```
On Saturday, 18 April 2020 at 15:47:38 UTC, Marcone wrote:

How convert String to Hex?

Example:

string text = "Hello World"; // Converted to Hex =
48656c6c6f20576f726c64

import std.format : format;

string hex = format("%(%2x%)", "Hello World");

import std.stdio : writeln;
writeln(hex);

A bit of explanation: %(  %) is a range formatting specifier, and
basically means "format each element of the range with the format
specifier between these two symbols". In other words, it's the
equivalent of "Hello World".map!(c => format("%2x", c)).joiner.

--
Simen

```

### Re: Extracting user defined attributes on function parameters

```
On Saturday, 18 April 2020 at 09:19:48 UTC, Simen Kjærås wrote:
On Wednesday, Friday, 17 Apr 2020 17:45:47 UTC, H. S. Teoh
wrote:

I wonder if the ultimate cause of the above case is ultimately
caused by
the change to import semantics that hid private symbols from
outside the
module. Perhaps something, somewhere, is triggering an illegal
access of
a private symbol, which percolates up the call/instantiation
stack and

causing what appears to be a strange compiler discrepancy.

Not unlikely. Importing the module defining S in the module
defining ParameterDefaults does indeed make things compile.
Hiding S by making it private makes the error return.

It's not about private. Or even if it is, there's other issues.
Proof:

struct A {
struct S {}
void f(@S int = 3);
pragma(msg, Issue20744!f);
}

template Issue20744(func...) {
static if (is(typeof(func[0]) PT == __parameters)) {
alias Issue20744 = (PT args) {};
}
}

--
Simen

```

### Re: Extracting user defined attributes on function parameters

```
On Wednesday, Friday, 17 Apr 2020 17:45:47 UTC, H. S. Teoh wrote:

I wonder if the ultimate cause of the above case is ultimately
caused by
the change to import semantics that hid private symbols from
outside the
module. Perhaps something, somewhere, is triggering an illegal
access of
a private symbol, which percolates up the call/instantiation
stack and

causing what appears to be a strange compiler discrepancy.

Not unlikely. Importing the module defining S in the module
defining ParameterDefaults does indeed make things compile.
Hiding S by making it private makes the error return.

(for whatever reason your message isn't visible in the web
interface)

--
Simen

```

### Re: Extracting user defined attributes on function parameters

```
On Friday, 17 April 2020 at 16:54:42 UTC, Adam D. Ruppe wrote:

This part seems fine...

pragma(msg, ParameterDefaults!f.stringof);

It is this, specifically, that causes the problem. Replace it
with:

void main() {
import std.stdio;
writeln(ParameterDefaults!f.stringof);
}

and it is fine.

So pragma(msg) is doing something really weird, the bug doesn't
appear to be in Phobos per se, I think it is the compiler doing
the wrong thing, it seems to me it works inside a function
scope but not at module scope..

It's even more fascinating - the issue doesn't occur if
ParameterDefaults is defined in the same module that it's used
in, and it works if there's a type with the same name as the UDA.
Reducing the code as much as I can, I get this:

struct S {}

void f(@S int = 3);

pragma(msg, ParameterDefaults!f.stringof);

template ParameterDefaults(func...) {
import std.traits : FunctionTypeOf;
static if (is(FunctionTypeOf!(func[0]) PT == __parameters)) {
enum ParameterDefaults = (PT[0..1] args) @trusted {
return *&(args[0]);
}();
}
}

The above code works, and prints "3". If you move
ParameterDefaults to a different module, something like this:

-

import bar;

struct S {}

void f(@S int = 3);

pragma(msg, ParameterDefaults!f.stringof);

-

module bar;

template ParameterDefaults(func...) {
static if (is(typeof(func[0]) PT == __parameters)) {
enum ParameterDefaults = (PT[0..1] args) @trusted {
return *&(args[0]);
}();
}
}
-

some kind of S to bar, and you get an error message about S not
being readable at compile-time or things just work if it is
readable. It seems the UDA is being looked up in the wrong
context.

--
Simen

```

### Re: Checked!({short, ushort, byte, ubyte}, Throw): compilation fails

```
On Friday, 17 April 2020 at 08:59:19 UTC, kdevel wrote:

On Friday, 17 April 2020 at 04:29:06 UTC, Meta wrote:
Unlike C/C++, char is not a numeric type in D; It's a UTF-8
code point:

Thanks, it's a code /unit/. main reads now:

void main ()
{
bar!ubyte;
bar!byte;
bar!ushort;
bar!short;
bar!uint;
bar!int;
bar!ulong;
bar!long;
}

and dmd complains:

The problem is, short/short gives an int answer:

unittest {
import std.experimental.checkedint;
Checked!(short, Throw) a;
pragma(msg, typeof(a/a));
}

So, in your code you get this situation:

unittest {
import std.experimental.checkedint;
Checked!(int, Throw) a;
Checked!(short, Throw) b = a;
}

And assigning from an int to a short may discard data, so it's
statically disallowed by Checked. This is a deliberate design
choice, and the appropriate way to handle it is with a cast:

unittest {
import std.experimental.checkedint;
Checked!(int, Throw) a = 65535;
Checked!(short, Throw) b = cast(short)a;
}

The above code will throw when casting (before the assignment),
because 65535 can't fit in a short.

You also get a deprecation message, about an integral promotion
not being performed. I believe the result is correct and the
warning can be ignored.

--
Simen

```

### Re: Find the heir.

```
On Sunday, 29 March 2020 at 14:04:53 UTC, TodNaz wrote:

Hello!

class A
{
...
}

class B : A
{
...
}

class C : A
{
...
}

A example1;
B example2 = new B(...);
A = example2;
auto heir = A.whoheir(); ///

The question in this code is: is it possible to track the class
inheritor? Or is it beyond D?

Sorry if the question is fool ...

The question is a bit unclear - what is whoheir expected to
return? This is one way that may or may not fulfill your
requirements:

module foo;
class A {
string whoheir() {
return typeid(this).name;
}
}
class B : A {}
class C : A {}

unittest {
A a = new B();
assert(a.whoheir == "foo.B");
a = new C();
assert(a.whoheir == "foo.C");
}

--
Simen

```

### Re: Get symbols (and/or UDAs) of subclass from superclass

```
On Sunday, 15 March 2020 at 20:18:03 UTC, James Blachly wrote:
I would like to programmatically retrieve members of a subclass
to create a self-documenting interface. I am afraid that my
approach is not possible due to need for compile time __traits
/ std.traits, and runtime typeinfo. My proposed approach is as
follows:

class Base
{
string whatever;

string toString()
{
// loop over __traits(allMembers, typeof(this)) or
getSymbolsByUDA, etc.

}
}

/// There may be a dozen Derived classes
class Derived1 : Base
{
@Config("a name", "a description")
float probability;
}
class Derived2 : Base
{
@Config("another", "more description")
int replicates;
}
...

There's no built-in way to do this - toString() doesn't know what
derived classes exist, and more could be added from other modules
and even dynamically loaded libraries. Now, there are ways to do
something somewhat like it. I would suggest creating an abstract
method in the base class, that derived class would have to
override, and use a template this argument to get the correct
type for __traits(allMembers) to operate on:

class Base {
override string toString() {
}
abstract string toStringImpl();
string toStringBase(this That)() {
// foreach (e; __traits(allMembers, That) {...}
}
}

class Derived : Base {
override string toStringImpl() {
return this.toStringBase();
}
}

Since toStringImpl will always call toStringBase, this could
perhaps better be modeled with a template mixin:

mixin template DerivedToString() {
override string toStringImpl() {
return this.toStringBase();
}
}

class Derived2 : Base {
mixin DerivedToString!();
}

This way, you can have all the logic of toString in the base
class, and the only thing a subclass will have to include is one
line for the mixin. In addition, since toStringImpl is abstract,
the implementer of a subclass will get a compile-time error if he
or she forgets to do either the mixin or override toStringImpl
themselves.

--
Simen

```

### Re: A set type implemented as an AA wrapper

```
On Thursday, 12 March 2020 at 08:51:24 UTC, mark wrote:
I use sets a lot and since I believe that D's rbtree is O(lg n)
for add/remove/in and that D's AA is O(1) for these, I want to
implement a set in terms of an AA.

Below is the code I've got so far. It allows for add and
remove. However, it has three problems (that I know of):

XXX: I need to use an if on the struct to restrict T to be a
type that supports toHash and opEquals (i.e., to be a valid AA
key)

I'd suggest simply testing if an AA with that key type is valid:

struct AAset(T) if (is(int[T]))

YYY: The range() method is clearly not good D style but I don't
know how to support foreach (item; aaset) ...

As Ferhat points out, you could use opApply for this. There's
also the option of implenting the range primitives front,
popFront() and empty. However, the easiest solution is the one
you've already chosen, combined with alias this:

struct AAset(T) if (is(int[T])) {
// stuffs...
auto range() { return set.byKey; }
alias range this;
}

ZZZ: I can't figure out how to support the in operator.

'in' for AAs returns a pointer to the value it finds, or null if
no item is found. This pointer does not implicitly convert to
bool when returned from a function, so you need to compare it to
null:

bool opBinaryRight(string op)(T lhs) {
static if (op == "in") return (lhs in set) != null;
else static assert(0, "operator " ~ op ~ " not
supported");

}

I would also suggest using a template specialization instead of
static if and static assert:

bool opBinaryRight(string op : "in")(T lhs) {
return (lhs in set) != null;
}

--
Simen

```

### Re: Aliases to mutable thread-local data not allowed [testable source code]

```
On Wednesday, 11 March 2020 at 12:43:28 UTC, mark wrote:

On Wednesday, 11 March 2020 at 12:22:21 UTC, Simen Kjærås wrote:

On Wednesday, 11 March 2020 at 09:29:54 UTC, mark wrote:

[snip]
Fascinating. It works just fine when compiling for 32-bit
targets with DMD on Windows, but not for 64-bit targets, nor
when compiling with LDC. Apparently, this difference is due to
DMD supporting 80-bit reals, and thus giving a different size
to Variant (VariantN!20 on DMD on Windows, VariantN!16 or
VariantN!32 elsewhere). There's a bug in VariantN that then
causes the compilation to fail
(https://issues.dlang.org/show_bug.cgi?id=20666).

The issue at hand then, is that Deb is too big until that
issue if fixed. The simple solution to this is to allocate Deb
on the heap with new and pass pointers instead of instances
directly. Since you are already calling .dup whenever you pass
a Deb somewhere, you can simply modify .dup to return a Deb*
and the receive function to receive a Deb*, and I think you
should be good to go.

I did that and it compiles & runs, but no Debs get added to the
collection.
See https://github.com/mark-summerfield/d-debtest-experiment --
the 'mto' version is the one with your fixes.

Yeah, I forgot we cast to immutable to be able to send, so
deb.dup to get a mutable copy:

(immutable(Deb)* deb) { debForName[deb.name] = deb.dup; },
(DoneMessage m) { jobs--; }
);

--
Simen

```

### Re: Aliases to mutable thread-local data not allowed [testable source code]

```
On Wednesday, 11 March 2020 at 09:29:54 UTC, mark wrote:

Hi Simen,

I think you must have done something else but didn't mention to
get it to compile. I did the exact changes you said and it
wouldn't compile. Here's what I get with changes mentioned
below (with new full source):

Fascinating. It works just fine when compiling for 32-bit targets
with DMD on Windows, but not for 64-bit targets, nor when
compiling with LDC. Apparently, this difference is due to DMD
supporting 80-bit reals, and thus giving a different size to
Variant (VariantN!20 on DMD on Windows, VariantN!16 or
VariantN!32 elsewhere). There's a bug in VariantN that then
causes the compilation to fail
(https://issues.dlang.org/show_bug.cgi?id=20666).

The issue at hand then, is that Deb is too big until that issue
if fixed. The simple solution to this is to allocate Deb on the
heap with new and pass pointers instead of instances directly.
Since you are already calling .dup whenever you pass a Deb
somewhere, you can simply modify .dup to return a Deb* and the
receive function to receive a Deb*, and I think you should be
good to go.

--
Simen

```

### Re: Aliases to mutable thread-local data not allowed [testable source code]

```
On Tuesday, 10 March 2020 at 20:03:21 UTC, mark wrote:

I've managed to make a cut-down version that's < 170 LOC.
It needs to be run on Debian or a Debian-based Linux (e.g.,
Ubuntu).

Hopefully this will help someone understand and be able to help!

This took some time figuring out. Turns out,
std.concurrency.spawn won't take a delegate as its callable
argument. There are sensible reasons for this - delegates have a
context that is not guaranteed to be immutable, so allowing
delegate callables could lead to mutable aliasing. I've filed an
issue to improve documentation and error messages:
https://issues.dlang.org/show_bug.cgi?id=20665

However, knowing that some things are impossible do not
necessarily help us figure out what we can do to fix the problem,
and the good news is, the problems can be fixed. Since the
problem is we're giving a delegate where the API expects a
function, we can simply turn it into a function. In the code
you've given, that means making readPackageFile and
readPackageLine static. This make spawn() run as it should.

(DoneMessage) { jobs--; }

That looks sensible, but since DoneMessage doesn't have a name,
it is parsed as a templated function taking one argument of
unspecified type and called DoneMessage. For some reason,
templates passed as function arguments show up in compiler output
as 'void', giving this weird error message:

template std.concurrency.receive cannot deduce function from
argument types !()(void delegate(Deb deb) pure nothrow @safe,
void)

The solution here is to simply give DoneMessage a name:

(DoneMessage d) { jobs--; }

With those changes, things at least compile. Now it's up to you
to ensure the semantics are correct. :)

One last thing: you're passing parentTid around, and that's not
actually necessary - std.concurrency.ownerTid does the exact same
thing, and is available even if not explicitly passed anywhere.

--
Simen

```

### Re: Aliases to mutable thread-local data not allowed

```
On Tuesday, 10 March 2020 at 08:13:19 UTC, mark wrote:

I have this struct:

struct Deb {
string name;
...
Unit[string] tags; // set of tags

Deb dup() const {
Deb deb;
deb.name = name;
...
foreach (key; tags.byKey)
deb.tags[key] = unit;
return deb;
}
}

void readPackageFile(Tid parentTid, string filename) { // (some
code elided)

try {
Deb deb;
auto file = File(filename);
foreach(lino, line; file.byLine.enumerate(1))
deb);
// readPackageLine also calls send with same code
as AAA below

if (deb.valid)
send(parentTid, deb.dup); // AAA

/home/mark/opt/ldc2-1.20.0-linux-x86_64/bin/../import/std/concurrency.d(625,5): Error:
static assert:  "Aliases to mutable thread-local data not allowed."

Is there any nice solution to this? Surely it is a common
pattern to read multiple files and create lots of data items to
be merged into a collection?

As the error message hints at, the problem is Deb may hold
references to data that is shared with other objects on the
thread from which it originates. Since you know this is not the
case, even if the compiler can't prove it, you can safely cast

if (deb.valid)
send(parentTid, cast(immutable)deb.dup);

In fact, even the .dup is unnecessary here, since no data is
shared with other objects, so you can simply write
send(parentTid, cast(immutable)deb);. (Note on this point: since
you have not included all your code, it could be other parts
create shared mutable state, in which case .dup is necessary, and
if badly written may not be sufficient.

--
Simen

```

### Re: @property with opCall

```
On Monday, 9 March 2020 at 09:25:31 UTC, Calvin P wrote:

Is this a bugs ?

==
struct A {
ref auto opCall(string tmp) scope return {
return this;
}
}

struct B {
A _a;

@property ref auto a() scope return {
return _a;
}
}

extern(C) int main(){
A a;
a("a")("b");
B b;
b.a("a")("b");  // Error: function test_opCall.B.a() is
not callable using argument types (string)

return 0;
}
==

I has to use  b.a()("a")("b") to avoid the compiler error. I
think it should work to avoid the unnecessary ()

Should I submit a bugs ?

As written on
https://dlang.org/spec/function.html#property-functions:

WARNING: The definition and usefulness of property functions is
being reviewed, and the implementation is currently incomplete.
Using property functions is not recommended until the
definition is more certain and implementation more mature.

So no, I don't think it's necessary to file a bug - we're aware
they're somewhat wonky, and until a resolution has been agreed
on, I don't think filing bugs on what's undecided behavior is
worth it.

--
Simen

```

### Re: Idiomatic way to express errors without resorting to exceptions

```
On Saturday, 7 March 2020 at 15:44:38 UTC, Arine wrote:
The case when there isn't a value should be handled explicitly,
not implicitly. Propogating a None value

isn't useful

Except when it is useful, and shouldn't be handled explicitly. I
have code in D, C and C++ that looks like this:

ReturnValue result = someInitialValue;
auto foo = getFoo();
if (!foo) return result;
auto bar = foo.fun();
if (!bar) return result;
return bar.gun();

In C#, this would be:

return getFoo()?.fun().gun() ?? someInitialValue;

And with implicit handling in Optional!T, it looks like this:

return getFoo().oc.fun().gun().or(someInitialValue);

Clearly the latter two are more readable, and I'm not gonna care
that it's a little slower in the 99% of cases where speed is not
important.

--
Simen

```

### Re: What does assigning void mean?

```
On Thursday, 5 March 2020 at 08:35:52 UTC, drug wrote:

On 3/5/20 10:47 AM, mark wrote:
In Adam Ruppe's D Cookbook there're these lines in a ref
counting example:

RefCountedObject o = void; // What does this mean/do?
o.data = new Implementation();
o.data.refcount = 1;

I don't understand the first line; could someone explain

In D all vars are initialized by default. If you use assigning
void then the var won't be initialized.

To expand a bit on this: You probably don't want to initialize
things with = void - it can lead to hard-to-track bugs and
unexpected behavior. The reasons it's there is almost entirely as
an optimization - if you know the variable will be initialized
elsewhere void initialization ensure things won't be initialized
twice when once is enough, and this can be faster.

The other use case is when for whatever reason there is no valid
default value, but you still want an instance. Probably in order
to fill it with data from somewhere else. This would apply e.g.
to structs with @disabled parameterless constructors whose
contents you are reading from disk.

In short, when you know you need to void initialize something,
that's when you're ready to use it. Kinda like goto.

--
Simen

```

### Re: Call method if declared only

```
On Friday, 28 February 2020 at 10:33:11 UTC, Виталий Фадеев wrote:

Thanks all !
I happy !
Check this one:
void On( T, M )( T o, M message )
{

[snip]

void main()
{
auto a = new A();
a.Send( a, WM_KEYUP );
a.Send( a, WM_KEYDOWN );
}

That does mostly work, but fails for this code:

void main()
{
Base a = new A();
a.send( a, WM_KEYUP );
}

Basically, whenever you assign a derived to a base, this solution
doesn't work, because T will be Base, not A.

I enjoyed with the previous code, so I wrote the code necessary
to handle any WM_ message:

import core.sys.windows.windows;
import std.stdio;
import std.meta;

template startsWith(string prefix) {
enum startsWith(string s) = s.length >= prefix.length &&
s[0..prefix.length] == prefix;

}

enum getMessageValue(string s) = __traits(getMember,
core.sys.windows.winuser, s);

// Get the all the WM_ messages
alias messageNames = Filter!(startsWith!"WM_",
__traits(allMembers, core.sys.windows.winuser));
alias messageValues = NoDuplicates!(staticMap!(getMessageValue,
messageNames));

class Base {
LRESULT On(UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
foreach (msg; messageValues) {
case msg:
if (auto that =
cast(IMessageHandler!msg)this) {

return that.handle(wParam, lParam);
}
break;
}
default:
}
return 0;
}
}

interface IMessageHandler(alias msg) {
mixin("LRESULT On"~__traits(identifier, msg)~"(WPARAM wParam,
LPARAM lParam);");

alias handle = mixin("On"~__traits(identifier, msg));
}

class Button : Base, IMessageHandler!WM_KEYDOWN,
IMessageHandler!WM_SETTINGCHANGE {

LRESULT OnWM_KEYDOWN(WPARAM wParam, LPARAM lParam) {
writeln("WM_KEYDOWN");
return 0;
}
LRESULT OnWM_SETTINGCHANGE(WPARAM wParam, LPARAM lParam) {
writeln("WM_SETTINGCHANGE");
return 0;
}
}

unittest {
Base b1 = new Base();
Base b2 = new Button();

writeln("Base:");
// None of these will print anything, as Base doesn't handle
them

b1.On(WM_KEYDOWN, 0, 0);
b1.On(WM_SETTINGCHANGE, 0, 0);
b1.On(WM_DRAWITEM, 0, 0);
writeln("Button:");
b2.On(WM_KEYDOWN, 0, 0);
b2.On(WM_SETTINGCHANGE, 0, 0);
// This will print nothing, as Button doesn't handle that
message.

b2.On(WM_DRAWITEM, 0, 0);
}

--
Simen

```

### Re: Call method if declared only

```
On Friday, 28 February 2020 at 09:25:58 UTC, Виталий Фадеев wrote:

Yes. Thank !
Problem is - OS has many messages + user messages... It mean
what interfaces like IKeyDown must me declared. All. Dream on
write less code...

So let's create a template for that:

interface IMessageHandler(alias msg) {
mixin("LRESULT On"~__traits(identifier, msg)~"(WPARAM wParam,
LPARAM lParam);");

}

And use it:

import core.sys.windows.windows;
import std.stdio;

class Base {
LRESULT On(UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_KEYDOWN:
if (auto that =
cast(IMessageHandler!WM_KEYDOWN)this) {

return that.OnWM_KEYDOWN(wParam, lParam);
}
break;
default:
}
return 0;
}
}

class Button : Base, IMessageHandler!WM_KEYDOWN {
LRESULT OnWM_KEYDOWN(WPARAM wParam, LPARAM lParam) {
writeln("WM_KEYDOWN");
return 0;
}
}

unittest {
Base b1 = new Base();
Base b2 = new Button();

writeln("Base:");
b1.On(WM_KEYDOWN, 0, 0);
writeln("Button:");
b2.On(WM_KEYDOWN, 0, 0);
}

You'll still have to specify for each derived class which
messages they handle, but no need to define hundreds of
interfaces separately.

--
Simen

```

### Re: Call method if declared only

```
On Friday, 28 February 2020 at 06:12:37 UTC, Виталий Фадеев wrote:

Searching solution for idea !

For whatever reason, it seems my attempts at answering this
earlier has disappeared into the void. Here:

import core.sys.windows.windows;
import std.stdio;

class Base {
LRESULT On(UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_KEYDOWN:
return tryCall!"OnWM_KEYDOWN"(wParam, lParam);
default:
}
return 0;
}

auto tryCall(string name, Args...)(Args args) {
import std.meta;

alias This = typeof(this);
alias module_ = __traits(parent, This);

enum isSubclass(T...) = is(T[0] : This);
alias getModuleMember(string name) = __traits(getMember,
module_, name);

enum hasMethod(T) = __traits(hasMember, T, name);

// Get every member in this module
enum memberNames = __traits(allMembers, module_);
alias members = staticMap!(getModuleMember, memberNames);

// Filter away anything that isn't derived from Base
alias subclasses = Filter!(isSubclass, members);

// Get rid of anything that doesn't have a method with
the correct name
alias subclassesWithMethod = Filter!(hasMethod,
subclasses);

// Sort them so you get the most derived types first
alias Types = DerivedToFront!subclassesWithMethod;

// Check for each type if the `this` is an instance of
that specific one

static foreach (T; Types) {
if (cast(T)this !is null) {
// And look up that method and call it.
return __traits(getMember, cast(T)this,
name)(args);

}
}

// If `this` is not one of the types with that method,
return some default value

return 0;
}
}

class Button : Base {
LRESULT OnWM_KEYDOWN(WPARAM wParam, LPARAM lParam) {
writeln("WM_KEYDOWN");
return 0;
}
}

unittest {
Base b1 = new Base();
Base b2 = new Button();

writeln("Base:");
b1.On(WM_KEYDOWN, 0, 0);
writeln("Button:");
b2.On(WM_KEYDOWN, 0, 0);
}

Now, this only works for subclasses defined in the same module. A
possibly better solution would be interfaces:

import core.sys.windows.windows;
import std.stdio;

class Base {
LRESULT On(UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_KEYDOWN:
if (cast(IKeyDown)this) {
return
(cast(IKeyDown)this).OnWM_KEYDOWN(wParam, lParam);

}
default:
}
return 0;
}
}

interface IKeyDown {
LRESULT OnWM_KEYDOWN(WPARAM wParam, LPARAM lParam);
}

class Button : Base, IKeyDown {
LRESULT OnWM_KEYDOWN(WPARAM wParam, LPARAM lParam) {
writeln("WM_KEYDOWN");
return 0;
}
}

unittest {
Base b1 = new Base();
Base b2 = new Button();

writeln("Base:");
b1.On(WM_KEYDOWN, 0, 0);
writeln("Button:");
b2.On(WM_KEYDOWN, 0, 0);
}

--
Simen

```

### Re: Call method if declared only

```
On Friday, 28 February 2020 at 08:08:59 UTC, Виталий Фадеев wrote:
On Friday, 28 February 2020 at 06:12:37 UTC, Виталий Фадеев
wrote:

Searching solution for idea !

Goal is to get System message, dispatch/route to method !
If method implemented only !

I dream on in future write clean code of a derived widgets
like this :

class Base
{
// dispatch
void On( message ... )
{
// call On()
// example: call OnKeyUp() - if method OnKeyUp() is
exists only

}
}

May be other than derived ? May be templating ?
How to implement ?

Now I go in ths way:

[snip]

Here's an attempt. It looks up all subclasses of Base in the same
module, and calls the named method if it exists. However, it will
fail for any subclass of Base that is defined in a different
module.

import core.sys.windows.windows;
import std.stdio;

class Base {
LRESULT On(UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_KEYDOWN:
return tryCall!"OnWM_KEYDOWN"(wParam, lParam);
default:
}
return 0;
}

auto tryCall(string name, Args...)(Args args) {
import std.meta;

alias This = typeof(this);
alias module_ = __traits(parent, This);

enum isSubclass(T...) = is(T[0] : This);
alias getModuleMember(string name) = __traits(getMember,
module_, name);

enum hasMethod(T) = __traits(hasMember, T, name);

// Get every member in this module
enum memberNames = __traits(allMembers, module_);
alias members = staticMap!(getModuleMember, memberNames);

// Filter away anything that isn't derived from Base
alias subclasses = Filter!(isSubclass, members);

// Get rid of anything that doesn't have a method with
the correct name
alias subclassesWithMethod = Filter!(hasMethod,
subclasses);

// Sort them so you get the most derived types first
alias Types = DerivedToFront!subclassesWithMethod;

// Check for each type if the `this` is an instance of
that specific one

static foreach (T; Types) {
if (cast(T)this !is null) {
// And look up that method and call it.
return __traits(getMember, cast(T)this,
name)(args);

}
}

// If `this` is not one of the types with that method,
return some default value

return 0;
}
}

class Button : Base {
LRESULT OnWM_KEYDOWN(WPARAM wParam, LPARAM lParam) {
writeln("WM_KEYDOWN");
return 0;
}
}

unittest {
Base b1 = new Base();
Base b2 = new Button();

writeln("Base:");
b1.On(WM_KEYDOWN, 0, 0);
writeln("Button:");
b2.On(WM_KEYDOWN, 0, 0);
}

--
Simen

```

### Re: How to copy const object?

```
On Thursday, 27 February 2020 at 11:28:11 UTC, Mitacha wrote:
I've a const struct object and I'd like to make a mutable copy
of it.

Struct definition contains string and an array of structs.
```
struct A {
string a;
B[] b;
}

struct B {
string a;
string b;
}
```
As far as I can tell copy constructor isn't generated for
struct `A` because it contains an array. Correct?

Is there an idiomatic way to create copy of a const object?

As long as the copy is also const, you can just assign it to a
new variable of the same type:

const A a = A("foo",[B("bar", "baz")]);
const A b = a;

If, however, you require a mutable copy, things get a little more
hair. In D, const is transitive, so that A.b[0] is a const(B).
This will thus not work:

A c = a; // Error: cannot implicitly convert expression a of
type const(A) to A

For built-in arrays, the .dup function does this:

const int[] arr1 = [1];
int[] arr2 = arr1; // Fails to compile
int[] arr3 = arr1.dup; // Works

For symmetry, we can add a similar function to A:

struct A {
string a;
B[] b;
A dup() const {
return A(a, b.dup);
}
}

This lets us easily create a copy:

A d = a.dup;

Now, the reason you can't just assign from const(A) to A, while
this works with const(B) to B, e.g., is that A contains mutable
indirections. That is, you can change the contents of A.b. Since
copies are generally shallow copies in D, allowing this behavior
would have unfortunate consequences:

const(A) a1 = A("foo", [B("bar", "baz")]);
A a2 = a1; // Assume this worked
assert(a1.b[0].a == "bar");
a1.b[0].a = "qux"; // Can't change b[0] through a1, since
it's const

a2.b[0].a = "qux"; // But we can change it through a2!
assert(a1.b[0].a != "bar"); // And suddenly the const value
in a1.b has changed.

--
Simen

```

### Re: String switch is odd using betterC

```
On Wednesday, 26 February 2020 at 08:32:50 UTC, Abby wrote:

On Wednesday, 26 February 2020 at 08:25:00 UTC, Abby wrote:

Any idea why?

Ok so this is enough to produce the same result, it seems that
there is a problem in string switch when there is more the 6
cases.

extern(C) void main()
{
auto s = "F";
final switch(s)
{
case "A": break;
case "B": break;
case "C": break;
case "D": break;
case "E": break;
case "F": break;
case "G": break;
}
}

The explanation can be found in
druntime/import/core/internal/switch_.d: the __switch template
does a simple binary search for less than 7 cases, but calls
.idup on each case label for >= 7 cases.

There's a comment there about why it's being done, but it seems
to be a far more complicated fix than necessary - static
immutable cases = [caseLabels]; works just as well, it seems.

Anyway, the current code was added in this commit:
https://github.com/dlang/druntime/commit/fa665f6618af7dbc09ed5ba1333f385017b7ece8.

Anyways, reported here:
https://issues.dlang.org/show_bug.cgi?id=20613

--
Simen

```

### Re: Alternative to friend functions?

```
On Tuesday, 18 February 2020 at 12:43:22 UTC, Adnan wrote:

class Wife(uint N) : Female {
FemaleID engagedTo = -1;
const MaleID[N] preferences;

this(MaleID[N] preferences) {
this.preferences = preferences;
}
}

void engage(N)(ref Wife!N, wife, ref Husband!N husband) {
// Here, I want to access both husband and wife's engaged_to
}

that, but I'd like to point out that as Wife and Husband are
classes, you probably don't intend to take them by ref - classes
are always by ref in D, so you're effectively passing a reference
to a reference to a class in `engage`.

Basically:

class Foo {
int n;
}

void fun(Foo f) {
f.n = 3;
// Local copy of the reference - does not modify other
references.

f = null;
}

void gun(ref Foo f) {
f = null;
}

unittest {
Foo f = new Foo();
Foo g = f;
f.n = 17;
// f and g point to the same object:
assert(f.n == 17);
assert(g.n == 17);

fun(f);
// fun() changed the object that both f and g point to:
assert(f.n == 3);
assert(g.n == 3);

gun(f);
// gun() changed f to no longer point at the same object, but
left g untouched:

assert(f is null);
assert(g !is null);
assert(g.n == 3);
}

--
Simen

```

### Re: How to declare a virtual member (not a function) in a class

```
On Tuesday, 18 February 2020 at 12:37:45 UTC, Adnan wrote:
I have a base class that has a couple of constant member
variables. These variables are abstract, they will only get
defined when the derived class gets constructed.

class Person {
const string name;
const int id;
}

class Male : Person {
this(string name = "Unnamed Male") {
static int nextID = 0;
this.id = nextID++;
this.name = name;
}
}

The compiler restricts me from assigning those two functions.
How can I get around this?

const members can only be set in the constructor of the type that
defines them. To set them in a subclass, forward the values to
the superclass' constructor:

class Person {
const string name;
const int id;
protected this(string _name, int _id) {
id = _id;
name = _name;
}
}

class Male : Person {
this(string name = "Unnamed Male") {
static int nextID = 0;
super(name, nextID++);
}
}

--
Simen

```

### Re: Why can't I pass a const array to a function that takes scope const arrays?

```
On Monday, 17 February 2020 at 14:04:34 UTC, Adnan wrote:

cdsa ~master: building configuration "cdsa-test-library"...
source/strassens_matmul.d(22,16): Error: cannot implicitly
convert expression [row][column] of type const(uint)* to
uint*
source/strassens_matmul.d(37,36): Error: template instance
strassens_matmul.getPointPtr!uint error instantiating

source/strassens_matmul.d(48,29):

I'd just finished writing a long post explaining the stuff you've
apparently figured out. Ah well. :p

In this case, getPointPtr return T*, but takes scope const ref
T[][]. Since getPointPtr always takes a mutable array, you could
just get rid of const on its parameters. Alternatively, if you
want to be able to use it on arrays of different constness, you
could use inout:

inout(T)* getPointPtr(T)(inout T[][] mat, size_t row, size_t
column) {

This will return a pointer to a mutable T if that's what the
array holds when you call the function, const(T) if it's a const
array, immutable(T) if it's immutable, and so on.

The same can be done with the other functions you have.

You are also somewhat overusing const, scope and ref, I'd say -
you should not take an array by ref unless you plan on modifying
it, which you are not doing in getPointPtr or any other of your
functions. scope may be worth it, as it guarantees you won't be
sending the data elsewhere.

None of these are necessary on your ulongs, which are passed by
value and never attempted modified. If you really like the extra
guarantee that you don't accidentally modify them, feel free to
keep 'const', but 'scope' on a ulong does nothing, and it's been
argued it should be a compiler error.

Lastly, you're using ulongs a lot, and this is mostly correct
when compiling for 64-bit, but makes code fail to compile for
32-bit. Using size_t instead makes for code that works for both.

All in all, I end up with this code:

module strassens_matmul;

debug {
static import std;
}

package {
size_t getRowSize(T)(const T[][] mat) {
return mat[0].length;
}

size_t getColumnSize(T)(const T[][] mat) {
return mat.length;
}

T[][] createMatrix(T)(size_t rowSize, size_t columnSize) {
return new T[][](rowSize, columnSize);
}

/// row and column are 0 index-based
inout(T)* getPointPtr(T)(inout T[][] mat, size_t row, size_t
column) {

return [row][column];
}

T getPointCopy(T)(const T[][] mat, size_t row, size_t column)
{

return mat[row][column];
}

T[][] mulIterative(T)(const T[][] mat1, const T[][] mat2) {
auto result = createMatrix!T(getRowSize!T(mat1),
getColumnSize!T(mat2));

foreach (row; 0 .. mat1.getRowSize()) {
foreach (column; 0 .. mat2.getColumnSize()) {
T value;
foreach (i; 0 .. mat1.getRowSize()) {
value += mat1.getPointCopy(row, i) *
mat2.getPointCopy(i, column);

}
*result.getPointPtr(row, column) = value;
}
}
return result;
}
}

unittest {
const uint[][] matA = [[10, 20, 10], [4, 5, 6], [2, 3, 5]];
const uint[][] matB = [[3, 2, 4], [3, 3, 9], [4, 4, 2]];
const uint[][] matC = [[130, 120, 240], [51, 47, 73], [35,
33, 45]];

assert(matA.mulIterative(matB) == matC);
}

--
Simen

```

### Re: operator overload for sh-like scripting ?

```
On Monday, 17 February 2020 at 13:03:38 UTC, Basile B. wrote:

eg

Sh(echo) < "meh";

struct Sh
{
// you see the idea we have op overload for < here
}

You can't overload < separately - all the comparison operators
(<, <=, >, >=) are handled via opCmp. Even if you choose to go
down that route, there are other issues - opCmp needs to return
something that may be compared to 0, since (a < b) is rewritten
as (a.opCmp(b) < 0), and the compiler checks if you are simply
discarding the return value of a comparison, so all in all, you
shouldn't do that in D (and the hoops you have to jump through to
make it work makes the code a lot less readable):

struct Sh {
int opCmp(string s) {
import std.stdio : writeln;
writeln(s);
return 0;
}
}

unittest {
Sh sh;
auto _ = sh < "baz";
}

This is also not chainable, so something like (sh < "foo" <
"bar") won't work, even with parentheses.

There's also the issue of (a < b) having a defined meaning in D
less readable. This is a point with differing opinions, and I'm
not firmly on either side of that argument, but it's worth
pointing out.

Now, if you absolutely want something that's somewhat similar in
regular D code, there's <<:

struct Sh {
Sh opBinary(string op : "<<")(string s) {
import std.stdio : writeln;
writeln(s);
return this;
}
}

unittest {
Sh sh;
sh << "foo" << "bar";
}

While this works, it's a design choice that C++ has gotten a lot
of flak for, including one of my favorite C++ quotes: "I saw
'cout' being shifted 'Hello world' times to the left and stopped
right there." There are cases where it's not at obvious to the
should be used with caution.

A better choice, perhaps, if using < is important, would be to
use a DSL and have it obvious in the code that normal D rules
aren't at play:

void fun() {
Sh sh;
mixin dsl!`
sh < "foo";
`;
}

At this point though, you're looking at a considerable chunk of
code just for a bit of syntactic sugar.

--
Simen

```

### Re: From [Tuple!(A,B), ...] to Tuple!(A[], B[])

```On Monday, 17 February 2020 at 11:51:52 UTC, FeepingCreature
wrote:

Here you go:

import std;

// extract the types that make up the tuple
auto transposeTuple(T : Tuple!Types[], Types...)(T tuples)
{
// templated function that extracts the ith field of an
array of tuples as an array

auto extractArray(int i)()
{
return tuples.map!(a => a[i]).array;
}
// return tuple of calls to extractArray, one for each
tuple index
return tuple(staticMap!(extractArray,
aliasSeqOf!(Types.length.iota)));

}

void main() {
Tuple!(int, double)[] array;
array ~= tuple(1, 2.0);
array ~= tuple(3, 4.0);
Tuple!(int[], double[]) tuple = array.transposeTuple;
assert(tuple[0] == [1, 3]);
assert(tuple[1] == [2.0, 4.0]);
}

One tiny thing: the above fails for tuples with named fields,
like Tuple!(int, "a", string "b"). This code handles that case,
and preserves field names:

import std.meta : staticMap, aliasSeqOf;
import std.typecons : Tuple;
import std.range : array, iota;
import std.algorithm : map;

alias ToArray(T) = T[];
alias ToArray(T...) = T;
alias ToArrayTuple(T : Tuple!U, U...) =
Tuple!(staticMap!(ToArray, U));

auto transpose(T : Tuple!U, U...)(T[] arr) {
auto extract(int i)() { return arr.map!(a => a[i]).array; }
aliasSeqOf!(T.Types.length.iota)));

}

unittest {
alias T = Tuple!(int, "a", string, "b");
auto a = [T(1, "a"), T(2, "b")];
assert(a.transpose.a == [1, 2]);
assert(a.transpose.b == ["a", "b"]);
}

--
Simen

```

### Re: From [Tuple!(A,B), ...] to Tuple!(A[], B[])

```On Monday, 17 February 2020 at 11:51:52 UTC, FeepingCreature
wrote:

On Monday, 17 February 2020 at 11:07:33 UTC, foozzer wrote:

Hi all,

There's something in Phobos for that?

Thank you

Here you go:

import std;

// extract the types that make up the tuple
auto transposeTuple(T : Tuple!Types[], Types...)(T tuples)
{
// templated function that extracts the ith field of an
array of tuples as an array

auto extractArray(int i)()
{
return tuples.map!(a => a[i]).array;
}
// return tuple of calls to extractArray, one for each
tuple index
return tuple(staticMap!(extractArray,
aliasSeqOf!(Types.length.iota)));

}

void main() {
Tuple!(int, double)[] array;
array ~= tuple(1, 2.0);
array ~= tuple(3, 4.0);
Tuple!(int[], double[]) tuple = array.transposeTuple;
assert(tuple[0] == [1, 3]);
assert(tuple[1] == [2.0, 4.0]);
}

^^ Do what he said - I misread the title. :)

--
Simen

```

### Re: From [Tuple!(A,B), ...] to Tuple!(A[], B[])

```
On Monday, 17 February 2020 at 11:07:33 UTC, foozzer wrote:

Hi all,

There's something in Phobos for that?

Thank you

import std.meta : staticMap;
import std.typecons : Tuple;

// Turn types into arrays
alias ToArray(T) = T[];
// Leave everything else the same
alias ToArray(T...) = T;
// Now apply the above to each element of the Tuple template args:
alias ToArrayTuple(T : Tuple!U, U...) =
Tuple!(staticMap!(ToArray, U));

unittest {
alias A = Tuple!(int, string);
assert(is(ToArrayTuple!A == Tuple!(int[], string[])));
alias B = Tuple!(int, "a", string, "b");
assert(is(ToArrayTuple!B == Tuple!(int[], "a", string[],
"b")));

}

--
Simen

```

### Re: Global version/debug statements in file?

```
On Wednesday, 12 February 2020 at 08:44:24 UTC, cc wrote:
Is there some way to globally declare version= or debug=
statements in a file and have them apply to the entire project
being compiled?  As the documentation says these only apply to
the module scope they exist in, and need to be added to the
command line otherwise.  It would be a bit easier for me to
maintain a separate .d source file when I want to add/comment
out statements for testing than to keep updating the build
command line.

https://dlang.org/dmd-windows.html#switches

specifies that DMD may be passed a file on the command line that
contains compiler arguments and switches. This may be freely
combined with regular command line arguments if you so wish.

So, you could have a file called 'versions' containing this:

# Setting 'Compress' version
-version=Compress
# Optionally set other versions
#-version=Foo
#-version=Bar

and feed it to dmd like so:

dmd -w -wi -g @versions -main foo.d

--
Simen

```

### Re: Custom separator in array format

```
On Tuesday, 28 January 2020 at 07:36:25 UTC, Malte wrote:
I want to format an array using the %(...%) syntax. How can I
change the separator? I tried to use ? and add it as additional
parameter, but that doesn't seem to work on arrays:

import std;
void main()
{
writeln("This works:");
writefln("%,2?d", '_', 2000); // 20_00

auto vec = [1000, 2000, 3000];
writeln("This should fail (separator character expected)
but the ? is just ignored:");

writefln("%(%,2?d\t%)", vec); // 10,0020,00   30,00
writeln("This throws:");
writefln("%(%,2?d\t%)", '_', vec); //
std.format.FormatException@/dlang/dmd/linux/bin64/../../src/phobos/std/format.d(2271): incompatible format character for integral argument: %(

}

I think I see why it's not working. Essentially, for each element
of vec, format is called with only that element as an argument.
Essentially, rather than:

foreach (e; vec)
writef("%,2?d\t", '_', e);
writeln();

You get:

foreach (e; vec)
writef("%,2?d\t", e);
writeln();

For whatever reason, it doesn't throw when missing an argument
for the separator - I'd say this is a bug
(https://issues.dlang.org/show_bug.cgi?id=20541).

For now, you can work around the issue this way:

import std.stdio : writefln;
import std.format : format;
import std.algorithm : map;

auto vec = [1000, 2000, 3000];

writefln("%-(%s\t%)", vec.map!(e => format!"%,2?d"('_', e)));

--
Simen

```

### Re: @disable("reason")

```On Wednesday, 8 January 2020 at 07:03:26 UTC, Jonathan M Davis
wrote:

you could just document that no one should ever use its init
value explicitly, and that they will have bugs if they do

You also create a static init member marked @disable:

struct S {
@disable this();
@disable static S init();
}

This will give sensible error messages anywhere .init is being
used. Now, Phobos and other libraries might expect that .init is
always working, so this could potentially be a problem.

```

### Re: @disable("reason")

```
On Wednesday, 8 January 2020 at 08:26:51 UTC, user1234 wrote:

class Example
{
@disable this() { pragma(msg, "not allowed..."); }
}

void main()
{
new Example();
}

outputs:

not allowed...
/tmp/temp_7F8C65489550.d(12,5): Error: constructor
`runnable.Example.this` cannot be used because it is annotated
with `@disable`

However, it will print that message even if the constructor is
never called. If you make the constructor a template instead, you
will only get the message when someone attempts to use the
default constructor:

class Example
{
@disable this()() { pragma(msg, "not allowed..."); }
}

void main()
{
new Example();
}

Sadly, this does not work for structs, as they don't really have
a default constructor, as Jonathan pointed out.

--
Simen

```

### Re: Should I stop being interested in D language if I don't like to see template instantiation in my code?

```
On Thursday, 14 November 2019 at 09:30:23 UTC, user9876 wrote:
A good thing is that in many cases the template instance
parameters can be deduced from the arguments used:

---
import std;

void main()
{
assert(max(0,1) == 1);
// same as assert(max!(int,int)(0,1) == 1);
}
---

This feature is known as "IFTI" see §6,
https://dlang.org/spec/template.html#function-templates.

You're not forced to use the D templates but you'll have to
write many code by yourself because the standard library use
them everywhere.

IFTI is nifty. (sorry, I had to)

--
Simen

```