Re: Installing D on Fresh Windows 10 machine is a pain

2020-08-28 Thread rikki cattermole via Digitalmars-d-learn

On 28/08/2020 3:59 AM, Jesse Phillips wrote:


DMD installer still is unable to find "VS installed"


One of the reasons for this is that the environment variables have not 
been updated.


You need to restart to do this.


Re: Installing D on Fresh Windows 10 machine is a pain

2020-08-28 Thread Jacob Carlborg via Digitalmars-d-learn

On Friday, 28 August 2020 at 05:38:59 UTC, novice3 wrote:
DMD x86 on Windows have no dependencies, just unpack .zip and 
use.

It's a pitty, that DMD x64 depend on VS :(


It does not. If VS is not installed the MinGW provided libraries, 
which are bundled, will be used.


--
/Jacob Carlborg


Re: Wrong selection of opEquals for objects.

2020-08-28 Thread Simen Kjærås via Digitalmars-d-learn
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.

2020-08-28 Thread Alexandru Ermicioi via Digitalmars-d-learn

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.


- Alex


Re: How to define delegate what returns ref?

2020-08-28 Thread Oleg B via Digitalmars-d-learn

On Friday, 28 August 2020 at 11:50:35 UTC, kinke wrote:

On Friday, 28 August 2020 at 11:46:15 UTC, Oleg B wrote:

How to do this more clearly?


alias Dg = ref int delegate();
Dg foo;


Thanks!


Re: How do I convert an ISO 8601 datetime into a unix timestamp - at compile-time?

2020-08-28 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/27/20 9:54 PM, Andrej Mitrovic wrote:

-
import std.datetime;

void main ()
{
     static time =
SysTime(DateTime.fromISOString("20220101T00")).toUnixTime;
}
-

-
/Library/D/dmd/src/phobos/std/concurrency.d(2574): Error: static 
variable lock cannot be read at compile time
/Library/D/dmd/src/phobos/std/concurrency.d(2574):    called from 
here: atomicLoad(lock)
/Library/D/dmd/src/phobos/std/concurrency.d(2600):    called from 
here: initOnceLock()
/Library/D/dmd/src/phobos/std/concurrency.d(2600):    called from 
here: initOnce(delegate shared(bool)() pure @nogc @safe => init(), 
initOnceLock())
/Library/D/dmd/src/phobos/std/datetime/timezone.d(1106): called from 
here: initOnce(delegate shared(bool)() pure nothrow @nogc @safe => 
(*function () nothrow @nogc @safe => true)())
/Library/D/dmd/src/phobos/std/datetime/timezone.d(546): called from 
here: (*& singleton)()
/Library/D/dmd/src/phobos/std/datetime/systime.d(524): called from here: 
opCall()
/Library/D/dmd/src/phobos/std/datetime/systime.d(472): called from here: 
this.this(dateTime, zero(), tz)
test.d(6):    called from here: SysTime(0L, Rebindable(null, 
)).this(fromISOString("20220101T00"), null)

-

I'm sure there must be a better way to do this. But I couldn't find it 
in the documentation.


It's trying to look up the local timezone at compile time.

You need to specify a time zone:

static time =
SysTime(DateTime.fromISOString("20220101T00"), 
UTC()).toUnixTime;


-Steve


Re: Wrong selection of opEquals for objects.

2020-08-28 Thread Simen Kjærås via Digitalmars-d-learn
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 
(https://dlang.org/spec/operatoroverloading.html#equals):


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: How to define delegate what returns ref?

2020-08-28 Thread kinke via Digitalmars-d-learn

On Friday, 28 August 2020 at 11:46:15 UTC, Oleg B wrote:

How to do this more clearly?


alias Dg = ref int delegate();
Dg foo;


How to define delegate what returns ref?

2020-08-28 Thread Oleg B via Digitalmars-d-learn

Hello all!

syntax

ref int delegate() foo0;

or

ref(int) delegate() foo1;

or

int delegate() ref foo2;

are not valid.

if I try alias

alias refint = ref int;
refint delegate() foo3;

foo3 have type `int delegate()` (without `ref`)
and it can't store delegate from object method that have `int 
delegate() ref` (that can be printed if we use 
`typeof(&someobject.method).stringof`)


I found only one ugly way to do this

interface Foo { ref int func(); }
typeof(&Foo.init.func) foo4;

How to do this more clearly?


Re: Wrong selection of opEquals for objects.

2020-08-28 Thread Alexandru Ermicioi via Digitalmars-d-learn
On Friday, 28 August 2020 at 10:42:09 UTC, Alexandru Ermicioi 
wrote:

...
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?


Re: Wrong selection of opEquals for objects.

2020-08-28 Thread Alexandru Ermicioi via Digitalmars-d-learn

On Friday, 28 August 2020 at 10:28:07 UTC, Simen Kjærås wrote:

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


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.


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?


- Alex.



Re: Wrong selection of opEquals for objects.

2020-08-28 Thread Simen Kjærås via Digitalmars-d-learn
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: in; scope; scope ref; DIP1000; documentation

2020-08-28 Thread Mathias LANG via Digitalmars-d-learn

On Thursday, 27 August 2020 at 18:49:19 UTC, James Blachly wrote:
Peeling off from Mathias Lang's thread in General about making 
'in' useful, for some novice questions:



1. The thread involves 'in' qualifier. Documentation 
(https://dlang.org/spec/function.html#param-storage) indicates 
that `in` is defined as `scope const` and should not be used as 
it is not implemented. **Is this [fact and recommendation] 
still true?**


I have a PR to update the documentation: 
https://github.com/dlang/dlang.org/pull/2845
I got feedback on it, just didn't have time to complete / finish 
it, will come back to it soon.


Is "scope ref" documented somewhere specifically? I found 
https://dlang.org/spec/function.html#scope-parameters which 
discusses the use of `scope` with ref type parameters, but the 
example given is pointer-based. Is it correct that `scope ref 
T` behaves the same as `scope T*` ?


Regarding `scope` more generally, DIP1000 shows as "superseded" 
-- **can I still rely on this document for guidance?** We have 
a `-dip1000` flag but a superseded DIP. The discordance is 
extremely confusing.


It is, for users and compilers developers alike. We're still 
waiting for Walter to write down the docs on that. If you look in 
the forums / PRs, you'll see that it's the most common feedback.


I am glad D is iterating quickly and improving on safety, but I 
have found that documentation may not well recent changes in 
this area. Consequently I am reluctant to use (newer) features 
related to memory safety. If this is all comprehensively 
documented somewhere please let me know!


We have a policy that every language change should come with a 
spec PR. It has improved documentation drastically, but there's 
still a way to go.


I hope the aforementioned PR will clarify the status of `in`. I'm 
currently focusing on making sure it works properly everywhere 
before the next release (in 1 or 2 weeks), hence why fixing that 
PR has taken the back-seat (the website gets auto-updated, so 
even if the PR doesn't make the deadline, it'll be deployed as 
soon as it gets merged).


Re: Wrong selection of opEquals for objects.

2020-08-28 Thread Alexandru Ermicioi via Digitalmars-d-learn
On Friday, 28 August 2020 at 08:16:01 UTC, Alexandru Ermicioi 
wrote:

Hi everyone,



Would be glad at least to pointers, where in dmd is logic for 
operator overloading happens, as well as for overloading rules, 
so I could fix it myself, if no-one is able to pick up it.


Wrong selection of opEquals for objects.

2020-08-28 Thread Alexandru Ermicioi via Digitalmars-d-learn

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.