Re: Error: variable 'xyz' has scoped destruction, cannot build closure

2018-10-04 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 5 October 2018 at 06:22:57 UTC, Nicholas Wilson wrote:
tenRandomNumbers.each!((n,o) => 
o.appendln(n.to!string))(output);


or

tenRandomNumbers.each!((n, ref o) => 
o.appendln(n.to!string))(output);


should hopefully do the trick (run.dlang.io seems to be down 
atm).




Alas is does not because each does not accept additional argument 
other than the range. Shouldn't be hard to fix though.


Re: Error: variable 'xyz' has scoped destruction, cannot build closure

2018-10-04 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 5 October 2018 at 03:27:17 UTC, Jon Degenhardt wrote:
I got the compilation error in the subject line when trying to 
create a range via std.range.generate. Turns out this was 
caused by trying to create a closure for 'generate' where the 
closure was accessing a struct containing a destructor.


The fix was easy enough: write out the loop by hand rather than 
using 'generate' with a closure. What I'm wondering/asking is 
if there alternate way to do this that would enable the 
'generate' approach. This is more curiosity/learning at this 
point.


Below is a stripped down version of what I was doing. I have a 
struct for output buffering. The destructor writes any data 
left in the buffer to the output stream. This gets passed to 
routines performing output. It was this context that I created 
a generator that wrote to it.


example.d-
struct BufferedStdout
{
import std.array : appender;

private auto _outputBuffer = appender!(char[]);

~this()
{
import std.stdio : write;
write(_outputBuffer.data);
_outputBuffer.clear;
}

void appendln(T)(T stuff)
{
import std.range : put;
put(_outputBuffer, stuff);
put(_outputBuffer, "\n");
}
}

void foo(BufferedStdout output)
{
import std.algorithm : each;
import std.conv : to;
import std.range: generate, takeExactly;
import std.random: Random, uniform, unpredictableSeed;

auto randomGenerator = Random(unpredictableSeed);
auto randomNumbers = generate!(() => uniform(0, 1000, 
randomGenerator));

auto tenRandomNumbers = randomNumbers.takeExactly(10);
tenRandomNumbers.each!(n => output.appendln(n.to!string));
}

void main(string[] args)
{
foo(BufferedStdout());
}
End of  example.d-

Compiling the above results in:

   $ dmd example.d
   example.d(22): Error: variable `example.foo.output` has 
scoped destruction, cannot build closure


As mentioned, using a loop rather than 'generate' works fine, 
but help with alternatives that would use generate would be 
appreciated.


The actual buffered output struct has more behind it than shown 
above, but not too much. For anyone interested it's here:  
https://github.com/eBay/tsv-utils/blob/master/common/src/tsvutil.d#L358


tenRandomNumbers.each!((n,o) => o.appendln(n.to!string))(output);

or

tenRandomNumbers.each!((n, ref o) => 
o.appendln(n.to!string))(output);


should hopefully do the trick (run.dlang.io seems to be down atm).


The problem is that `output` is captured by the delegate and this 
somehow causes problems (idk what or why). If the (perviously 
captured) variables are instead passed as parameters then there 
is no need to create a closure for the variable, so no problem.
This is also the way to ensure that lambdas are @nogc if you ever 
need that.




Error: variable 'xyz' has scoped destruction, cannot build closure

2018-10-04 Thread Jon Degenhardt via Digitalmars-d-learn
I got the compilation error in the subject line when trying to 
create a range via std.range.generate. Turns out this was caused 
by trying to create a closure for 'generate' where the closure 
was accessing a struct containing a destructor.


The fix was easy enough: write out the loop by hand rather than 
using 'generate' with a closure. What I'm wondering/asking is if 
there alternate way to do this that would enable the 'generate' 
approach. This is more curiosity/learning at this point.


Below is a stripped down version of what I was doing. I have a 
struct for output buffering. The destructor writes any data left 
in the buffer to the output stream. This gets passed to routines 
performing output. It was this context that I created a generator 
that wrote to it.


example.d-
struct BufferedStdout
{
import std.array : appender;

private auto _outputBuffer = appender!(char[]);

~this()
{
import std.stdio : write;
write(_outputBuffer.data);
_outputBuffer.clear;
}

void appendln(T)(T stuff)
{
import std.range : put;
put(_outputBuffer, stuff);
put(_outputBuffer, "\n");
}
}

void foo(BufferedStdout output)
{
import std.algorithm : each;
import std.conv : to;
import std.range: generate, takeExactly;
import std.random: Random, uniform, unpredictableSeed;

auto randomGenerator = Random(unpredictableSeed);
auto randomNumbers = generate!(() => uniform(0, 1000, 
randomGenerator));

auto tenRandomNumbers = randomNumbers.takeExactly(10);
tenRandomNumbers.each!(n => output.appendln(n.to!string));
}

void main(string[] args)
{
foo(BufferedStdout());
}
End of  example.d-

Compiling the above results in:

   $ dmd example.d
   example.d(22): Error: variable `example.foo.output` has scoped 
destruction, cannot build closure


As mentioned, using a loop rather than 'generate' works fine, but 
help with alternatives that would use generate would be 
appreciated.


The actual buffered output struct has more behind it than shown 
above, but not too much. For anyone interested it's here:  
https://github.com/eBay/tsv-utils/blob/master/common/src/tsvutil.d#L358


Re: What does -vtls compiler flag does and ...

2018-10-04 Thread Seb via Digitalmars-d-learn
On Wednesday, 3 October 2018 at 20:58:01 UTC, Stanislav Blinov 
wrote:

On Wednesday, 3 October 2018 at 20:41:15 UTC, welkam wrote:
I was playing around with dmd`s make file trying to see if I 
can compile dmd with different compilers and different 
compilation flags. By playing around I found that some dmd 
files are compiled with -vtls flag unconditionally and that 
ldc do not support this flag. First I dont know what -vtls 
flag does so I looked at documentation...



Aren't all variables thread local unless explicitly specified?


No, all *static non-immutable* variables are thread-local by 
default, not just "all variables".


What this flag does? Why some files compiled with it and other 
dont? Why it is added to all compilation targets 
unconditionally?


It does what it says, just prints some diagnostic info. You can 
just ignore it, i.e. not use it. As for why it's in the 
makefile, I can only guess that someone keeps it there for 
diagnostic purposes :)


It was added during the transition to a D codebase to avoid 
regressions. These days its more or less useless as it doesn't 
fail the build anyhow.
Though LDC and GDC still rely on extern(C++) global variables for 
their interface with the frontend (not TLS static).


See also: https://github.com/dlang/dmd/pull/8018


Re: What does -vtls compiler flag does and ...

2018-10-04 Thread bauss via Digitalmars-d-learn

On Thursday, 4 October 2018 at 13:48:24 UTC, welkam wrote:
Oh so its like thread local globals sort of. My reasoning was 
that stack is a form of storage and is thread local so...


Thread local storage IS "global" per thread though, instead of 
per process which "global" is in other languages.


The stack, is... well the stack and has nothing to do with the 
thread local storage. Although each thread has their own stack, 
else threads would have to wait for each other every time 
something was pushed or popped.


Thread local storage is a bit more complex though and very 
different than regular heap allocations.


See: https://en.wikipedia.org/wiki/Thread-local_storage


Re: What does -vtls compiler flag does and ...

2018-10-04 Thread welkam via Digitalmars-d-learn
On Wednesday, 3 October 2018 at 21:50:49 UTC, Stanislav Blinov 
wrote:

Thread-local storage is memory allocated for each thread.
Only static non-immutable variables go there. Regular variables 
on the stack aren't explicitly placed in any TLS, they're, 
well, on the stack as it is.


Oh so its like thread local globals sort of. My reasoning was 
that stack is a form of storage and is thread local so...


Thanks for responses it became more clear what this flag does.

Quick tests with different compilers.

DMD from Arch repo compiles hello world (dmd -c main.d) in:
~0.1s
DMD compiled with DMD and stock flags
~0.12s
DMD compiled with ldc with -o2
~0.35s


DMD code gen is not that bad


Re: std.socket tutorials? examples?

2018-10-04 Thread bauss via Digitalmars-d-learn

On Thursday, 4 October 2018 at 13:09:17 UTC, bauss wrote:

On Thursday, 4 October 2018 at 13:07:30 UTC, bauss wrote:


buffer = buffer[0 .. $]; // Slice the buffer to the actual 
size of the received data.

```


Typo...

Was supposed to be "received" and not "$"...

buffer = buffer[0 .. received]; // Slice the buffer to the 
actual size


Another typo is "recv" should be "received".

That's what happens when you copy-paste from old code.


Re: std.socket tutorials? examples?

2018-10-04 Thread bauss via Digitalmars-d-learn

On Thursday, 4 October 2018 at 09:54:40 UTC, Chris Katko wrote:
On Thursday, 4 October 2018 at 08:52:28 UTC, Andrea Fontana 
wrote:

On Thursday, 4 October 2018 at 08:32:13 UTC, Chris Katko wrote:

I've been Google'ing and there's like... nothing out there.

One of the top results for "std.socket dlang examples"... is 
for TANGO. That's how old it is.


Socket paradigm is quite standard across languages.

Anyway you can find a couple of example here:
https://github.com/dlang/dmd/blob/master/samples/listener.d
https://github.com/dlang/dmd/blob/master/samples/htmlget.d

Andrea


I was hoping someone would have a walk-through or something. 
Those examples are 110 lines each!


Usually, with D, there's plenty of useful 
paradigms/templates/Phobos magic. So if I just port a C/C++/C# 
socket example over, how am I supposed to know if I'm doing it 
"the right/proper/best way" in D? That kind of thing.


Not exactly a tutorial or a walkthrough, but I'll try to explain 
basic usage of std.socket using an asynchronous tcp server as 
example.


Usually sockets are pretty low-level though, so not a lot of D 
magic will be present in the example.


First of all D implements classes for the two most common 
protocols UDP and TCP, both called UdpSocket and TcpSocket for 
obvious reasons.


We'll focus on TcpSocket in these examples, but using UdpSocket 
is not much different if you at the very least understand UDP and 
how it works.


The first thing you want to do for the server is creating a new 
instance of the TcpSocket class.


```
auto server = new TcpSocket;
```

Then to make it a non-blocking socket you simply set "blocking" 
to false.


This will call the low-level OS functions that creates 
non-blocking sockets on Windows it would be: ioctlsocket().


https://docs.microsoft.com/en-us/windows/desktop/api/winsock/nf-winsock-ioctlsocket

For Posix it would be fcntl() wih first "F_GETFL" and then 
"F_SETFL" where the flags are updated with "O_NONBLOCK"


http://man7.org/linux/man-pages/man2/fcntl.2.html

```
server.blocking = false;
```

The next thing we do is binding the socket.

In D you can use the "InternetAddress" class to construct a valid 
address for the socket.



```
server.bind(new InternetAddress(ip, port));
```

"ip" and "port" can be changed to the ip and port of your server.

Ex:

```
const ip = "127.0.0.1";
const port = 9988;
```

Once the socket has been bound then we can simply listen for 
connections.


It can be done with the listen function.

```
server.listen(100); // The backlog is set to 100, can be whatever 
you prefer.

```

As you can see so far there has been no real D magic, because 
it's pretty low-level.


Now to actual listen for the connections etc. it'll be a little 
more complex, because we're going to use the "SocketSet" class.


The major difference between something like implementing sockets 
in ex. C++ and D is that in D you don't have to implement your 
socket logic per platform, because phobos already creates that 
logic for you. Of course that's not taking something like boost 
into account which gives same usability in C++.


The next thing is to actually accept the sockets and since we're 
using non-blocking sockets then we don't really need to make a 
separate thread for accepting them, neither do the sockets 
actually need a thread for themselves.


First we need some collection that can hold all current sockets 
accepted (An array will be fine for now.)


```
Socket[] clients;
```

Then we'll create two instances of the "SocketSet" class.

That's because we need a socket set for the server socket and one 
for all the connected sockets.


```
auto serverSet = new SocketSet;
auto clientSet = new SocketSet;
```

A simple infinite while loop will be okay.

```
while (true)
{
...
}
```

Now let's dive into our loop, because this is where the "magic" 
of the socket handling actually happens.


At the beginning of the loop we'll want to reset the socket sets.

This can be done using the "reset" function.

This would most definitely be handled differently in a more 
performance critical server, but you'd also use multiple threads 
that each holds a set of sockets etc. we'll not do such things 
for the sake of simplicity.


```
serverSet.reset();
clientSet.reset();
```
First we want to add the server socket to "serverSet".

```
serverSet.add(server);
```

Next we'll loop through our client array and add each socket to 
the client set.


```
if (clients)
{
  foreach (client; clients)
  {
clientSet.add(client);
  }
}
```

At first we want to check if there are any new sockets connected 
that we can accept.


By calling "Socket.select()" we can get different socket states 
based on a socket set.


```
auto serverResult = Socket.select(serverSet, null, null);
```

If the result from "Socket.select()" is below 1 then there are no 
new sockets to accept.


If the result is 0 then it timed out, if it's -1 then it was 
interrupted.


We want to check for that before we can ca

Re: std.socket tutorials? examples?

2018-10-04 Thread bauss via Digitalmars-d-learn

On Thursday, 4 October 2018 at 13:07:30 UTC, bauss wrote:


buffer = buffer[0 .. $]; // Slice the buffer to the actual size 
of the received data.

```


Typo...

Was supposed to be "received" and not "$"...

buffer = buffer[0 .. received]; // Slice the buffer to the 
actual size


Re: std.socket tutorials? examples?

2018-10-04 Thread Adam D. Ruppe via Digitalmars-d-learn

On Thursday, 4 October 2018 at 08:32:13 UTC, Chris Katko wrote:

I've been Google'ing and there's like... nothing out there.


My book has a few examples
https://www.packtpub.com/application-development/d-cookbook


of course, buying it for just std.socket (which is just like one 
page out of the 300) is a bit silly, but the code examples are 
also here


http://arsdnet.net/dcode/book/chapter_02/03/


The code examples have little to no explanation (that's what the 
book is for lol) but std.socket is pretty simple so you can 
probably figure it out - like the others said, it is a very, very 
thin wrapper over the same basic BSD socket library every other 
language uses.


The client example is like 15 lines too so you can use it easily, 
and the server is only like 30 so that isn't too bad either.


The library docs http://dpldocs.info/std.socket can be used to 
look up the specific functions used.


Re: Compile time sequences

2018-10-04 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, October 4, 2018 5:44:55 AM MDT drug via Digitalmars-d-learn 
wrote:
> I was incorrect with description of the problem. The problem is that
> there is no simple way to distinct types and symbols if symbols are
> private. Because private symbol is not accessible you can not get any
> info on it, including is it type or symbol or value. And you can not get
> protection for types and values, because they have no protection at all.
> So you can not get protection for types and values and can not check if
> alias is type, value and symbol because it is private/protected. Vicious
> circle.
>
> Specific case https://run.dlang.io/is/CAoxXO
>
> Honestly, if `isType` can recognize private members the problem would be
> solved. But I think `isSymbol` and `isValue` (working with private
> members) will make situation more consistent.
>
>
> Current workaround with fields is using FieldNameTuple. But I fails to
> work around private enums.

It's a known issue that you can't properly do type introspection on private
symbols from other modules, and it needs to be fixed in the language. It
shouldn't be possible to actually use private symbols from other modules,
but it should be possible to get type information on them.

In his dconf talk this year, Andrei discussed adding wrappers around all of
the various traits that present the type information as a set of structs so
that you can easily and consistently get at it all instead of having to
piece it all together like you do now. He has a partial prototype, though I
don't know if he's made it public aside from what he showed in his sides,
and it's just wrapping the current stuff, so it's not addding any
information, just better organizing it. However, to get where he wants to go
with it, problems like this with private symbols are pretty much going to
have to be solved. Either way, the access level issues are a language issue
and not something that can be fixed by std.traits.

- Jonathan M Davis





Re: Compile time sequences

2018-10-04 Thread drug via Digitalmars-d-learn

04.10.2018 14:44, drug пишет:
I was incorrect with description of the problem. The problem is that 
there is no simple way to distinct types and symbols if symbols are 
private. Because private symbol is not accessible you can not get any 
info on it, including is it type or symbol or value. And you can not get 
protection for types and values, because they have no protection at all. 
So you can not get protection for types and values and can not check if 
alias is type, value and symbol because it is private/protected. Vicious 
circle.


Specific case https://run.dlang.io/is/CAoxXO

Honestly, if `isType` can recognize private members the problem would be 
solved. But I think `isSymbol` and `isValue` (working with private 
members) will make situation more consistent.



Current workaround with fields is using FieldNameTuple. But I fails to 
work around private enums.




I forget about scope in static foreach, this correct 
version:https://run.dlang.io/gist/97294d89d5c0b89ebcf009c18c4743d4


Re: Compile time sequences

2018-10-04 Thread drug via Digitalmars-d-learn
I was incorrect with description of the problem. The problem is that 
there is no simple way to distinct types and symbols if symbols are 
private. Because private symbol is not accessible you can not get any 
info on it, including is it type or symbol or value. And you can not get 
protection for types and values, because they have no protection at all. 
So you can not get protection for types and values and can not check if 
alias is type, value and symbol because it is private/protected. Vicious 
circle.


Specific case https://run.dlang.io/is/CAoxXO

Honestly, if `isType` can recognize private members the problem would be 
solved. But I think `isSymbol` and `isValue` (working with private 
members) will make situation more consistent.



Current workaround with fields is using FieldNameTuple. But I fails to 
work around private enums.




Re: std.socket tutorials? examples?

2018-10-04 Thread Chris Katko via Digitalmars-d-learn

On Thursday, 4 October 2018 at 08:52:28 UTC, Andrea Fontana wrote:

On Thursday, 4 October 2018 at 08:32:13 UTC, Chris Katko wrote:

I've been Google'ing and there's like... nothing out there.

One of the top results for "std.socket dlang examples"... is 
for TANGO. That's how old it is.


Socket paradigm is quite standard across languages.

Anyway you can find a couple of example here:
https://github.com/dlang/dmd/blob/master/samples/listener.d
https://github.com/dlang/dmd/blob/master/samples/htmlget.d

Andrea


I was hoping someone would have a walk-through or something. 
Those examples are 110 lines each!


Usually, with D, there's plenty of useful 
paradigms/templates/Phobos magic. So if I just port a C/C++/C# 
socket example over, how am I supposed to know if I'm doing it 
"the right/proper/best way" in D? That kind of thing.


Re: Private struct constructor

2018-10-04 Thread Ritchie via Digitalmars-d-learn

On Thursday, 4 October 2018 at 09:21:39 UTC, Simen Kjærås wrote:

This is apparently a known issue:

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

which is basically just a special case of this issue:

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

--
  Simen


I see. Looks like the chances of it being fixed anytime soon are 
slim. Thanks for the info.


Re: Private struct constructor

2018-10-04 Thread Simen Kjærås via Digitalmars-d-learn

On Thursday, 4 October 2018 at 08:52:50 UTC, Ritchie wrote:
I apologize for not making it clear. I was talking about the 
private constructor only. The @disable this() is there to 
prevent struct literal syntax and the other disables really 
have no reason to be there for the purpose of this question.


Oddly enough I asked this because I was working on something 
and was able to call the private constructor from another 
module, but then I created the run.dlang.io snippet to demo my 
problem.


Right. Reduced your example to this:

module bar;
struct S() {
private this()(int n) {}
}

module foo;
unittest {
import bar;
auto a = S!()(3);
}

This is apparently a known issue:

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

which is basically just a special case of this issue:

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

--
  Simen


Re: std.socket tutorials? examples?

2018-10-04 Thread Andrea Fontana via Digitalmars-d-learn

On Thursday, 4 October 2018 at 08:32:13 UTC, Chris Katko wrote:

I've been Google'ing and there's like... nothing out there.

One of the top results for "std.socket dlang examples"... is 
for TANGO. That's how old it is.


Socket paradigm is quite standard across languages.

Anyway you can find a couple of example here:
https://github.com/dlang/dmd/blob/master/samples/listener.d
https://github.com/dlang/dmd/blob/master/samples/htmlget.d

Andrea


Re: Private struct constructor

2018-10-04 Thread Ritchie via Digitalmars-d-learn

On Thursday, 4 October 2018 at 08:14:44 UTC, Simen Kjærås wrote:

On Thursday, 4 October 2018 at 07:31:21 UTC, Ritchie wrote:

Any reason why this works?

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


Yup.


Alright, so there's a few features in use here - which one are 
you asking about?


1. Private constructor.
You can call the private constructor because the unit of 
encapsulation in D is the module, not the type. So everything 
is visible to everything else inside the same module.


2. @disable this()
This only disables default construction. Since you call a 
different constructor, this doesn't affect the compilation.


3. @disable this(this)
This disables copy construction. In the example, no copying 
occurs - the variable declaration leads to a move instead. 
Simply put, copy construction requires that two copies exist 
simultaneously, and in this case the potential second copy is 
immediately destroyed, so no copy is necessary.


4. @disable void opAssign()
There's several reasons this doesn't affect compilation here. 
First, the signature is wrong - you're disabling an opAssign 
that takes no arguments. You're probably wanting to do @disable 
void opAssign(X x);.


Now, even that isn't going to cause it to fail to compile in 
this case though, since as in #3, what's happening on line 14 
is move construction, not assignment. To force an assignment, 
you need to have an object already:


X x = void;
x = X(5); // calls opAssign

So, now we've explained why it compiles. Currently, there's no 
way to @disable or hook move construction. There's a DIP in the 
works (DIP 1014) that aims to provide a hook into move 
construction, but I don't see that it allows for @disabling it 
altogether.


Hope this helps!

--
  Simen


I apologize for not making it clear. I was talking about the 
private constructor only. The @disable this() is there to prevent 
struct literal syntax and the other disables really have no 
reason to be there for the purpose of this question.


Oddly enough I asked this because I was working on something and 
was able to call the private constructor from another module, but 
then I created the run.dlang.io snippet to demo my problem.


I have this in one module: https://pastebin.com/J8r4fyK8

and this in another module:

void testUniquePtr() {
import bclib.memory.unique_ptr : Unique;

alias TestUnique = Unique!(int, TestMallocator);
{
auto unique = TestUnique(20);
assert(*unique == 20);
}
TestMallocator.check();
}

and it runs without complaints. (SmartPtrMembers doesnt have any 
constructors in it)


std.socket tutorials? examples?

2018-10-04 Thread Chris Katko via Digitalmars-d-learn

I've been Google'ing and there's like... nothing out there.

One of the top results for "std.socket dlang examples"... is for 
TANGO. That's how old it is.


Re: Private struct constructor

2018-10-04 Thread Simen Kjærås via Digitalmars-d-learn

On Thursday, 4 October 2018 at 07:31:21 UTC, Ritchie wrote:

Any reason why this works?

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


Yup.


Alright, so there's a few features in use here - which one are 
you asking about?


1. Private constructor.
You can call the private constructor because the unit of 
encapsulation in D is the module, not the type. So everything is 
visible to everything else inside the same module.


2. @disable this()
This only disables default construction. Since you call a 
different constructor, this doesn't affect the compilation.


3. @disable this(this)
This disables copy construction. In the example, no copying 
occurs - the variable declaration leads to a move instead. Simply 
put, copy construction requires that two copies exist 
simultaneously, and in this case the potential second copy is 
immediately destroyed, so no copy is necessary.


4. @disable void opAssign()
There's several reasons this doesn't affect compilation here. 
First, the signature is wrong - you're disabling an opAssign that 
takes no arguments. You're probably wanting to do @disable void 
opAssign(X x);.


Now, even that isn't going to cause it to fail to compile in this 
case though, since as in #3, what's happening on line 14 is move 
construction, not assignment. To force an assignment, you need to 
have an object already:


X x = void;
x = X(5); // calls opAssign

So, now we've explained why it compiles. Currently, there's no 
way to @disable or hook move construction. There's a DIP in the 
works (DIP 1014) that aims to provide a hook into move 
construction, but I don't see that it allows for @disabling it 
altogether.


Hope this helps!

--
  Simen


Re: Private struct constructor

2018-10-04 Thread Ritchie via Digitalmars-d-learn

On Thursday, 4 October 2018 at 07:55:48 UTC, Andrea Fontana wrote:

On Thursday, 4 October 2018 at 07:31:21 UTC, Ritchie wrote:

Any reason why this works?

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


Why not?


The constructor is private.


Re: Private struct constructor

2018-10-04 Thread John Chapman via Digitalmars-d-learn

On Thursday, 4 October 2018 at 07:31:21 UTC, Ritchie wrote:

Any reason why this works?

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


"private" applies to the module, not the type. 
https://dlang.org/spec/attribute.html#visibility_attributes


Re: Private struct constructor

2018-10-04 Thread Andrea Fontana via Digitalmars-d-learn

On Thursday, 4 October 2018 at 07:31:21 UTC, Ritchie wrote:

Any reason why this works?

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


Why not?


Private struct constructor

2018-10-04 Thread Ritchie via Digitalmars-d-learn

Any reason why this works?

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