Re: Best way to make a template function conditionally @trusted

2021-04-03 Thread tsbockman via Digitalmars-d-learn

On Friday, 2 April 2021 at 19:49:30 UTC, ikod wrote:

On Thursday, 1 April 2021 at 22:35:01 UTC, tsbockman wrote:
Suppose I have a templated struct member function for which I 
can compute at compile-time when the function is memory safe, 
and when it is not. But, the compiler cannot correctly 
determine this automatically.


Compiler should be able to derive safety of templated 
functions. You may just omit `@safe`/`@trusted`.


The compiler's approach to verifying memory safety is very 
simplistic: it declares a function non-`@safe` if any potentially 
unsafe operation is found in its implementation, without regard 
for the context. It can only ever infer `@safe` or `@system`, 
never `@trusted`.


The reason `@trusted` is in the language at all is to allow the 
programmer to manually mark as memory safe those functions which 
contain operations that would be unsafe in some other context, 
but which the programmer has manually analyzed and verified to be 
incapable of violating memory safety, no matter what inputs it 
receives.


Consider the following program:
```D
import std.stdio;

void writeSafe()(int[2] stuff ...) {
foreach(n; 0 .. stuff.length)
writeln(stuff[n]);
}
void writeTrusted()(int[2] stuff ...) {
foreach(n; 0 .. stuff.length)
writeln(stuff.ptr[n]);
}

void main() @safe {
writeSafe(3, 5);
writeTrusted(3, 5);
}
```

`writeSafe` and `writeTrusted` generate identical code, and are 
equally memory safe in reality. The compiler even knows this on 
some level, because it correctly deduces that the bounds check 
for `stuff[n]` can never fail, and omits it even in `writeSafe`.


Nevertheless, because `.ptr` can be used to violate memory safety 
in other contexts, `writeSafe` is inferred as `@safe`, while 
`writeTrusted` is inferred as `@system`. And so, the program 
above will not compile as it stands.


This is, of course, a trivial example where there is no benefit 
to using the non-`@safe` version, but there are more complex 
cases where the desired algorithm is memory safe as a whole, but 
it cannot be expressed in D without using some operations that 
are forbidden in `@safe` code.


Re: Example for Mir-Random fails

2021-04-03 Thread Brad via Digitalmars-d-learn

On Saturday, 3 April 2021 at 20:55:40 UTC, Preetpal wrote:

On Saturday, 3 April 2021 at 19:02:34 UTC, Brad wrote:
Obviously it is a type mismatch - I have tried using to!uint 
to convert the result from unpredictableSeed to a type that 
will match - but that just causes more errors.


Thank you in advance.


I was able to compile the sample without any issue and it was 
able to run. Can you give more information about your 
environment and possibly create a minimal example that 
re-creates the issue like in a Github repository?


I figured out that I had not purged all the Phobos random imports 
from my code and the issue was related to the two libraries not 
playing well together.


It is working now.

Interestingly though - the example code will not compile in the D 
Playground.  I am not going to worry about that.  It is working 
for me now.


Thanks


Re: Example for Mir-Random fails

2021-04-03 Thread Brad via Digitalmars-d-learn

On Saturday, 3 April 2021 at 22:04:33 UTC, Bastiaan Veelo wrote:

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

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

[...]


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


— Bastiaan.


You nailed it.  I just now figured that out.  It never ceases to 
amaze me how much time can my lost to a simple mistake like that.


Thank you.


Re: Example for Mir-Random fails

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

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

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

[...]


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


— Bastiaan.


Re: Example for Mir-Random fails

2021-04-03 Thread Preetpal via Digitalmars-d-learn

On Saturday, 3 April 2021 at 19:02:34 UTC, Brad wrote:
Obviously it is a type mismatch - I have tried using to!uint to 
convert the result from unpredictableSeed to a type that will 
match - but that just causes more errors.


Thank you in advance.


I was able to compile the sample without any issue and it was 
able to run. Can you give more information about your environment 
and possibly create a minimal example that re-creates the issue 
like in a Github repository?


Example for Mir-Random fails

2021-04-03 Thread Brad via Digitalmars-d-learn
I just do not know enough about the D libraries to figure out 
what is wrong.  I know it is a case of type mismatch.  The 
example appears on the Mir-Random page as listed under DUB:

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

The code looks like this:

```d
void main()
{
import mir.random;
import mir.random.variable: normalVar;
import mir.random.algorithm: randomSlice;

// Engines are allocated on stack or global
auto rng = Random(unpredictableSeed);
auto sample = rng.randomSlice(normalVar, 10);

import std.stdio;
sample[rng.randIndex($)].writeln;
}
```

This is the error I am seeing (I slapped the sample code into 
another program that flips a coin... It compiles file without the 
sample code):


```d
source\flipcoin.d(39,20): Error: constructor 
`std.random.MersenneTwisterEngine!(uint, 32LU, 624LU, 397LU, 
31LU, 2567483615u, 11LU, 4294967295u, 7LU, 2636928640u, 15LU, 
4022730752u, 18LU, 1812433253u).MersenneTwisterEngine.this(uint 
value)` is not callable using argument types `(ulong)`
source\flipcoin.d(39,20):cannot pass argument 
`unpredictableSeed()` of type `ulong` to parameter `uint value`

```

Obviously it is a type mismatch - I have tried using to!uint to 
convert the result from unpredictableSeed to a type that will 
match - but that just causes more errors.


Thank you in advance.


Re: Extern/scope issue

2021-04-03 Thread DLearner via Digitalmars-d-learn

On Saturday, 3 April 2021 at 13:50:27 UTC, ag0aep6g wrote:

On 03.04.21 15:34, DLearner wrote:

The following produces the expected result.
However, changing extern(C) to extern(D) causes linker 
failures.

To me, that is bizarre.
Testmain:
extern(C) int xvar;

[...]


Testmod:
extern extern(C) int xvar;


With `extern (C)`, those two `xvar`s refer to the same data.
Without `extern (C)` (or with `extern (D)`), they are distinct 
variables with no relation to another. In D, you don't 
re-declare another module's symbols. You import the other 
module.



module testmain;

import std.stdio: writeln;
import testmod: testsub, xvar;

void main()
{
xvar = 1;
writeln(xvar); /* prints "1" */
testsub();
writeln(xvar); /* prints "2" */
}



module testmod;

int xvar; /* same as `extern (D) int xvar;` */

void testsub()
{
   xvar = 2;
}



Thank you, your suggestions worked.
No externs anywhere.
For the record, the code is below.
import itf;
import testmod:testsub;
void main() {
   import std.stdio;

   writeln("Entering: main");
   xvar = 1;
   writeln("xvar=", xvar);
   testsub();
   writeln("xvar=", xvar);

   writeln("Leaving: main");
}

module itf;
int xvar;

module testmod;
import itf;
void testsub() {

   import std.stdio;

   writeln("Entering: testsub");
   writeln("xvar=", xvar);
   xvar = 2;
   writeln("xvar=", xvar);
   writeln("Leaving: testsub");
}







Re: Extern/scope issue

2021-04-03 Thread rikki cattermole via Digitalmars-d-learn



On 04/04/2021 2:48 AM, DLearner wrote:

On Saturday, 3 April 2021 at 13:38:25 UTC, rikki cattermole wrote:


On 04/04/2021 2:34 AM, DLearner wrote:

However, changing extern(C) to extern(D) causes linker failures.
To me, that is bizarre.


extern(D) sets the ABI AND mangling.

D mangling incorporates things like the module name.


I'm sure you are correct, but extern(C) -> extern(D) in both references.
So both source streams are aware of the convention used.


https://dlang.org/spec/abi.html#name_mangling


Re: Extern/scope issue

2021-04-03 Thread ag0aep6g via Digitalmars-d-learn

On 03.04.21 15:34, DLearner wrote:

The following produces the expected result.
However, changing extern(C) to extern(D) causes linker failures.
To me, that is bizarre.
Testmain:
extern(C) int xvar;

[...]


Testmod:
extern extern(C) int xvar;


With `extern (C)`, those two `xvar`s refer to the same data.
Without `extern (C)` (or with `extern (D)`), they are distinct variables 
with no relation to another. In D, you don't re-declare another module's 
symbols. You import the other module.



module testmain;

import std.stdio: writeln;
import testmod: testsub, xvar;

void main()
{
xvar = 1;
writeln(xvar); /* prints "1" */
testsub();
writeln(xvar); /* prints "2" */
}



module testmod;

int xvar; /* same as `extern (D) int xvar;` */

void testsub()
{
   xvar = 2;
}



Re: Extern/scope issue

2021-04-03 Thread DLearner via Digitalmars-d-learn

On Saturday, 3 April 2021 at 13:38:25 UTC, rikki cattermole wrote:


On 04/04/2021 2:34 AM, DLearner wrote:
However, changing extern(C) to extern(D) causes linker 
failures.

To me, that is bizarre.


extern(D) sets the ABI AND mangling.

D mangling incorporates things like the module name.


I'm sure you are correct, but extern(C) -> extern(D) in both 
references.

So both source streams are aware of the convention used.


templated overload of opAssign

2021-04-03 Thread kdevel via Digitalmars-d-learn

Why does this code

```d
import std.stdio,std.typecons;

struct EC {
   Exception [] ex;
   auto opAssign (X: void) (lazy X f)
   {
  writeln (__PRETTY_FUNCTION__);
  try return f (); catch (Exception e) ex ~= e;
   }
}

class E : Exception { this (string s) { super (s); } }
void bar (int i) { if (i == 1) throw new E ("E"); }

void main ()
{
   EC ec;

   ec.opAssign (bar (1)); // okay
//   ec = bar (1); // Error: expression bar(1) is void and has no 
value


   ec.writeln;
}
```

compile with the abovementioned error?


Re: Extern/scope issue

2021-04-03 Thread rikki cattermole via Digitalmars-d-learn



On 04/04/2021 2:34 AM, DLearner wrote:

However, changing extern(C) to extern(D) causes linker failures.
To me, that is bizarre.


extern(D) sets the ABI AND mangling.

D mangling incorporates things like the module name.


Re: Extern/scope issue

2021-04-03 Thread DLearner via Digitalmars-d-learn
The __gshared is irrelevant to it working between modules, but 
it is relevant if you want C compatibility between threads 
(NOTE: extern(C) sets mangling, otherwise the module would be 
encoded in its name).

Solved:
The following produces the expected result.
However, changing extern(C) to extern(D) causes linker failures.
To me, that is bizarre.
Testmain:
extern(C) int xvar;
import testmod;
void main() {
   import std.stdio;

   writeln("Entering: main");
   xvar = 1;
   writeln("xvar=", xvar);
   testsub();
   writeln("xvar=", xvar);

   writeln("Leaving: main");
}

Testmod:
extern extern(C) int xvar;
void testsub() {

   import std.stdio;

   writeln("Entering: testsub");
   writeln("xvar=", xvar);
   xvar = 2;
   writeln("xvar=", xvar);
   writeln("Leaving: testsub");
}



Re: Extern/scope issue

2021-04-03 Thread rikki cattermole via Digitalmars-d-learn



--- main.d
module main;

extern(C) __gshared int foo;

import std;
void main()
{
import foo : func;
func;

writeln(foo);
}

--- foo.d
module foo;
extern extern(C) __gshared int foo;

void func() {
foo++;
}

The __gshared is irrelevant to it working between modules, but it is 
relevant if you want C compatibility between threads (NOTE: extern(C) 
sets mangling, otherwise the module would be encoded in its name).


Re: Extern/scope issue

2021-04-03 Thread DLearner via Digitalmars-d-learn

https://dlang.org/spec/attribute.html#gshared

However, you should be using the module system for accessing 
globals, rather than redeclaring them.


If the module system is dumped, and evrything put into one file, 
works perfectly.

With or without __gshared in from of 'int xvar'.

int xvar;
void main() {
   import std.stdio;

   writeln("Entering: main");
   xvar = 1;
   writeln("xvar=", xvar);
   testsub();
   writeln("xvar=", xvar);

   writeln("Leaving: main");
}

void testsub() {
   import std.stdio;

   writeln("Entering: testsub");
   writeln("xvar=", xvar);
   xvar = 2;
   writeln("xvar=", xvar);
   writeln("Leaving: testsub");
}



Re: Extern/scope issue

2021-04-03 Thread DLearner via Digitalmars-d-learn
extern(L) extern otherQualifiersIfAny variableType 
variableName; //appears to be a variable declared outside of 
the module, so at link time a .obj file will have to declare a 
variable with this symbol name or else the linker will error 
out.

```
It seems that case 4 is what you desired but i do not know if 
with this module hierarchy it can/will work with dub.(it 
should.)
With the code as is you should be able to access both variables 
from main with `testmod.xvar` and simply `xvar`.(when name 
conflicts like this occur the most local is used by default, 
otherwise use the full name which should be `testmain.xvar` in 
this case.)


I tried case 4, failed with link errors.

I am not trying to establish two variables, just exactly the same 
one everywhere.

That's why the desired test output is 1,1,2,2


Re: Extern/scope issue

2021-04-03 Thread DLearner via Digitalmars-d-learn

Tried the following, same result (1,0,2,1):
testmain:
__gshared int xvar;
import testmod;

void main() {
   import std.stdio;

   writeln("Entering: main");
   xvar = 1;
   writeln("xvar=", xvar);
   testsub();
   writeln("xvar=", xvar);

   writeln("Leaving: main");
}

testmod:
void testsub() {
   __gshared int xvar;

   import std.stdio;

   writeln("Entering: testsub");
   writeln("xvar=", xvar);
   xvar = 2;
   writeln("xvar=", xvar);
   writeln("Leaving: testsub");
}



Re: Extern/scope issue

2021-04-03 Thread z via Digitalmars-d-learn

On Saturday, 3 April 2021 at 10:17:14 UTC, DLearner wrote:

Does this mean D has no equivalent of C globals?
What is the D way of doing this?


With __gshared.
If the global is defined from within another language, apparently 
you'd have to do [extern(C) extern __gshared 
*name*](https://dlang.org/spec/interfaceToC.html#c-globals)
It seems that the whole extern keyword can be confusing with 
variables:


```d
//L is the language name
extern(L) returnType functionName(parameters); // function 
implemented in another language or out of this module.


extern(L) returnType functionName(parameters) {/*...*/}//extern 
only changes the name mangling and the calling rules in the 
resulting assembly code.(with D it does not change anything?)


extern(L) variableType variableName; //what you did, declares a 
normal variable, except that the name mangling rule is that of 
the language you specified.


extern(L) extern otherQualifiersIfAny variableType variableName; 
//appears to be a variable declared outside of the module, so at 
link time a .obj file will have to declare a variable with this 
symbol name or else the linker will error out.

```
It seems that case 4 is what you desired but i do not know if 
with this module hierarchy it can/will work with dub.(it should.)
With the code as is you should be able to access both variables 
from main with `testmod.xvar` and simply `xvar`.(when name 
conflicts like this occur the most local is used by default, 
otherwise use the full name which should be `testmain.xvar` in 
this case.)


Re: Extern/scope issue

2021-04-03 Thread rikki cattermole via Digitalmars-d-learn



On 03/04/2021 11:17 PM, DLearner wrote:

On Saturday, 3 April 2021 at 10:05:45 UTC, rikki cattermole wrote:

On 03/04/2021 11:01 PM, DLearner wrote:

[...]


TLS variable with D mangling, not a c global.


 [...]


That is a regular variable.
Setting the calling convention/mangling like that doesn't make any 
sense and shouldn't be allowed in context.



[...]



TLS variable with D mangling, not a c global.

Does this mean D has no equivalent of C globals?
What is the D way of doing this?


https://dlang.org/spec/attribute.html#gshared

However, you should be using the module system for accessing globals, 
rather than redeclaring them.


Re: Deprecation message when assigning Nullable values to an associative array.

2021-04-03 Thread Peter Jacobs via Digitalmars-d-learn

On Saturday, 3 April 2021 at 10:03:09 UTC, rikki cattermole wrote:


On 03/04/2021 10:58 PM, rikki cattermole wrote:

Nullable has an alias this which has been deprecated.

It is due for removal (the alias this).

You can remove it manually from your copy of phobos source.

Otherwise you'll just have to wait until it is removed 
upstream. (deprecation are not errors, so you can ignore them).


So yeah, next release.

https://github.com/dlang/phobos/commit/36c309fc5fb5bc886e14bd8010e1375fa3a57d53#diff-81bed7f05cbd4e992067b7019125e6a1349ebe5098c6980b64bbbca8d5491e17


Thank you.  I am happy with this situation.

PJ



Re: Extern/scope issue

2021-04-03 Thread DLearner via Digitalmars-d-learn

On Saturday, 3 April 2021 at 10:05:45 UTC, rikki cattermole wrote:

On 03/04/2021 11:01 PM, DLearner wrote:

[...]


TLS variable with D mangling, not a c global.


 [...]


That is a regular variable.
Setting the calling convention/mangling like that doesn't make 
any sense and shouldn't be allowed in context.



[...]



TLS variable with D mangling, not a c global.

Does this mean D has no equivalent of C globals?
What is the D way of doing this?


Re: Extern/scope issue

2021-04-03 Thread rikki cattermole via Digitalmars-d-learn

On 03/04/2021 11:01 PM, DLearner wrote:

'Testmain' imports module 'testmod'.
Both are shown below.
I expected 1,1,2,2.
I got 1,0,2,1 - which speaks to scope/extern misunderstanding

Any ideas?
Best regards

Testmain:

int xvar;


TLS variable with D mangling, not a c global.


import testmod;
void main() {
   import std.stdio;

   writeln("Entering: main");
   xvar = 1;
   writeln("xvar=", xvar);
   testsub();
   writeln("xvar=", xvar);

   writeln("Leaving: main");
}

Testmod:

void testsub() {

   extern(D) int xvar;


That is a regular variable.
Setting the calling convention/mangling like that doesn't make any sense 
and shouldn't be allowed in context.



   import std.stdio;

   writeln("Entering: testsub");
   writeln("xvar=", xvar);
   xvar = 2;
   writeln("xvar=", xvar);
   writeln("Leaving: testsub");
}





Extern/scope issue

2021-04-03 Thread DLearner via Digitalmars-d-learn

'Testmain' imports module 'testmod'.
Both are shown below.
I expected 1,1,2,2.
I got 1,0,2,1 - which speaks to scope/extern misunderstanding

Any ideas?
Best regards

Testmain:

int xvar;
import testmod;
void main() {
   import std.stdio;

   writeln("Entering: main");
   xvar = 1;
   writeln("xvar=", xvar);
   testsub();
   writeln("xvar=", xvar);

   writeln("Leaving: main");
}

Testmod:

void testsub() {

   extern(D) int xvar;
   import std.stdio;

   writeln("Entering: testsub");
   writeln("xvar=", xvar);
   xvar = 2;
   writeln("xvar=", xvar);
   writeln("Leaving: testsub");
}



Re: Deprecation message when assigning Nullable values to an associative array.

2021-04-03 Thread rikki cattermole via Digitalmars-d-learn



On 03/04/2021 10:58 PM, rikki cattermole wrote:

Nullable has an alias this which has been deprecated.

It is due for removal (the alias this).

You can remove it manually from your copy of phobos source.

Otherwise you'll just have to wait until it is removed upstream. 
(deprecation are not errors, so you can ignore them).


So yeah, next release.

https://github.com/dlang/phobos/commit/36c309fc5fb5bc886e14bd8010e1375fa3a57d53#diff-81bed7f05cbd4e992067b7019125e6a1349ebe5098c6980b64bbbca8d5491e17


Re: Deprecation message when assigning Nullable values to an associative array.

2021-04-03 Thread rikki cattermole via Digitalmars-d-learn

Nullable has an alias this which has been deprecated.

It is due for removal (the alias this).

You can remove it manually from your copy of phobos source.

Otherwise you'll just have to wait until it is removed upstream. 
(deprecation are not errors, so you can ignore them).


Deprecation message when assigning Nullable values to an associative array.

2021-04-03 Thread Peter Jacobs via Digitalmars-d-learn
I am using the OpenMPI binding and, in recent times, I have been 
getting a deprecation message when compiling.  It seems to be 
related to assigning Nullable!int entries to an associative 
array.  The following program shows the same message three times 
but it does run as I expect.



import std.stdio, std.typecons;

void main(string[] args)
{
Nullable!(int)[string] my_entries;
// First way.
my_entries["A"] = Nullable!int.init;
// Second way.
Nullable!(int) empty;
my_entries["B"] = empty;
// Third way.
my_entries["C"] = 0.nullable;
my_entries["C"].nullify();
writeln("my_entries=", my_entries);

Nullable!(int) b = Nullable!int.init;
writeln("b=", b);
Nullable!(int) c = 0.nullable;
writeln("c=", c);
}



peterj@helmholtz ~/work/play/dlang $ dmd null_test.d
null_test.d(7): Deprecation: function 
`std.typecons.Nullable!int.Nullable.get_` is deprecated - 
Implicit conversion with `alias Nullable.get this` will be 
removed after 2.096. Please use `.get` explicitly.
null_test.d(10): Deprecation: function 
`std.typecons.Nullable!int.Nullable.get_` is deprecated - 
Implicit conversion with `alias Nullable.get this` will be 
removed after 2.096. Please use `.get` explicitly.
null_test.d(12): Deprecation: function 
`std.typecons.Nullable!int.Nullable.get_` is deprecated - 
Implicit conversion with `alias Nullable.get this` will be 
removed after 2.096. Please use `.get` explicitly.

peterj@helmholtz ~/work/play/dlang $ ./null_test
my_entries=["A":Nullable.null, "C":Nullable.null, 
"B":Nullable.null]

b=Nullable.null
c=0


Can someone please tell me how I should set these associative 
array entries such that I keep the compiler happy?