Re: Manu's `shared` vs the @trusted promise

2018-10-22 Thread Nicholas Wilson via Digitalmars-d

On Monday, 22 October 2018 at 11:24:27 UTC, Dukc wrote:
Frankly, this does not sound credible. According to this 
rationale, array access should be @system too, because it 
relies on the array not giving direct access to its length to 
the user, which would also in itself be @safe.


For reading, its a size_t so can be done with atomics, writing 
OTOH is a @property that calls a function to reallocate if ned 
be. Reallocation obviously needs to be locked.


Re: shared - i need it to be useful

2018-10-21 Thread Nicholas Wilson via Digitalmars-d

On Monday, 22 October 2018 at 00:55:00 UTC, Timon Gehr wrote:

On 22.10.18 02:46, Nicholas Wilson wrote:

On Monday, 22 October 2018 at 00:38:33 UTC, Timon Gehr wrote:

I just did,


Link please?



https://forum.dlang.org/post/pqii8k$11u3$1...@digitalmars.com


That contains no code.

Not all of the parties that participate in the data race are in 
@trusted code.


There are two cases of @trusted code, bad and good. Bad trusted 
code can indeed be misused by @safe code to corrupt memory. Good 
trusted code cannot.


What part of the proposal breaks the type system? The implicit 
conversion to shared implies that the passed to function is @safe 
iff all the functions it calls are @safe only call function with 
that parameter to other shared @safe functions _OR_ they are 
@trusted.


The point of @trusted is modularity: you manually check 
@trusted code according to some set of restrictions and then 
you are sure that there is no memory corruption.


Yes. And?


Re: shared - i need it to be useful

2018-10-21 Thread Nicholas Wilson via Digitalmars-d

On Monday, 22 October 2018 at 00:46:04 UTC, Walter Bright wrote:
That's what I was referring to, and Manu's example. It doesn't 
work, as I pointed out.


I'm pretty sure it does, but please repeat it.

We will eventually. This started as a "please point out any 
problems with this" and has probably outlived that phase.


You'll need to address the issues raised here in the DIP.


That is a given. You would do well to heed it for your own DIPs.


Re: shared - i need it to be useful

2018-10-21 Thread Nicholas Wilson via Digitalmars-d

On Monday, 22 October 2018 at 00:38:33 UTC, Timon Gehr wrote:

I just did,


Link please?



Re: shared - i need it to be useful

2018-10-21 Thread Nicholas Wilson via Digitalmars-d

On Monday, 22 October 2018 at 00:32:35 UTC, Timon Gehr wrote:
This only works if untrusted programmers (i.e. programmers who 
are only allowed to write/modify @safe code) are not allowed to 
change your class. I.e. it does not work.


This is the basis of the current @safe/@trusted/@system model.
Are you saying it is useless?


Re: shared - i need it to be useful

2018-10-21 Thread Nicholas Wilson via Digitalmars-d

On Sunday, 21 October 2018 at 22:12:18 UTC, Neia Neutuladh wrote:

On Sun, 21 Oct 2018 12:04:16 -0700, Manu wrote:
On Sun, Oct 21, 2018 at 12:00 PM Timon Gehr via Digitalmars-d 
 wrote:
Note that there may well be a good way to get the good 
properties of MP without breaking the type system, but MP 
itself is not good because it breaks @safe.


Show me. Nobody has been able to show that yet. I'd really 
like to know this.


If we only used your proposal and only used @safe code, we 
wouldn't have any data races,


Only of the @trusted implementation is thread safe, which it 
_should_ be. This is the same caveat as non threaded 
-@safe/@tusted code.


but that's only because we wouldn't have any shared data. We'd 
have shared *variables*, but they would not contain any data we 
could read


Reads must be atomic.


or alter, and that's pretty much useless.

To use your proposal, we need to cast data back from shared to 
unshared.


Yes but this is in the @trusted implementation that forms the 
basis of your threadsafety.


When it's unshared, we need to make sure that exactly one 
thread has a reference to that data as unshared.


Nod.


And @safe *should* help us with that.


Nod.

Currently, it helps because casting unshared to shared is not 
@safe,


This remains the case, and should be done (enforced by the 
compiler) only in @trusted/@system code as a basis for thread 
safe, @safe code.


because it makes it trivial to get multiple threads with 
unshared references to the same data.


That is @trusted or @system code and therefore is the programmers 
responsibility.


And that's when you're using shared as expected rather than 
doing something weird.


That forms the basis of your thread safe stack. From there on, 
the basis that shared arguments to functions are treated safely 
in the presence of threading means that code that calls the 
@trusted implementations is @safe.


Re: shared - i need it to be useful

2018-10-21 Thread Nicholas Wilson via Digitalmars-d

On Sunday, 21 October 2018 at 21:32:14 UTC, Walter Bright wrote:

On 10/21/2018 2:08 PM, Walter Bright wrote:

On 10/21/2018 12:20 PM, Nicholas Wilson wrote:
Yes, but the problem you describe is arises from implicit 
conversion in the other direction, which is not part of the 
proposal.


It's Manu's example.


Then I don't know what the proposal is. Pieces of it appear to 
be scattered over numerous posts, mixed in with other text, 
opinions, and handwavy stuff. There's nothing to point to that 
is "the proposal".


The proposal is:

Implicit conversion _to_ shared, e.g. passing it to a thread 
entry point, and not implicit conversion _from_ shared (just like 
implicit const conversions).


Shared disables reads and writes

 Your confusion results from the use of atomic add which, in 
Manu's examples had a different signature than before.


I suggest you and Manu write up a proper proposal. Something 
that is complete, has nothing else in it, has a rationale, 
illuminating examples, and explains why alternatives are 
inferior.


We will eventually. This started as a "please point out any 
problems with this" and has probably outlived that phase.



Trying to rewrite the semantics of shared is not a simple task,


Not as much as trying to explain it! Having talked to Manu in 
person it is much easier to understand.


doing multithreading correctly is a minefield of "OOPS! I 
didn't think of that!"


The above case in point, this is about assuming your 
implementation of thread safe primitives are thread safe 
(@trusted) that you use it correctly (@safe).





Re: shared - i need it to be useful

2018-10-21 Thread Nicholas Wilson via Digitalmars-d

On Sunday, 21 October 2018 at 19:07:37 UTC, Nicholas Wilson wrote:

On Sunday, 21 October 2018 at 09:50:09 UTC, Walter Bright wrote:
Your proposal makes that impossible because the compiler would 
allow unshared data to be implicitly typed as shared.


Yes, but not the other way around.


Whoops that should read


Your proposal makes that impossible


No

because the compiler would allow unshared data to be 
implicitly typed as shared.


Yes, but the problem you describe is arises from implicit 
conversion in the other direction, which is not part of the 
proposal.


Re: shared - i need it to be useful

2018-10-21 Thread Nicholas Wilson via Digitalmars-d

On Sunday, 21 October 2018 at 09:50:09 UTC, Walter Bright wrote:

 Manu's Proposal ---
@safe:
int i;
int* a = &i;
StartNewThread(a); // Compiles! Coder has no idea!

... in the new thread ...
void StartOfNewThread(shared(int)* b) {

... we have two threads accessing 'i',
one thinks it is shared, the other unshared,
and StartOfNewThread() has no idea and anyone
writing code for StartOfNewThread() has no way
to know anything is wrong ...

lockedIncrement(b);  // Data Race!


No, does not compile, lockedIncrement takes an int*
Error cannot convert shared(int)* to int*

Your proposal means that the person writing the 
lockedIncrement(), which is a perfectly reasonable thing to do,


Indeed.

simply cannot write it in a way that has a @safe interface, 
because the person writing the lockedIncrement() library 
function has no way to know that the data it receives is 
actually unshared data.


It does, it takes an int* which is not implicitly convertible to 
given an shared(int)*



I.e. @trusted code is obliged to proved a safe interface.


Yes.

Your proposal makes that impossible because the compiler would 
allow unshared data to be implicitly typed as shared.


Yes, but not the other way around.



Re: shared - i need it to be useful

2018-10-21 Thread Nicholas Wilson via Digitalmars-d

On Sunday, 21 October 2018 at 09:58:18 UTC, Walter Bright wrote:

On 10/20/2018 11:08 AM, Nicholas Wilson wrote:
You can if no-one else writes to it, which is the whole point 
of Manu's proposal. Perhaps it should be const shared instead 
of shared but still.


There is no purpose whatsoever to data that can be neither read 
nor written.


Indeed but there is a subtle difference between that and Manu's 
proposal: access through the shared variable may not have 
non-atomic reads, not no reads.


Shared data is only useful if, at some point, it is 
read/written,


Yes


presumably by casting it to unshared in @trusted code.


That is one way to do it, others include atomics  and other 
@trusted primitives


As soon as that is done, you've got a data race with the other 
existing unshared aliases.


You're in @trusted code, that is the whole point. The onus is on 
the programmer to make that correct, same with regular 
@safe/@trusted@system code.




Re: shared - i need it to be useful

2018-10-20 Thread Nicholas Wilson via Digitalmars-d
On Saturday, 20 October 2018 at 17:06:22 UTC, Stanislav Blinov 
wrote:
On Saturday, 20 October 2018 at 16:48:05 UTC, Nicholas Wilson 
wrote:
On Saturday, 20 October 2018 at 09:04:17 UTC, Walter Bright 
wrote:

by code that believes it is unshared


you cannot `@safe`ly modify the memory  through `b`, `a`'s 
view of the memory is unchanged in @safe code.


And that's already a bug, because the language can't enforce 
threadsafe access through `a`, regardless of presence of `b`. 
Only the programmer can.


 access through `a` is through the owned reference threadsafety 
through a does't mean anything, all _other_ access must ensure 
that the are ordered correctly.





and, code that believes it is shared.


you cannot have non-atomic access though `b`, `b` has no @safe 
view of the memory, unless it is atomic (which by definition 
is synchronised).


Synchronized with what? You still have `a`, which isn't 
`shared` and doesn't require any atomic access or 
synchronization.


Synchronized w.r.t any writes to that memory, e.g. from `a`.


At this point it doesn't matter if it's an int
or a struct.


Yes.

As soon as you share `a`, you can't just pretend that reading 
or writing `a` is safe.


You can if no-one else writes to it, which is the whole point of 
Manu's proposal. Perhaps it should be const shared instead of 
shared but still.





Re: shared - i need it to be useful

2018-10-20 Thread Nicholas Wilson via Digitalmars-d
On Saturday, 20 October 2018 at 16:41:41 UTC, Stanislav Blinov 
wrote:

On Saturday, 20 October 2018 at 16:18:53 UTC, aliak wrote:


class C {
  void f();
  void g() shared;
}

void t1(shared C c) {
  c.g; // ok
  c.f; // error
}

void t2(shared C c) {
  c.g; // ok
  c.f; // error
}

auto c = new C();
spawn(&t1, c); // line 20
spawn(&t2, c); // line 21
c.f; // ok
c.g; // ok // line 23


Those are not "ok". They're only "ok" under Manu's proposal so 
long as the author of C promises (via documentation) that 
that's indeed "ok". There can be no statically-enforced 
guarantees that those calls are "ok", or that issuing them in 
that order is "ok". Yet Manu keeps insisting that somehow there 
is.


Backing up a bit and making a few observations (after adding 
imports and wrapping the bottom code in a function):


1. the code above currently does not compile, error messages are:
i.  line 20 & 21: spawn fails to instantiate because c is not 
shared
ii. line 23: shared method C.g is not callable using a 
non-shared object

iii. the lines already marked // error

2. in order to fix 1.i, one must cast c to shared at the call 
site, this is not @safe


3 fixing 1.ii requires doing `(cast(shared)c).g`, this is also 
not @safe


4 fixing 1.iii fixing requires casting away shared, this is not 
only not @safe, but also wrong. c is a class so one could try 
locking it although I'm not sure what the implications are for 
doing that when another thread owns the data, probably bad.


5 the current means of dealing with shared with lock and cast 
away shared is also not @safe


6 under Manu's proposal reading and writing shared objects 
results in compilation error


7 The static guarantees we have in the language are type safety 
and @safe


8 under Manu's proposal to do anything one must call shared 
functions on said object, this implies a "@trusted" 
implementation at the bottom of the stack for ensuring thread 
safety (atomics and lock + cast (assuming it is not wrong), other 
sync primitives) that are not @safe, but not outright wrong 
either.


The question then becomes: assuming the implementation _is_ @safe 
type correct and thread safe etc., can the author of C provide 
guarantees of @safe and type correctness? and can this guarantee 
be free of false positives?


Currently the answer is no: the requirement to cast to and from 
shared is un-@safe and that burden is on the user which means 
that they must understand the inner workings of C to know it that 
is the case.


Manu's proposal is slightly more interesting. shared becomes a 
guarantee that accesses to that object will not race, assuming 
that the @trusted implementation at the bottom of the stack are 
correct. In the above if t1 and t2 took `const shared C` and `g` 
was also const shared, then I think that it could.







Re: shared - i need it to be useful

2018-10-20 Thread Nicholas Wilson via Digitalmars-d

On Saturday, 20 October 2018 at 09:04:17 UTC, Walter Bright wrote:

On 10/19/2018 11:18 PM, Manu wrote:

The reason I ask is because, by my definition, if you have:
int* a;
shared(int)* b = a;

While you have 2 numbers that address the same data, it is not 
actually aliased because only `a` can access it.


They are aliased,


Quoting Wikipedia:

two pointers A and B which have the same value, then the name 
A[0] aliases the name B[0]. In this case we say the pointers A 
and B alias each other. Note that the concept of pointer 
aliasing is not very well-defined – two pointers A and B may or 
may not alias each other, depending on what operations are 
performed in the function using A and B.


In this case given the above: `a[0]` does not alias `b[0]` 
because `b[0]` is ill defined under Manu's proposal, because the 
memory referenced by `a` is not reachable through `b` because you 
can't read or write through `b`.



by code that believes it is unshared


you cannot `@safe`ly modify the memory  through `b`, `a`'s view 
of the memory is unchanged in @safe code.



and, code that believes it is shared.


you cannot have non-atomic access though `b`, `b` has no @safe 
view of the memory, unless it is atomic (which by definition is 
synchronised).



This is not going to work.


Aú contraire.



Re: Shared - Another Thread

2018-10-19 Thread Nicholas Wilson via Digitalmars-d
On Saturday, 20 October 2018 at 00:00:49 UTC, Dominikus Dittes 
Scherkl wrote:

Hmm.
mutable, immutable and const form a triple, the second is a 
declaration attribute, the last an parameter attribute, 
indicating that you don't want to modify the parameter, may it 
be because you can't (as it is immutable) or you only don't 
need to despite it would be possible (if it was mutable). The 
later is your responsibility to guarantee (with the help from 
the compiler).
Therefore it is possible to implicitly cast from mutable or 
immutable to const but not in any other direction.


I think for unshared, shared and threadsave it should be the 
same:
The second is a declaration attribute, the third a parameter 
attribute. The first two can implicitly be cast to threadsave, 
may be because it is thread-local and therefore no race 
condition is possible, or may be because you take special care 
in your type to guarantee the thread safety by using atomic 
operations or locking or whatever.
That make it possible, that the implicit cast from shared to 
unshared can be avoided while still providing functions that 
can take both kinds of arguments.


Yes, that would add a little to the attribute bloat (new 
keyword) but not to the number of attributes per type or 
parameter.


Mutable = value may change
const = I will not change the value
immutable = the value will not change

unshared = I (well the current thread) owns the reference
shared = reference not owned, no unordered access, no (unordered) 
writes

threadsafe = ???


Re: Truly @nogc Exceptions?

2018-10-19 Thread Nicholas Wilson via Digitalmars-d

On Friday, 19 October 2018 at 23:34:01 UTC, Atila Neves wrote:
On Thursday, 20 September 2018 at 12:48:13 UTC, Steven 
Schveighoffer wrote:

How is the exception destroyed when dip1008 is enabled?


Apparently, it isn't. Which renders dip1008 pretty much useless 
since we could already use static immutable exceptions before.


Wow, that is useless! Is that an implementation bug or was that 
specified by the DIP?


Re: shared - i need it to be useful

2018-10-17 Thread Nicholas Wilson via Digitalmars-d
On Wednesday, 17 October 2018 at 15:51:04 UTC, Steven 
Schveighoffer wrote:

On 10/17/18 9:58 AM, Nicholas Wilson wrote:
On Wednesday, 17 October 2018 at 13:25:28 UTC, Steven 
Schveighoffer wrote:
It's identical to the top one. You now have a new unshared 
reference to shared data. This is done WITHOUT any 
agreed-upon synchronization.


It isn't, you typo'd it (I originally missed it too).

int *p3 = cast(int*)p2;


vs


int *p3 = p;


It wasn't a typo.


The first example assigns p2, the second assigns p (which is 
thread local) _not_ p2 (which is shared), I'm confused.




Re: shared - i need it to be useful

2018-10-17 Thread Nicholas Wilson via Digitalmars-d

On Wednesday, 17 October 2018 at 14:26:43 UTC, Timon Gehr wrote:

On 17.10.2018 16:14, Nicholas Wilson wrote:


I was thinking that mutable -> shared const as apposed to 
mutable -> shared would get around the issues that Timon 
posted.


Unfortunately not. For example, the thread with the mutable 
reference is not obliged to actually make the changes that are 
performed on that reference visible to other threads.


Yes, but that is covered by not being able to read non-atomically 
from a shared reference.


Re: shared - i need it to be useful

2018-10-17 Thread Nicholas Wilson via Digitalmars-d
On Wednesday, 17 October 2018 at 07:24:13 UTC, Stanislav Blinov 
wrote:
On Wednesday, 17 October 2018 at 05:40:41 UTC, Walter Bright 
wrote:



When Andrei and I came up with the rules for:

   mutable
   const
   shared
   const shared
   immutable

and which can be implicitly converted to what, so far nobody 
has found a fault in those rules...


Here's one: shared -> const shared shouldn't be allowed. 
Mutable aliasing in single-threaded code is bad enough as it is.


Could you explain that a bit more? I don't understand it, mutable 
-> const is half the reason const exists.


I was thinking that mutable -> shared const as apposed to mutable 
-> shared would get around the issues that Timon posted.


Re: shared - i need it to be useful

2018-10-17 Thread Nicholas Wilson via Digitalmars-d
On Wednesday, 17 October 2018 at 13:25:28 UTC, Steven 
Schveighoffer wrote:

On 10/16/18 8:26 PM, Manu wrote:
On Tue, Oct 16, 2018 at 2:20 PM Steven Schveighoffer via 
Digitalmars-d

 wrote:

There is in fact, no difference between:

int *p;
shared int *p2 = p;
int *p3 = cast(int*)p2;


Totally illegal!! You casted away shared. That's as bad as 
casting away const.


But if you can't do anything with shared data, how do you use 
it?





and this:

int *p;
shared int *p2 = p;
int *p3 = p;


There's nothing wrong with this... I don't understand the 
point?


It's identical to the top one. You now have a new unshared 
reference to shared data. This is done WITHOUT any agreed-upon 
synchronization.


It isn't, you typo'd it (I originally missed it too).

int *p3 = cast(int*)p2;


vs


int *p3 = p;


Re: shared - i need it to be useful

2018-10-16 Thread Nicholas Wilson via Digitalmars-d

On Wednesday, 17 October 2018 at 00:29:04 UTC, Manu wrote:
On Tue, Oct 16, 2018 at 3:25 PM Nicholas Wilson via 
Digitalmars-d  wrote:


On Tuesday, 16 October 2018 at 21:19:26 UTC, Steven 
Schveighoffer wrote:

> There is in fact, no difference between:
>
> int *p;
> shared int *p2 = p;
> int *p3 = cast(int*)p2;
>
> and this:
>
> int *p;
> shared int *p2 = p;
> int *p3 = p;

If I understand Manu correctly the first should compile, and 
the second should error, just like if you replaces shared with 
const in the above.


Why is the second an error?

Right, for the sake of the thought experiment, replace shared 
with const.
The first is an abomination (casting away const)... the second 
is just a no-op.


I missed that the third example was *p3 = p; not *p3 = p2;


Re: shared - i need it to be useful

2018-10-16 Thread Nicholas Wilson via Digitalmars-d
On Tuesday, 16 October 2018 at 21:19:26 UTC, Steven Schveighoffer 
wrote:

There is in fact, no difference between:

int *p;
shared int *p2 = p;
int *p3 = cast(int*)p2;

and this:

int *p;
shared int *p2 = p;
int *p3 = p;


If I understand Manu correctly the first should compile, and the 
second should error, just like if you replaces shared with const 
in the above.




Re: shared - i need it to be useful

2018-10-16 Thread Nicholas Wilson via Digitalmars-d
On Tuesday, 16 October 2018 at 21:19:26 UTC, Steven Schveighoffer 
wrote:
OK, so here is where I think I misunderstood your point. When 
you said a lock-free queue would be unusable if it wasn't 
shared, I thought you meant it would be unusable if we didn't 
allow the implicit cast. But I realize now, you meant you 
should be able to use a lock-free queue without it being 
actually shared anywhere.


What I say to this is that it doesn't need to be usable. I 
don't care to use a lock-free queue in a thread-local capacity. 
I'll just use a normal queue, which is easy to implement, and 
doesn't have to worry about race conditions or using atomics. A 
lock free queue is a special thing, very difficult to get 
right, and only really necessary if you are going to share it. 
And used for performance reasons!


I think this comes up where the queue was originally shared, you 
acquired a lock on the thing it is a member of, and you want to 
continue using it through your exclusive reference.




Re: shared - i need it to be useful

2018-10-15 Thread Nicholas Wilson via Digitalmars-d
On Monday, 15 October 2018 at 23:30:43 UTC, Stanislav Blinov 
wrote:

On Monday, 15 October 2018 at 21:51:43 UTC, Manu wrote:

If a shared method is incompatible with an unshared method, 
your class is broken.


What?!? So... my unshared methods should also perform all 
that's necessary for `shared` methods?


No, its the other way around: a shared method that does extra 
synchronisation should work irrespective of wether or not the 
object needs that synchronisation. e.g. atomic loading a TLS 
variable is fine.



Explicit casting doesn't magically implement thread-safety, it
basically just guarantees failure.


It doesn't indeed. It does, however, at least help prevent 
silent bugs. Via that same guaranteed failure. That failure is 
about all the help we can get from the compiler anyway.


What I suggest are rules that lead to proper behaviour with 
respect to writing a thread-safe API.

You can write bad code with any feature in any number of ways.


Yup. For example, passing an int* to a function expecting 
shared int*.


That is a reasonable thing to do if shared is const + no 
unsynched reads.



I see it this way:
If your object has shared methods, then it is distinctly and
*deliberately* involved in thread-safety. You have deliberately
opted-in to writing a thread-safe object, and you must deliver 
on your promise.


The un-shared API of an object that supports `shared` are not 
exempt from the thread-safety commitment, they are simply the 
subset of the API that may not be called from a shared context.


And therefore they lack any synchronization. So I don't see how 
they *can* be "compatible" with `shared` methods.




I think Manu means you have a shared object with some shared 
methods and some unshared methods. The shared methods deal with 
synchronisation and can therefore be call from anywhere by 
anyone, whereas the unshared methods must be called on a locked 
object.



snip
Nobody writes methods of an object such that they don't work 
with each other... methods are part of a deliberately crafted 
and packaged
entity. If you write a shared object, you do so deliberately, 
and you buy responsibility of making sure your objects API is 
thread-safe.

If your object is not thread-safe, don't write shared methods.


Ahem... Okay...

import std.concurrency;
import core.atomic;

void thread(shared int* x) {
(*x).atomicOp!"+="(1);
}

shared int c;

void main() {
int x;
auto tid = spawn(&thread, &x); // "just" a typo
}

You're saying that's ok, it should "just" compile. It 
shouldn't. It should produce an error and a mild electric 
discharge into the developer's chair.


Indeed that is just a typo, just as that is a contrived example. 
You'd notice that pretty quick in a debugger.




Re: shared - i need it to be useful

2018-10-15 Thread Nicholas Wilson via Digitalmars-d

On Monday, 15 October 2018 at 21:08:38 UTC, Manu wrote:
On Mon, Oct 15, 2018 at 2:05 PM Nicholas Wilson via 
Digitalmars-d  wrote:
I'm saying that while what you propose sounds very reasonable, 
we should make sure that reading immutable variables is still 
good ;)


I don't think what I describe affects immutable in any way;
`is(immutable(int) == shared) == false`, as it should be. 
Immutable

wouldn't have its rules affected by any change to shared.


OK, just making sure you've got this covered.



Re: shared - i need it to be useful

2018-10-15 Thread Nicholas Wilson via Digitalmars-d

On Monday, 15 October 2018 at 20:54:12 UTC, jmh530 wrote:

On Monday, 15 October 2018 at 20:44:35 UTC, Manu wrote:

snip

Are you saying `is(immutable(int) == shared) == true)` ??


From the spec:
"Applying any qualifier to immutable T results in immutable T. 
This makes immutable a fixed point of qualifier combinations 
and makes types such as const(immutable(shared T)) impossible 
to create."


Example:

import std.stdio : writeln;

void main()
{
writeln(is(immutable(int) == shared immutable(int)) == 
true); //prints true

}


The philosophy of this is that: the value never changes, 
therefore only one copy of the variable needs to exist (i.e. 
immutable variables declared at module scope are _not_ thread 
local) and can be shared between threads with no race conditions.


I'm saying that while what you propose sounds very reasonable, we 
should make sure that reading immutable variables is still good ;)


Re: shared - i need it to be useful

2018-10-15 Thread Nicholas Wilson via Digitalmars-d

On Monday, 15 October 2018 at 18:46:45 UTC, Manu wrote:

Destroy...


Keep in mind immutable is implicitly shared (i.e. not in tls) 
because nobody can change it. It should stay readable for this 
reason.


Re: shared - i need it to be useful

2018-10-15 Thread Nicholas Wilson via Digitalmars-d

On Monday, 15 October 2018 at 19:14:58 UTC, Peter Alexander wrote:

On Monday, 15 October 2018 at 18:46:45 UTC, Manu wrote:
2. object may have shared methods; such methods CAN be called 
on

shared instances. such methods may internally implement
synchronisation to perform their function. perhaps methods of a
lock-free queue structure for instance, or operator overloads 
on

`Atomic!int`, etc.


Just checking my understanding: are you saying here that shared 
methods can effectively do anything and the burden of 
correctness is on the author? Or do you still have to cast the 
shared away first?


Well `this` is still shared so you would be prevented from doing 
anything non-atomically or lock cast away shared, but that will 
be enforced by the type system. So the burden of  correctness is 
on the author, but the complier enforces correct behaviour.


Re: You don't like GC? Do you?

2018-10-12 Thread Nicholas Wilson via Digitalmars-d
On Friday, 12 October 2018 at 20:12:26 UTC, Stanislav Blinov 
wrote:
On Friday, 12 October 2018 at 19:55:02 UTC, Nicholas Wilson 
wrote:


Freeing your mind and the codebase of having to deal with 
memory leaves it in an easier place to deal with the less 
common higher impact leaks: file descriptors, sockets, 
database handles ect. (this is like chopping down the forest 
so you can see the trees you care about ;) ).


That's done first and foremost by stripping out unnecessary 
allocations, not by writing "new" every other line and closing 
your eyes.


If you need perf in your _scripts_, a use LDC and b) pass -O3 
which among many other improvements over baseline will promote 
unnecessary garbage collection to the stack.


I mean come on, it's 2018. We're writing code for multi-core 
and multi-processor systems with complex memory interaction.


We might be sometimes. I suspect that is less likely for a script 
to fall in that category.


Precisely where in memory your data is, how it got there and 
how it's laid out should be bread and butter of any D 
programmer. It's true that it isn't critical for one-off 
scripts, but so is deallocation.


Saying stuff like "do more with GC" is just outright harmful.


That is certainly not an unqualified truth. Yes one shouldn't 
`new` stuff just for fun, but speed of executable is often not 
what one is trying to optimise when writing code, e.g. when 
writing a script one is probably trying to minimise 
development/debugging time.



Kids are reading, for crying out loud.


Oi, you think thats bad? Try reading what some of the other 
Aussies post, *cough* e.g. a frustrated Manu *cough*




Re: You don't like GC? Do you?

2018-10-12 Thread Nicholas Wilson via Digitalmars-d
On Friday, 12 October 2018 at 19:43:02 UTC, Stanislav Blinov 
wrote:
On Friday, 12 October 2018 at 18:50:26 UTC, Neia Neutuladh 
wrote:


Over the lifetime of the script, it processed more memory than 
my computer had. That means I needed a memory management 
strategy other than "allocate everything". The GC made that 
quite easy.


Now *that* is a good point. Then again, until you run out of 
address space you're still fine with just plain old 
allocate-and-forget. Not that it's a good thing for production 
code, but for one-off scripts? Sure.


People demonstrably have trouble doing that. We can do it 
most of the time, but everyone occasionally forgets.


The GC isn't a cure for forgetfulness. One can also forget to 
close a file or a socket, or I dunno, cancel a financial 
transaction.


By lines of code, programs allocate memory much more often 
than they deal with files or sockets or financial 
transactions. So anything that requires less discipline when 
dealing with memory will reduce bugs a lot, compared with a 
similar system dealing with sockets or files.


My point is it's irrelevant whether it's memory allocation or 
something else. If you allow yourself to slack on important 
problems, that habit *will* bite you in the butt in the future.


Freeing your mind and the codebase of having to deal with memory 
leaves it in an easier place to deal with the less common higher 
impact leaks: file descriptors, sockets, database handles ect. 
(this is like chopping down the forest so you can see the trees 
you care about ;) ).


Re: std.data.json formal review

2018-10-09 Thread Nicholas Wilson via Digitalmars-d

On Tuesday, 9 October 2018 at 18:07:44 UTC, Márcio Martins wrote:

On Tuesday, 28 July 2015 at 14:07:19 UTC, Atila Neves wrote:

Start of the two week process, folks.

Code: https://github.com/s-ludwig/std_data_json
Docs: http://s-ludwig.github.io/std_data_json/

Atila


Sorry for the late ping, but it's been 3 years - what has 
happened to this? Has it been forgotten?


Working with JSON in D is still quite painful.


I presume it became vibe.data.json, there is also asdf if you're 
looking for some other library.


Re: Thread-safe attribution

2018-10-06 Thread Nicholas Wilson via Digitalmars-d

On Sunday, 7 October 2018 at 01:59:21 UTC, Manu wrote:

So I'm working on a SMT infrastructure, and expression of
thread-safety is a core design mechanic... but I'm really 
struggling

to express it in terms of the type system.
I figure I'll throw some design challenges out here and see if 
anyone

can offer some good ideas.

The thing I'm trying to model is an attribute along the lines of
`shared`, but actually useful ;)
I'll use the attribute `threadsafe` in place of `shared`, and 
see

where that goes.

Consider:
struct Bob
{
  int x;
  threadsafe Atomic!int y;

  void m1();
  void m2() threadsafe;;

  void overloaded();
  void overloaded() threadsafe;
}

void func( ref Bob x, ref threadsafe Bob y)
{
  x.x = 10; // fine
  x.y = 10; // fine
  x.m1(); // fine
  x.m2(); // fine
  x.overloaded(); // fine, use the un-threadsafe overload

  y.x = 10; // ERROR, a threadsafe reference can NOT modify an
un-threadsafe member
  y.y = 10; // fine
  x.m1(); // ERROR, method not threadsafe
  x.m2(); // fine
  x.overloaded(); // fine, use the threadsafe overload

  threadsafe Bob* p = &x; // can take threadsafe reference to
thread-local object
}

This is loosely what `shared` models, but there's a few 
differences:

1. thread-local can NOT promote to shared
2. shared `this` applies to members

For `shared` to be useful, it should be that a shared reference 
to something inhibits access to it's thread-local stuff. And in 
that world, then I believe that thread-local promotion to 
shared would work like const does.


I guess I'm wondering; should `shared` be transitive? Perhaps 
that's what's wrong with it...?


A delta comparison with shared

void func( ref Bob x, ref threadshared /* either shared or 
threadsafe*/ Bob y)

{
 // threadsafe / shared
  x.x = 10; // fine / fine
  x.y = 10; // fine / fine uses atomics
  x.m1(); // fine / fine
  x.m2(); // fine / error cannot call shared method on unshared 
object

  x.overloaded(); // fine, use the un-threadsafe overload / fine

  y.x = 10; // ERROR, a threadsafe reference can NOT modify an 
un-threadsafe member / error

  y.y = 10; // fine / fine (using atomics)
// Assuming these are supposed to be y not x
  y.m1(); // ERROR, method not threadsafe / error
  y.m2(); // fine / fine
  y.overloaded(); // fine, use the threadsafe overload / fine

  threadsafe Bob* p = &x; // can take threadsafe reference to 
thread-local object / error

}

Differences:
Can call threadsafe method on thread local / unshared
Can take threadsafe reference to thread-local object.

One thing that occurred to me is that _objects_ are shared, 
whereas _functions/methods_ (and their parameters) are thread 
safe .


Theadsafe is kind of like a const (as to mutable/immutable) to 
threading, a promise to behave correctly in the presence of 
threading. thread safe references therefore must not escape.




Re: Farewell (of sorts)

2018-10-04 Thread Nicholas Wilson via Digitalmars-d
On Thursday, 4 October 2018 at 13:15:23 UTC, Shachar Shemesh 
wrote:

Hello everyone,

First of all, I know I've had a shorter than usual fuse of 
late. I'd like to apologize to everyone about this. It is the 
culmination of quite a few things increasing the load I'm under.


One of those things is this: October 14th will be my last day 
working for Weka.IO. Accordingly, my involvement in D will be 
considerably reduced after that date, as working with D will no 
longer be my day job.


A few of you knew that I was looking for a new job, but I 
postponed officially announcing this, as I wanted to see who 
will be taking over maintenance of Mecca. On that front, I have 
some good news and some bad news.


The bad news is that the person taking over will not have Mecca 
as his sole responsibility. I am hoping he'll be able to do 
enough.


The good news is that they put on this task my top pick for it. 
His name is Eyal Lotem, and is a great developer. Some of you 
have met him as he attended DConf three years ago.


I will probably keep half an eye on the forum, and I might also 
be around on the Slack channels. My email address will change 
as a result. Feel free to find me at firstn...@lastname.biz, 
after applying the relevant substitutions. I think it's a 
better captcha than running D code :-)


Shachar


Please do keep around if you can. I hope to have some good news 
regarding D processes (the wetware kind) soon.


I do hope you get to keep your job title wherever you go next, 
its the best I've ever seen :)


So long and thanks for all the laughs, Chief Court Jester

Nic


Re: DConf and outreach, e.g. ACCU [was Please don't do a DConf 2018, consider alternatives]

2018-10-03 Thread Nicholas Wilson via Digitalmars-d

On Wednesday, 3 October 2018 at 07:33:44 UTC, Russel Winder wrote:

I have been muttering about this a while. :-)


I know, but this conference was sorta last minute realisation 
that it would be very beneficial to attend and I've been rather 
busy with it.


Being at another conference clearly makes things a bit more 
difficult, but having registered, logged in to the Web 
application, a submission just requires a title, blurb and 
presenter bio. This might hopefully be feasible for you, albeit 
less than ideal.


Good, although I can't guarantee that the blurb will match the 
final presentation because I'm sure a lot will happen in the mean 
time, but oh well.


Re: DConf and outreach, e.g. ACCU [was Please don't do a DConf 2018, consider alternatives]

2018-10-03 Thread Nicholas Wilson via Digitalmars-d

On Wednesday, 3 October 2018 at 06:40:28 UTC, Russel Winder wrote:
How about DConf continues, as it should, and people submit 
sessions to
ACCU as part of the outreach programme. The call for sessions 
opens at

the end of this week and lasts three weeks.


Ow, that does not give me a lot of time, as I'm going to the US 
for a conference in the mean time.


Re: Please don't do a DConf 2018, consider alternatives

2018-10-02 Thread Nicholas Wilson via Digitalmars-d

On Tuesday, 2 October 2018 at 06:26:30 UTC, Joakim wrote:

[snip]


Also you're out by a year :)



Re: Please don't do a DConf 2018, consider alternatives

2018-10-02 Thread Nicholas Wilson via Digitalmars-d

On Tuesday, 2 October 2018 at 06:26:30 UTC, Joakim wrote:
I'm sure some thought and planning is now going into the next 
DConf, so I'd like to make sure people are aware that the 
conference format that DConf uses is dying off, as explained 
here:


https://marco.org/2018/01/17/end-of-conference-era

There was a discussion about this in a previous forum thread:

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

Jonathan and Mike argue in that thread that DConf is great for 
the core team to get together in person and hash things out for 
D with very high-bandwidth interaction, but I pointed out that 
doesn't justify 95%+ of the attendees being there. If there's a 
real need for this, maybe get those 8-15 people together in an 
online video conference or offline retreat, without a bunch of 
hangers-on and talks.


People are now experimenting with what replaces conferences, we 
should be doing that too. I came up with some ideas in that 
thread:


"Have most talks prerecorded by the speaker on their webcam or 
smartphone, which produce excellent video these days with not 
much fiddling, and have a couple organizers work with them to 
get those home-brewed videos up to a certain quality level, 
both in content and presentation, before posting them online."


I volunteer to help presenters do this.

"Once the videos are all up, set up weekend meetups in several 
cities [all over the world], where a few livestreamed talks may 
talk place if some speakers don't want to spend more time 
producing a pre-recorded talk, but most time is spent like the 
hackathon, discussing various existing issues from bugzilla in 
smaller groups or brainstorming ideas, designs, and libraries 
for the future."


I can setup an event like this in my city, where AFAIK nobody 
uses D, so most of it would be geared towards introducing them 
to the language.


I estimate that you could do ten times better at raising 
awareness and uptake with this approach than the current DConf 
format, by casting a much wider net, and it would cost about 
10X less, ie you get two orders of magnitude better bang for 
the buck.


At the very least, DConf should just be a big hackathon of 
self-organizing groups, rather than wasting any time passively 
imbibing talks next to a hundred other people. I still don't 
think the cost of getting a hundred people in the same room for 
3-4 days would be justified, but at least it would be a step in 
the right direction.


As I'm sure has been said before, if it were just the talks it 
probably wouldn't be worth it. But conferences are sooo 
much more than just the talks. Its the conversations over 
breakfast/lunch/dinner/ between talks and long into the night 
(sometimes too long). Its the networking, the hacking, the face 
to face. The talks are usually pretty good too.


The conference is definitely not dead, I'm going to one in San 
José in 2 weeks, sure the talks look really interesting but the 
main reason is to talk to other people to get stuff done.


Re: `shared`...

2018-10-01 Thread Nicholas Wilson via Digitalmars-d

On Monday, 1 October 2018 at 09:55:41 UTC, ag0aep6g wrote:

On 10/01/2018 08:47 AM, Nicholas Wilson wrote:
In order to be safe, a mutable parameter can be implicitly 
cast to shared iff the parameter is also scope (that includes 
the `this` reference`). With an implicit cast in place of the 
explicit cast under the new rules it would fail to compile 
because the `this` reference is not scope.


I don't see why it would fail to compile. There's no reason why 
my `doThing` couldn't be marked as `scope`. It doesn't leak 
anything.


Hmm, you are right. Its annoying because the use case for this is 
where the data is already shared and a lock has been taken.


`pure` would break the example. I'm not sure if it would ensure 
safety, though. Can a `pure` method spawn a new thread (that 
outlives the method call)?


Error: pure function onlineapp.f cannot call impure function 
core.thread.Thread.start


Re: `shared`...

2018-10-01 Thread Nicholas Wilson via Digitalmars-d

On Monday, 1 October 2018 at 08:04:38 UTC, Kagamin wrote:

Shared data may need different algorithms.


Yes, but those same algorithms will work on unshared (they might 
be slower but they will work). The reverse is not true, it can 
lead to race conditions.



If unshared data is
implicitly convertible to shared, you start to conflate shared 
data with unshared, so you're back to C-style sharing.


No, when participating in overloading, an unshared method will be 
preferred over a shared method for an unshared object. Same with 
parameters that are not `this`.



This is how you can do it:

shared struct SharedBob
{
this(int){}
void setThing(){}
}
alias shared SharedBob Bob;

void f(ref shared Bob a, ref Bob b)
{
  a.setThing(); // I have a shared object, can call shared 
method


  b.setThing(); // ok
}

int main()
{
auto b=Bob(0);
Bob c;
f(b,c);
return 0;
}


I'm not sure what that was supposed to demonstrate.


Re: `shared`...

2018-09-30 Thread Nicholas Wilson via Digitalmars-d

On Monday, 1 October 2018 at 06:06:31 UTC, ag0aep6g wrote:
`shared` isn't analogous to `const`. It's analogous to 
`immutable`. Functions dealing with `shared` data can assume 
that other threads also see the data as `shared`. If you allow 
calling `shared` methods on non-`shared` objects, you're 
breaking that.


Example:


struct Bob
{
  int* p;
  void doThing() shared
  {
p = &s;
  }
}

shared int s;

void main()
{
  Bob bob;
  (cast(shared Bob)bob).doThing();/* You'd make the cast 
implicit. */


  import core.thread;
  import core.atomic;
  enum n = 1_000_000;
  auto t = new Thread(() { foreach (i; 0 .. n) atomicOp!"+="(s, 
1); });

  t.start();
  foreach (i; 0 .. n) ++*bob.p;
  thread_joinAll();

  import std.stdio;
  writeln(s); /* usually not "200", because of race */
}



We've realised that.

In order to be safe, a mutable parameter can be implicitly cast 
to shared iff the parameter is also scope (that includes the 
`this` reference`). With an implicit cast in place of the 
explicit cast under the new rules it would fail to compile 
because the `this` reference is not scope.


Re: `shared`...

2018-09-30 Thread Nicholas Wilson via Digitalmars-d

On Monday, 1 October 2018 at 04:22:24 UTC, Manu wrote:

Ah, good point. So, it could only be allowed if scope...

struct Bob
{
  void setThing() shared scope;
}

That's going to require far-reaching proliferation of `scope`.
Do we infer `scope` like the other attributes?


For templates (either the function or the struct it is in) and 
auto returning functions, I think so: definitely under -dip1000, 
probably also when not using -dip1000.



The default for  `scope` is totally backwards. :/


Alas, such is the nature of retrofitting.


Re: `shared`...

2018-09-30 Thread Nicholas Wilson via Digitalmars-d

On Monday, 1 October 2018 at 03:33:16 UTC, Manu wrote:
On Sun, Sep 30, 2018 at 8:20 PM Nicholas Wilson via 
Digitalmars-d  wrote:


On Monday, 1 October 2018 at 02:29:40 UTC, Manu wrote:
> struct Bob
> {
>   void setThing() shared;
> }
>
> As I understand, `shared` attribution intends to guarantee 
> that

> I dun
> synchronisation internally.
> This method is declared shared, so if I have shared 
> instances,

> I can
> call it... because it must handle thread-safety internally.

seems reasonable

https://github.com/dlang/dmd/pull/8782


Haha, sneaky bugger :P
I reckon the patch is gonna be a lot bigger than that though!


Of course, there will be updating the test suite. And Walter will 
probably tell you to bugzilla this.


implicit conversion of mutable (i.e. no mods) to const share 
should be absolutely no problem, as that it rusts borrowing model 
(one owning mutable thread local reference and zero or more non 
thread local non-owning const references) and is fine.


 mutable to mutable shared I'm not so sure as references to 
otherwise owned references could escape.


shared Bob* sneaky;

struct Bob
{
  void setSneaky() shared // legit as this is shared
   {
  sneaky = &this;
   }
}
void oblivious(ref shared Bob a, ref Bob b)
{
  a.setSneaky(); // Fine

  b. setSneaky(); // would become not an error, but totally not 
fine.

}

unfortunately scope is not a modifier so the PR will have to be 
larger, oh well.





Re: `shared`...

2018-09-30 Thread Nicholas Wilson via Digitalmars-d

On Monday, 1 October 2018 at 02:29:40 UTC, Manu wrote:

struct Bob
{
  void setThing() shared;
}

As I understand, `shared` attribution intends to guarantee that 
I dun

synchronisation internally.
This method is declared shared, so if I have shared instances, 
I can

call it... because it must handle thread-safety internally.


seems reasonable

https://github.com/dlang/dmd/pull/8782


Re: BetterC and CTFE mismatch

2018-09-26 Thread Nicholas Wilson via Digitalmars-d
On Wednesday, 26 September 2018 at 12:51:57 UTC, Steven 
Schveighoffer wrote:
So anything I do at CTFE has to be betterC as well? That is a 
bummer.


This is an artificial, and not really intended, limitation. 
Essentially, CTFE has to be a real function. If it's defined, 
it's expected to be callable from runtime as well as CTFE.


But I can't see why, if you don't call from runtime, it should 
matter. I think this has to do with the places betterC is 
enforced in the compiler.




I'll try to workaround this, but I would like to see this 
fixed. Is there anything I can do to move this forward?


I'd suggest a bug report if one hasn't been made.

-Steve


https://issues.dlang.org/show_bug.cgi?id=18472 is an open 
regression on 2.078. Doesn't cover all use cases of what 
Sebastiaan might want though.


Re: Jai compiles 80,000 lines of code in under a second

2018-09-21 Thread Nicholas Wilson via Digitalmars-d
On Friday, 21 September 2018 at 09:21:34 UTC, Petar Kirov 
[ZombineDev] wrote:
I have been watching Jonathan Blow's Jai for a while myself. 
There are many interesting ideas there, and many of them are 
what made me like D so much in the first place. It's very 
important to note that the speed claims he has been making are 
all a matter of developer discipline. You can have an infinite 
loop executed at compile-time in both D and Jai.


You're going to OOM pretty fast in D if you try :)


Re: DIP 1015--removal of integer & character literal conversion to bool--Final Review

2018-09-16 Thread Nicholas Wilson via Digitalmars-d

On Sunday, 16 September 2018 at 23:59:18 UTC, aliak wrote:

What about:

enum E: bool {
no, yes
}

void main() {
E e = cast(E)(0);
}

Would be illegal I assume?


You have an explicit cast, so no, it would be fine.





Re: int/longRe: DIP 1015--removal of integer & character literal conversion to bool--Final Review

2018-09-15 Thread Nicholas Wilson via Digitalmars-d

On Sunday, 16 September 2018 at 01:47:33 UTC, Mike Franklin wrote:

On Friday, 14 September 2018 at 23:08:34 UTC, Nicholas Wilson
The only thing I think is missing is a flag to accelerate the 
process s.t. the examples


f(E.a);
f(E.b);
g(a - b);

can be made to call their int/long overloads straight away. 
But otherwise, er, no. A resounding yes with a small request 
to make the transition faster!


I'm not too keen on adding a compiler flag, because then I have 
to worry about deprecating the compiler flag.  I don't know if 
the bugs that this DIP fixes are serious enough to justify it.  
I'd be happy to add it if others are willing to voice their 
support for it, demonstrating sufficient demand.  Or, I suppose 
I could add it as an option for Walter and Andrei to approve or 
reject on judgement day.


Mike


Its more about dealing with the deprecation warning.

With the current specification I can tell the compiler I want the 
old behaviour with a cast. I should be able to tell the compiler 
that "Yes, I wan't this new behaviour. Please don't warn me about 
it.", once I have verified that my code is correct under the new 
behaviour.


Without it, I get a (possibly quite a lot of) deprecation 
warnings and I have to insert a cast to the corresponding type, 
e.g. f(cast(int)E.a)/g(cast(long)(a - b)), to verify the 
behaviour under the new system and silence the deprecation 
warning (absolutely necessary if using `-de`). Then I have to 
delete them after stage 2, but what if I want to support older 
compilers? Well then I have to wait until they are sufficiently 
old enough.




int/longRe: DIP 1015--removal of integer & character literal conversion to bool--Final Review

2018-09-14 Thread Nicholas Wilson via Digitalmars-d

On Friday, 14 September 2018 at 13:41:40 UTC, Mike Parker wrote:
DIP 1015, "Deprecation and removal of implicit conversion from 
integer and character literals to bool", is now ready for Final 
Review. This is a last chance for community feedback before the 
DIP is handed off to Walter and Andrei for the Formal 
Assessment. Please read the procedures document for details on 
what is expected in this review stage:


https://github.com/dlang/DIPs/blob/master/PROCEDURE.md#final-review

The current revision of the DIP for this review is located here:

https://github.com/dlang/DIPs/blob/299f81c2352fae4c7fa097de71308d773dcd9d01/DIPs/DIP1015.md

In it you'll find a link to and summary of the previous review 
round. This round of review will continue until 11:59 pm ET on 
September 28 unless I call it off before then.


Thanks in advance for your participation.


Small typo under Breaking Changes and Deprecations

"4. After the time period specified in step 4 has elapsed, stage 
2 can be merged."


should be

"4. After the time period specified in step _3_ has elapsed, 
stage 2 can be merged."


The only thing I think is missing is a flag to accelerate the 
process s.t. the examples


f(E.a);
f(E.b);
g(a - b);

can be made to call their int/long overloads straight away. But 
otherwise, er, no. A resounding yes with a small request to make 
the transition faster!


Thanks Mike & Mike! Looking forward to it.

Nic



Re: More fun with autodecoding

2018-09-12 Thread Nicholas Wilson via Digitalmars-d

On Tuesday, 11 September 2018 at 14:58:21 UTC, jmh530 wrote:

Is there any reason why this is not sufficient?

[1] https://run.dlang.io/is/lu6nQ0


Overloads:

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

The static asserts being in the constraint affects the template 
candidacy viability. Being in the function body/runtime contract 
does not so you'll end up with


onlineapp.d(17): Error: onlineapp.foo called with argument types 
(float) matches both:

onlineapp.d(1): onlineapp.foo!float.foo(float x)
and:
onlineapp.d(7): onlineapp.foo!float.foo(float x)

despite the fact only one of them is viable, whereas bar is fine.


Re: Mobile is the new PC and AArch64 is the new x64

2018-09-12 Thread Nicholas Wilson via Digitalmars-d

On Tuesday, 11 September 2018 at 07:52:45 UTC, Joakim wrote:

On Tuesday, 11 September 2018 at 07:42:38 UTC, passenger wrote:

On Monday, 10 September 2018 at 13:43:46 UTC, Joakim wrote:

[...]


Is it possible to develop versus a NVidia Jetson, CUDA 
included?


I think so, but I doubt anyone has ever actually tried it:

https://www.nvidia.com/en-us/autonomous-machines/embedded-systems-dev-kits-modules/

As for CUDA, Nicholas Wilson said recently that he could do 
something with it for his DCompute project with ldc, but no 
idea what the current status is:


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


I'm about to release v0.2, ETA 1 week, with math functions and a 
API that asserts that you use it correctly (i.e. less reliant on 
driver error codes which is therefore easier to develop for).


Re: extern(C++, ns) is wrong

2018-09-11 Thread Nicholas Wilson via Digitalmars-d

On Wednesday, 12 September 2018 at 03:59:30 UTC, Danni Coy wrote:
So my understanding is that the main issue with 
extern(C++,"ns") is
functions that have different C++ name-spaces overriding each 
other in

unexpected ways.
How feasible is to simply disallow 
functions/variables/objects/... with the

same name but a different "ns" being in the same module?


Very. The compiler would do it automatically because they would 
cause name collisions.


Re: More fun with autodecoding

2018-09-11 Thread Nicholas Wilson via Digitalmars-d
On Tuesday, 11 September 2018 at 13:08:46 UTC, Steven 
Schveighoffer wrote:

On 9/10/18 7:00 PM, Nicholas Wilson wrote:
On Monday, 10 September 2018 at 20:44:46 UTC, Andrei 
Alexandrescu wrote:

On 9/10/18 12:46 PM, Steven Schveighoffer wrote:

On 9/10/18 8:58 AM, Steven Schveighoffer wrote:
I'll have to figure out why my specialized range doesn't 
allow splitting based on " ".


And the answer is: I'm an idiot. Forgot to define empty :) 
Also my slicing operator accepted ints and not size_t.


I guess a better error message would be in order.


https://github.com/dlang/DIPs/pull/131 will help narrow down 
the cause.


While this would help eventually, I'd prefer something that 
just transforms all the existing code into useful error 
messages. See my response to Andrei.


-Steve


Please tell me where to get one of those!

But yeah, that DIP will tell you that has slicing is you problem 
straight away. Extracting useful information to present to the 
user on why hasSlicing!R is false is much trickier for the same 
reason that providing useful information in the current template 
constraint format is hard: it is a bunch of potentially 
unstructured logic that has already been const-folded in order to 
evaluate it in the first place, so you can't re-evaluate it 
without flushing the template cache.


That's not to say that the situation can't be improved beyond 
what the DIP specifies, but I haven't had any brilliant ideas 
(and the Idea for that DIP was stolen from someone else anyway).


Re: More fun with autodecoding

2018-09-10 Thread Nicholas Wilson via Digitalmars-d
On Monday, 10 September 2018 at 20:44:46 UTC, Andrei Alexandrescu 
wrote:

On 9/10/18 12:46 PM, Steven Schveighoffer wrote:

On 9/10/18 8:58 AM, Steven Schveighoffer wrote:
I'll have to figure out why my specialized range doesn't 
allow splitting based on " ".


And the answer is: I'm an idiot. Forgot to define empty :) 
Also my slicing operator accepted ints and not size_t.


I guess a better error message would be in order.


https://github.com/dlang/DIPs/pull/131 will help narrow down the 
cause.


Re: Debugging mixins - we need to do something

2018-09-09 Thread Nicholas Wilson via Digitalmars-d

On Saturday, 8 September 2018 at 22:01:23 UTC, Manu wrote:

[snip]
Is anyone interested in this issue?


https://github.com/dlang/dmd/pull/8677


Re: Debugging mixins - we need to do something

2018-09-08 Thread Nicholas Wilson via Digitalmars-d

On Saturday, 8 September 2018 at 22:01:23 UTC, Manu wrote:
TL;DR, debugging is critical and neglected. Mixin is worst 
offender.


So, string mixin breaks the debugger. All of a sudden there is 
code that's executing that doesn't exist anywhere. We need a 
solution to this problem...


As I and others have suggested before; mixin expansion should 
emit a `[sourcefile].d.mixin` file to the object directory, 
this file should accumulate mixin instantiations, and perhaps 
it would be ideal to also emit surrounding code for context.


The debuginfo should point into that file when compiling mixin 
code, so that it's possible to step and inspect within the 
mixin.




How is this done in C/C++ w.r.t macros? Point to within the macro?

I initially imagined an 'expanded' copy of the file would be 
cool, but that doesn't work when mixins are driven by template 
args, since the expansion may be different for every 
instantiation of the surrounding code.


There has been lots of chatter in the past, can we prioritise 
it? It would help me a lot.


I think this is a high-importance ticket. I have absolutely no 
idea
where to start with this, and I don't have anywhere near enough 
time

to put towards my current initiatives (extern(C++) stuff).

Is anyone interested in this issue?


Obligatory "Bugzilla issue?". I don't think is should be too 
difficult to come up with a really dumb solution, just dump 
CompileStatement's string to a file, set the Lexer's loc to that 
file and let regular debug info generation do its thing. I'm busy 
for the next few days, but I'll take a crack at it if no-one 
beats me to it.


Re: This is why I don't use D.

2018-09-08 Thread Nicholas Wilson via Digitalmars-d
On Friday, 7 September 2018 at 19:15:21 UTC, Jonathan M Davis 
wrote:
Honestly, I wouldn't rely on anything beyond dub build working 
in a consistent manner across projects. As far as I can tell, 
you can't actually do anything properly custom with dub test, 
and I'm inclined to think that how it approaches things is 
outright wrong.


For Dcompute I define a unittest configuration that has a main 
that runs tests, and the (default) library configuration excludes 
source files in the test directory. It seems to work fine. 
Admittedly it is a little different to you usual package, and 
there are no test specific symbols and no unit tests, and I 
haven't tested anything that has dcompute as a dependancy.


Are you suggesting this will break users of Dcompute that run dub 
test in their code? If so that truly does suck, because regular 
unittests will not cut the mustard.


Re: This is why I don't use D.

2018-09-08 Thread Nicholas Wilson via Digitalmars-d

On Thursday, 6 September 2018 at 16:50:32 UTC, H. S. Teoh wrote:
Again, this strongly suggests the idea I've mentioned a few 
times now: *all* packages on code.dlang.org needs to be run 
through a CI tester, and success/failure to compile should be 
reported back to dlang.org somehow.  Then in the search results 
and in the package's home page, there should be a 
prominently-displayed notice of which compiler versions work / 
don't work with the package.


This gives users the information they need to make the right 
decision (e.g., the last known compiler that compiles this 
package is 2.060, so don't bother, move on.).


And this *must* be automated, because nobody has the time or 
energy to manually test every package against every known 
compiler release and manually update code.dlang.org.  And doing 
it manually tends to quickly get out of date, not to mention 
the chance of human error.



T


How would this work for packages that cannot be built by DMD? Or 
that have no CI infrastructure but are maintained? *cough* 
DCompute *cough*


Re: extern(C++, ns) is wrong

2018-09-05 Thread Nicholas Wilson via Digitalmars-d
On Wednesday, 5 September 2018 at 13:53:15 UTC, Jonathan M Davis 
wrote:


Very well said, thanks.

Based on everything Walter said in the previous thread, it 
honestly seems to me to be primarily like he just can't give up 
on the idea that D has to worry about modeling C++ namespaces.


That is the conclusion I came to as well.

What Walter did makes perfect sense if you assume that D needs 
to care about namespaces when using the C++ symbol in D, but 
the conclusion of the rest of us when looking at the problem 
has been that D really doesn't need to care about the 
namespaces beyond mangling, because D modules already solve the 
problem.


I think this is the key insight, everything else follows from 
this.


But regardless, I'm with you and Manu at this point in that I 
don't understand why extern(C++, "Namespace") isn't a clearly 
better (and simpler) solution overall. But maybe we'll get 
lucky and after Walter has thought about it long enough, he'll 
come around. Either way, per the current process, we would 
clearly need a DIP even if Walter already agreed. So, the next 
step is to write a DIP, and hopefully it can be written well 
enough that it's appropriately convincing unlike everything 
that has been argued thus far.


Indeed, It is a pity the DIP pipeline is so full.

Manu, what timeline do you ideally need this by? and do you have 
an implementation? Putting it into LDC is probably going to be 
the fastest given there are 3 high impact DIPs in the queue 
already + however long takes to get this trough and then 
implemented.




Re: extern(C++, ns) is wrong

2018-09-05 Thread Nicholas Wilson via Digitalmars-d
On Wednesday, 5 September 2018 at 08:30:25 UTC, Walter Bright 
wrote:

On 9/4/2018 10:16 PM, Manu wrote:
I'm serious, you can have your cake, and potentially, I could 
have my

cake too, and everybody would be happy... nobody would be sad.


If it is the same,


It is

I provided solutions in those threads. The incomplete example 
code did not make use of them.


Those "solutions" do not satisfactorily solve the problem, hence:

I have to contort my code to undo a thing that should never have 
been there. It's truly >embarrassing. I can't show this to 
people.


***I can not present my work to stakeholders with a straight 
face***


I don't think I could either.


I don't know why you have "no option" left.


There is one: add it to LDC, which will accept it, see 
https://github.com/ldc-developers/ldc/issues/2800#issuecomment-410817126 but this is a language feature we (LDC) would rather not have an upstream diff for.


This is a prime example of an industry blocker if ever there was. 
Yes there has been a lot of talking past each other, but surely 
you understand _what_  Manu is wanting even if you seem to think 
that your workarounds (which you called solutions) are 
sufficient. It is backwards compatible and solves a clear need, I 
don't see why this is such a contentious issue.





Re: DIP25/DIP1000: My thoughts round 2

2018-09-02 Thread Nicholas Wilson via Digitalmars-d

On Sunday, 2 September 2018 at 05:14:58 UTC, Chris M. wrote:
Hopefully that was coherent. Again this is me for me to get my 
thoughts out there, but also I'm interested in what other 
people think about this.


Thanks! Please add anything you think is missing to 
https://github.com/dlang/dlang.org/pull/2453 since Walter doesn't 
seem to be interested.




Re: -op can be quite strange

2018-09-01 Thread Nicholas Wilson via Digitalmars-d
On Saturday, 1 September 2018 at 14:48:55 UTC, Jonathan Marler 
wrote:
Note that we would want this to be a new option so as not to 
break anyone depending on "-op" semantics. Maybe "-om" for 
"output path based on 'Module' name"?


LDC has this already as -oq, FWIW.



Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-30 Thread Nicholas Wilson via Digitalmars-d

On Thursday, 30 August 2018 at 23:03:57 UTC, Walter Bright wrote:

On 8/25/2018 4:49 PM, Nicholas Wilson wrote:
Run semantic3 on the constructor independent of the 
requirement to destruct already constructed objects. If the 
constructors is nothrow then there is no need to have the 
destructors run or the eh code at all, because no Exceptions 
can be thrown (an Error may be thrown but that will kill the 
program). This is how I intend to fix it after I refactor 
semantic3.


A function can be made nothrow by:

try {
   
} catch (Exception e) {
   ... handle it locally ...
}


Then I should have said: no exceptions can propagate, which is 
the real problem.


Also, your proposal is ignoring the destructors, which is 
literally what the compiler does now.


It was implicit in that the throwing case would call the 
destructors in the event of an exception (otherwise the bug ain't 
fixed). This formulation is to reduce the amount of breakage, 
which was the problem last time.


Yes this will break (as in code breakage) @safe ctors calling 
@system dtors but, such is life. The ctor probably shouldn't be 
throwing in the first place. I'll probably add -vthrowingctor and 
-vthrowingdtor as well since this will be a perf hit in the case 
of a throwing ctor.


Sorry for any confusion.


Re: splitting general into Technical and less technical

2018-08-29 Thread Nicholas Wilson via Digitalmars-d

On Wednesday, 29 August 2018 at 16:38:48 UTC, Ali Çehreli wrote:

On 08/22/2018 10:20 PM, Nicholas Wilson wrote:

That reminds me, what happened to our conversation with Ali 
Çehreli about splitting general [newsgroup/forum] into 
Technical and less technical?


Even I remember that conversation. :) I don't remember who were 
involved but as soon as I opened the discussion at the next 
dinner table, I was discouraged; I think people were against 
the idea.


Ali


It was You, me, Matthias Lang, Shachar, Liran, Don(?) and maybe 
some more.


That is a pity, it would be nice to have a list that has a better 
SNR than general.
Greater industry participation on the technical matters would be 
a nice thing to have.


Re: Is @safe still a work-in-progress?

2018-08-29 Thread Nicholas Wilson via Digitalmars-d

On Wednesday, 29 August 2018 at 08:35:30 UTC, Walter Bright wrote:

On 8/28/2018 10:18 PM, Nicholas Wilson wrote:
Bugzilla is not documentation. These are language changes they 
need to be in release notes and the spec.


You asked for a clue: "we have no clue WTF its supposed to do 
or why the changes are being made" and there it is. There are 
no barriers to reviewing the idea nor the implementation.


I don't know how much more blunt I can be while still being 
professional about it:
_this must be documented properly_. This is not just about us 
reviewing it, this is also about people using it.


Think about it this way: I'm a new user and I hear that D is 
supposed to be memory safe.


Am I going to trawl through bugzilla to find about the features 
of this memory safety?


Suppose I do a search for "dlang memory safety" on how I can use 
this feature. What does a search bring up?


First hit: https://dlang.org/spec/memory-safe-d.html
Gives me a link to https://dlang.org/articles/safed.html, not 
very helpful, and to
 @system/@safe/@trusted, that tells me a bunch of things I'm not 
allowed to do in safe code.


Second hit: 
https://dlang.org/blog/2016/09/28/how-to-write-trusted-code-in-d/

More (admittedly better) info on @system/@safe/@trusted

Third Hit: 
https://forum.dlang.org/thread/ofkjuq$or6$1...@digitalmars.com welp 
the forum is down, next!


Fourth hit: https://wiki.dlang.org/Memory_Management

Fifth hit: https://dconf.org/2017/talks/bright.pdf
Some stuff about scope, possibly not up to date(!).

Sixth hit is Adam Ruppe's fork of the spec page on memory safety

Seventh is https://news.ycombinator.com/item?id=12391370

Number 8: https://www.meetup.com/en-AU/SeaLang/events/246692611/

9: 
https://www.reddit.com/r/cpp/comments/6b4xrc/walter_bright_believes_memory_safety_will_kill_c/


10: is the Wikipdia page on D.

Searching for "dlang scope" brings up scope(exit) & friends and 
some old forum posts  including 
https://forum.dlang.org/thread/obfftm$2m3j$1...@digitalmars.com 
which feels like déjà vu, followed by a bunch of irrelevant links 
to various parts of the spec.


That was on a not anonymous search, I know precisely what I'm 
looking for, and the closest thing I found was 4/5ths the way 
down a 42 slide PDF with no annotations from a year ago.


Even someone relatively familiar is going to look at the spec and 
the changelog, and they're not going to find anything BECAUSE ITS 
NOT THERE! You know where it is? Bugzilla, because that's where 
Walter thinks documentation should go.






Re: Is @safe still a work-in-progress?

2018-08-28 Thread Nicholas Wilson via Digitalmars-d

On Wednesday, 29 August 2018 at 05:04:22 UTC, Walter Bright wrote:

On 8/25/2018 4:09 AM, Nicholas Wilson wrote:
On Saturday, 25 August 2018 at 02:25:41 UTC, Walter Bright 
wrote:
I'm not hostile to debate. I just don't care for "this is 
uncharted territory, so let's do nothing" which has been 
going on for probably 4 years now, coincident with "scope is 
incomplete, D sux".


I.e. lead, follow, or get out of the way :-)


Document it


Already done: https://issues.dlang.org/show_bug.cgi?id=19097


Bugzilla is not documentation. These are language changes they 
need to be in release notes and the spec.


Re: D now has a dangerous competitor

2018-08-28 Thread Nicholas Wilson via Digitalmars-d

On Tuesday, 28 August 2018 at 08:39:20 UTC, bauss wrote:

The following language is a dangerous competitor to D.

https://github.com/joaomilho/Enterprise


Thats very funny, but I found Rockstar even funnier.


Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-26 Thread Nicholas Wilson via Digitalmars-d

On Monday, 27 August 2018 at 01:10:17 UTC, Manu wrote:

On Sun, 26 Aug 2018 at 18:08, Manu  wrote:
Actually, I'm really mostly interested in DX12 shader output 
right
now... I think there are tools that can convert LLVM to DX 
shaders? I

haven't looked into it yet, but it's on my backlog.
Next would be SPIRV for Vulkan.


This looks promising: 
https://blogs.msdn.microsoft.com/directx/2017/01/23/new-directx-shader-compiler-based-on-clangllvm-now-available-as-open-source/


I would love to do it but that repo is _horribly_ organised and 
resembles nothing like a backend and appears to lack relevant 
LLVM IR tests. SPIRV for Vulkan would be doable if there is 
support from the Vulcan folks when the SPIRV backend is 
upstreamed to LLVM.


Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-26 Thread Nicholas Wilson via Digitalmars-d

On Monday, 27 August 2018 at 00:26:35 UTC, Manu wrote:

Yeah, i've been following both those efforts.
I don't have any free time to motivate this stuff on my own 
right now.

I'm just listing all the things (because Walter asked me to).



Fair enough. I suppose you'd need namespaces working first anyway 
to get  much out of those tools.



Incidentally, what's the state of DCompute stuff lately? Did the
front-end ever get a polish pass?
That's actually another really high-value ticket that I could 
use to
gain a lot of leverage, if it's at a place where you'd want to 
show it

to developers...
Mostly, just a good set of step-by-step docs would make all the 
difference.


Mostly I've been stupidly busy with uni but I'm now FREEE!

I'm going to wait for the LLVM 7 release (very soon) and then get 
things going again: testing, atomics, docs, API contracts etc. 
I'll post to Announce when I've done all that. I'm still waiting 
for the Khronos folks to get back to me to get the SPIRV backend 
into upstream LLVM.


You're mostly interested in CUDA, right? That should be much 
easier to get shipshape.


Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-26 Thread Nicholas Wilson via Digitalmars-d

On Sunday, 26 August 2018 at 23:39:32 UTC, Manu wrote:
We could really use robust tools to produce a matching C++ .h 
file
from the extern symbols in a D module, and likewise a .di file 
from a

C/C++ header.
This category of tooling has many existing instances, it's
overwhelming. As far as I can tell, they're all experimental, or
broken, or designed only to target a specific application 
(DMD), etc.
I think it would be an advantage if there were *one* tool, that 
works,
in both directions, which is advertised, recommended, and 
maintained

by the core group.
I've evaluated them all before at various points in time, but 
the

landscape keeps shifting. Someone, please give me a prominent
hyperlink to the solution that *works*, and instructions. I 
don't have
energy to re-do comprehensive evaluations on this front, I'm 
spent.
Agree on one, make it the official one, and then track bugs 
against it

in bugzilla?


I know this isn't quite what you asked for but you should get in 
contact with Iain to generalise 
https://github.com/dlang/dmd/pull/8591/files
As for the other direction, I'd suggest talking to Atila to get 
app working for your use cases.


This is about as official as its going to get.


Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-26 Thread Nicholas Wilson via Digitalmars-d

On Sunday, 26 August 2018 at 20:55:04 UTC, Walter Bright wrote:

On 8/26/2018 12:34 PM, Manu wrote:
I work at a company with a thousand engineers, all VS users, D 
could

find home there if some rough edges were polished, but they
*absolutely must be polished* before it would be taken 
seriously.
It is consistently expressed that poor VS integration is an 
absolute

non-starter.


I will tiresomely ask again, do you have a list of each and 
every aspect of the poor integration?


Not to put words in his mouth, but:
* rvalue references: see recent DIP
* https://github.com/ldc-developers/ldc/issues/2800 Really a DMD 
issue

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

probably more.


Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-26 Thread Nicholas Wilson via Digitalmars-d

On Sunday, 26 August 2018 at 10:17:51 UTC, Walter Bright wrote:
I'm not sure what you're referring to. I'm referring to the 
specified message, and the example:


struct Array
{
int[] _payload;
~this() // (2)
{
import core.stdc.stdlib : free;
free(_payload.ptr); // (3)
}
}

class Scanner
{
Array arr;
this() @safe {}  // (1)
}

In order for (1) to be @safe, then the destructor it calls for 
arr (2) must also be @safe. But the destructor calls free() 
(3), which is not @safe. Therefore, the compilation fails. 
Inference does not solve this problem, because (2) is inferred 
as @system.




Yes but if Scanners constructor is nothrow then all is fine, 
since it won't unwind unless an error is thrown in which case it 
game over anyway.





Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-25 Thread Nicholas Wilson via Digitalmars-d

On Saturday, 25 August 2018 at 20:52:06 UTC, Walter Bright wrote:

On 8/25/2018 3:52 AM, Chris wrote:

On Friday, 24 August 2018 at 19:26:40 UTC, Walter Bright wrote:
Every programmer who says this also demands new (and 
breaking) features.

"Every programmer who..." Really?


You want to remove autodecoding (so do I) and that will break 
just about every D program in existence. For everyone else, 
it's something else that's just as important to them.


For example, Shachar wants partially constructed objects to be 
partially destructed, a quite reasonable request. Ok, but 
consider the breakage:


  struct S {
~this() {}
  }

  class C {
S s;

this() nothrow {}
  }

I.e. a nothrow constructor now must call a throwing destructor. 
This is not some made up example, it breaks existing code:


  https://github.com/dlang/dmd/pull/6816

If I fix the bug, I break existing code, and apparently a 
substantial amount of existing code. What's your advice on how 
to proceed with this?


Run semantic3 on the constructor independent of the requirement 
to destruct already constructed objects. If the constructors is 
nothrow then there is no need to have the destructors run or the 
eh code at all, because no Exceptions can be thrown (an Error may 
be thrown but that will kill the program). This is how I intend 
to fix it after I refactor semantic3.




Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-25 Thread Nicholas Wilson via Digitalmars-d

On Saturday, 25 August 2018 at 20:19:44 UTC, Walter Bright wrote:

On 8/25/2018 6:32 AM, Timon Gehr wrote:
(Or at least, not wrong. Using e.g. `void*` instead of an 
incompatible type would already be an improvement.)


Making it void* is a reasonable idea.


If/when (I really hope the latter) DIP 1011 gets in it should be 
extern(delegate) with `ref typeof(this)` as the first parameter.


Re: Is @safe still a work-in-progress?

2018-08-25 Thread Nicholas Wilson via Digitalmars-d

On Saturday, 25 August 2018 at 02:25:41 UTC, Walter Bright wrote:
I'm not hostile to debate. I just don't care for "this is 
uncharted territory, so let's do nothing" which has been going 
on for probably 4 years now, coincident with "scope is 
incomplete, D sux".


I.e. lead, follow, or get out of the way :-)


Document it and we will help you get it reviewed and merged. 
Until you do that we will stay in your way. Heck, once we 
understand it we may even lead, but we can't do that if we have 
no clue WTF its supposed to do or why the changes are being made.


At the very least PRs need detailed changelog entries and 
preferably spec updates and revisions to the DIP1000 proposal 
document. Heck even a wiki page would be useful. I'm trying to 
make the spec page on memory safe programming the authoritative 
source see https://github.com/dlang/dlang.org/pull/2453


Re: D is dead

2018-08-25 Thread Nicholas Wilson via Digitalmars-d

On Saturday, 25 August 2018 at 07:56:55 UTC, Walter Bright wrote:

On 8/24/2018 6:34 AM, Shachar Shemesh wrote:
No, unlike what I suggest, that doesn't work without carefully 
reviewing every single place you put it to see whether the 
constructor actually supports destructing a partially 
constructed object.


All D objects are default-initialized before the constructor 
sees it (unlike C++). A destructor should be able to handle a 
default-initialized object.


Then we should add a switch to inject a unittest to run a 
destructor on a default initialisable object. i.e. if it has a 
static opCall or an @disable this(); then don't otherwise do. 
Otherwise this is a well disguised instance of faith based 
programming.


Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-25 Thread Nicholas Wilson via Digitalmars-d

On Saturday, 25 August 2018 at 01:43:19 UTC, Walter Bright wrote:

On 8/24/2018 4:22 PM, tide wrote:

struct SomeStruct
{
     void foo() {
     // use SomeStruct
     }
}


void broken()
{
     void function() foo = &SomeStruct.foo;
     foo(); // runtime error, isn't actually safe uses wrong 
calling convention as well

}

Not really lack of feature so much as there exists broken 
code. This has been valid code for god knows how long. At some 
point it was usable in @safe, but it looks you can't take an 
address of a member function without "this" as well in safe 
anymore.



That's because it isn't safe. But being able to take the 
address is important for system work.


The stupid thing is you _have_ to cast (which is unsafe) the 
return type to be correct.


This could be solvable with DIP1011 to make &SomeStruct.foo 
return `extern(delegate) void function(ref Foo)` although it 
makes no explicit mention other than "member functions be 
implicitly convertible to extern(delegate) functions".


Re: D is dead

2018-08-24 Thread Nicholas Wilson via Digitalmars-d

On Friday, 24 August 2018 at 09:58:13 UTC, Walter Bright wrote:

On 8/23/2018 5:02 PM, Nicholas Wilson wrote:
am currently up against a ~thousand headed hydra~ thousand 
line function .


Good times :-)


Tell me about it. I'm now wading through its carcass in review. I 
will split it up but it takes a lot of effort.


Re: D is dead

2018-08-23 Thread Nicholas Wilson via Digitalmars-d
On Thursday, 23 August 2018 at 17:02:12 UTC, Shachar Shemesh 
wrote:
How much time or money exactly has Weka spent on getting this 
issue and other "critical" bugs fixed?


Weka is paying prominent D developers as contractors. We've had 
David Nadlinger and currently employ Johan Engelen. Both said 
they are cannot fix this particular bug.


If you can, feel free to contact me off-list, and I'm fairly 
sure we can get the budget for you to work on it. The same goes 
for anyone else on this list.


I'll be taking a good stab at it. I am currently wading through 
the swamps of Semantic Analysis and am currently up against a 
~thousand headed hydra~ thousand line function .


Re: D is dead

2018-08-23 Thread Nicholas Wilson via Digitalmars-d

On Thursday, 23 August 2018 at 07:00:01 UTC, Iain Buclaw wrote:
On Thursday, 23 August 2018 at 06:34:04 UTC, Shachar Shemesh 
wrote:

On 23/08/18 09:17, Jacob Carlborg wrote:
I don't see why we just can't add support for scoped lazy 
parameters. It's already in the language just with a 
different syntax (delegates). That would probably be an easy 
fix (last famous words :)). I guess it would be better if it 
could be inferred.


Here's the interesting question, though: is this *going* to 
happen?


We've known about this problem for ages now. No movement.

It's on my todo list, however I've instead been doomed to work 
on higher priority things.


More generally though, some time should be spent on trying out 
things in the spirit of "will it blend" just to see what 
happens.
 Putting effort towards having a more homogeneous environment 
in the language should in the long run pay its dividends.


Is there even any way to escape a lazy? If no, then lazy is 
identical to scope lazy.

E.g. https://run.dlang.io/is fails to compile



Re: D is dead (was: Dicebot on leaving D: It is anarchy driven development in all its glory.)

2018-08-22 Thread Nicholas Wilson via Digitalmars-d
On Thursday, 23 August 2018 at 03:50:44 UTC, Shachar Shemesh 
wrote:

No, no and no.

I was holding out on replying to this thread to see how the 
community would react. The vibe I'm getting, however, is that 
the people who are seeing D's problems have given up on 
affecting change.


It is no secret that when I joined Weka, I was a sole D 
detractor among a company quite enamored with the language. I 
used to have quite heated water cooler debates about that point 
of view.


Every single one of the people rushing to defend D at the time 
has since come around. There is still some debate on whether, 
points vs. counter points, choosing D was a good idea, but the 
overwhelming consensus inside Weka today is that D has *fatal* 
flaws and no path to fixing them.


A list, please? Now that I actually have time to fix things, I 
intend to do so.


And by "fatal", I mean literally flaws that are likely to 
literally kill the language.


And the thing that brought them around is not my power of 
persuasion. The thing that brought them around was spending a 
couple of years working with the language on an every-day basis.


And you will notice this in the way Weka employees talk on this 
forum: except me, they all disappeared. You used to see Idan, 
Tomer and Eyal post here. Where are they?


This forum is hostile to criticism, and generally tries to keep 
everyone using D the same way. If you're cutting edge D, the 
forum is almost no help at all. Consensus among former posters 
here is that it is generally a waste of time, so almost 
everyone left, and those who didn't, stopped posting.


And it's not just Weka. I've had a chance to talk in private to 
some other developers. Quite a lot have serious, fundamental 
issues with the language. You will notice none of them speaks 
up on this thread.


They don't see the point.


That reminds me, what happened to our conversation with Ali 
Çehreli about splitting general into Technical and less 
technical? Not to imply that the problems listed are purely 
technical. There is a distinct lack of well documented direction 
beyond incremental improvements.


No technical project is born great. If you want a technical 
project to be great, the people working on it have to focus on 
its *flaws*. The D's community just doesn't do that.


To sum it up: fatal flaws + no path to fixing + no push from 
the community = inevitable eventual death.


With great regrets,
Shachar


Indeed. It is time to push, then.

Nic


Re: Is @safe still a work-in-progress?

2018-08-21 Thread Nicholas Wilson via Digitalmars-d

On Tuesday, 21 August 2018 at 14:31:02 UTC, Atila Neves wrote:
The problem is that the code we write doesn't deal directly 
with pointers - see the recent confusion in this forum over 
where `scope` on the left applies to the `this` pointer or the 
one returned by the member function.


Kagamin just told me I needed to use `return` instead of 
`scope` to get things to work and I'm still not sure why.


The way I think about it is if you have a function that takes a 
pointer, any pointer, and either returns it or a pointer derived 
from it (dereferencing or indexing) that argument must be marked 
`return`. In your case it was a pointer derived from `this` so 
`return` must be applied to `this`.




Re: Friends don't let friends use inout with scope and -dip1000

2018-08-21 Thread Nicholas Wilson via Digitalmars-d

On Tuesday, 21 August 2018 at 10:57:15 UTC, Atila Neves wrote:

On Tuesday, 21 August 2018 at 09:50:46 UTC, Atila Neves wrote:

On Monday, 20 August 2018 at 15:55:54 UTC, Kagamin wrote:

On Monday, 20 August 2018 at 13:02:23 UTC, Atila Neves wrote:

On Monday, 20 August 2018 at 12:56:42 UTC, Kagamin wrote:
Error: address of variable s assigned to gInt with longer 
lifetime


Looks safe to me.


With dmd 2.081.2 on Arch Linux, the code above compiles with 
no error message.


Never mind, I forgot to use -dip1000. Ok, cool, so _why_ does 
it work as intended now? Also, if I have to remember to 
annotate correctly, surely this is a massive hole in @safe 
dip1000?


MyStruct is not a template, I presume `return` would get inferred 
if it was. But yeah that is annoying.


Re: Friends don't let friends use inout with scope and -dip1000

2018-08-20 Thread Nicholas Wilson via Digitalmars-d

On Monday, 20 August 2018 at 09:31:09 UTC, Atila Neves wrote:
On Friday, 17 August 2018 at 13:39:29 UTC, Steven Schveighoffer 
wrote:

// used to be scope int* ptr() { return ints; }
scope inout(int)* ptr() inout { return ints; }


Does scope apply to the return value or the `this` reference?


I assumed the return value. I think I've read DIP1000 about a 
dozen times now and I still get confused. As opposed to `const` 
or `immutable`, `scope(T)` isn't a thing so... I don't know?


What usually happens is that qualifiers to the left of the name 
apply to the return type and those to the right apply `this`. Not 
that that _should_ make any difference since lifetime ints == 
lifetime this



What happens if you remove the return type? (i.e. scope auto)


And write what instead?



scope ptr() inout { return ints; } ?



Re: static foreach, expression-Based Contract Syntax and better error messages

2018-08-16 Thread Nicholas Wilson via Digitalmars-d

On Tuesday, 7 August 2018 at 08:20:55 UTC, Basile B. wrote:
On Tuesday, 7 August 2018 at 07:33:49 UTC, Nicholas Wilson 
wrote:

so the following
void foo(As...)(As as)
in
{
   static foreach (a ;as)
   assert(a>0);
}
do
{
}

void main()
{
 foo(1,2,3,4,5);
}

passes and compiles, whereas

void foo(As...)(As as)
static foreach (a ;as)
in(a>0)
{
}

void main()
{
 foo(1,2,3,4,5);
}

does not compile.  I suppose thats fair enough, there is after 
all a not very verbose workaround.


I only note this because in researching examples for my 
multiple template constraints DIP[1], I noticed while I can 
make individual clauses easier to understand, I realised that 
recursive templates clauses are still going to be horrible so 
it would be useful to be able to do


void foo(As...)(As as)
static foreach (alias A ;As)
if(isFoo!A)
{
//...
}
[...]
Should this work? And is this something people would like to 
see added to the DIP?


No. At this point syntax of contracts or constraints is getting 
*really* mad.
I think it's better to put the static loop in the function 
body, especially since with assert you can format a nice 
message, while not with constraints.


I have decided to make the DIP be consistent with `in` contracts: 
that is allow both an expression form and block statement form. 
The block state meant can use static foreach to static assert on 
variadic lists, while the expression from is more concise.


Re: DIP 1017--Add Bottom Type--Community Review Round 1

2018-08-11 Thread Nicholas Wilson via Digitalmars-d

On Friday, 10 August 2018 at 13:15:46 UTC, Dukc wrote:
The benefit would be that null can be a regular pointer 
constant (enum null = typeof(&assert(false)).init) instead of a 
symbol with special meaning. I'd think it makes compiler rules 
less complex.


I disagree.

Another advantage is that you could pass null as an argument 
for a function template which wants to know it's element type 
(but of course not instantiate it) like any other pointer.


Of what _practical use_ is that?


Re: DIP 1017--Add Bottom Type--Community Review Round 1

2018-08-10 Thread Nicholas Wilson via Digitalmars-d

On Friday, 10 August 2018 at 11:31:02 UTC, Dukc wrote:

On Friday, 10 August 2018 at 11:28:38 UTC, Dukc wrote:


One example comes to mind: is(typeof(null) == 
typeof(assert(0))).


meant is(typeof(*null) == typeof(assert(0)))


How is that a good thing??? Also that is not specified in the 
dip. I would expect that to fail because both will produce error 
nodes in the AST, only assert(0) is considered special under this 
DIP.


Re: DIP 1017--Add Bottom Type--Community Review Round 1

2018-08-09 Thread Nicholas Wilson via Digitalmars-d

On Thursday, 9 August 2018 at 10:47:37 UTC, Stefan Koch wrote:

Regarding the rationale:

It should be pointed out that this is a further complication of 
the type-system (which is already more complex than what c++ 
has).

That does impact generic code.

My own experience with generic code has show that it is very 
hard (practically impossible) to write correct code,
(correct meaning here working as intended, when instantiation 
succeeds) even when using template constraints.




Indeed.

There is no explanation of when the additional optimizations 
would be actually relevant,

Usually functions that don't return abort the program anyway.


I presume Walter is talking about considering all branches that 
don't return to be cold and "outlining" them as much as possible 
so as to not pollute icache, which he already implemented. So I 
assume he's talking about propagating that information?


There not even an example piece of code where the newly enabled 
optimizations would make an impact.


The point about other system languages having this feature is 
actually the most substantiated one :)


It was about that is was required to be competitive which I find 
to be a bizarre claim. But we already have this in LDC, GDC 
probably has something similar (whatever corresponds to 
__attribute__(noreturn)),and if you care about perf you are not 
using DMD.





Re: DIP 1017--Add Bottom Type--Community Review Round 1

2018-08-08 Thread Nicholas Wilson via Digitalmars-d

On Thursday, 9 August 2018 at 03:02:55 UTC, Mike Parker wrote:
This is the feedback thread for the first round of Community 
Review for DIP 1017, "Add Bottom Type":


https://github.com/dlang/DIPs/blob/8274b0f600075e4553b41c31f4b77be2d917bb40/DIPs/DIP1017.md

All review-related feedback on and discussion of the DIP should 
occur in this thread. The review period will end at 11:59 PM ET 
on August 24, or when I make a post declaring it complete.


At the end of Round 1, if further review is deemed necessary, 
the DIP will be scheduled for another round. Otherwise, it will 
be queued for the Final Review and Formal Assessment by the 
language maintainers.


Please familiarize yourself with the documentation for the 
Community Review before participating.


https://github.com/dlang/DIPs/blob/master/PROCEDURE.md#community-review

Thanks in advance to all who participate.


All of my points made in the draft review still stand, i.e. that 
this should be an attribute or pragma. Note that this feature is 
already supported by LDC as an attribute.


The benefit that this DIP provides are: "documentation" 
(rationale point 2) and optimisation (rationale points 1 & 4). 
The claim made by Point 3 is dubious and unsubstantiated at best.


Rationale point 2 comes in the form of rendered documentation and 
the source code.


Rendered documentation, regardless of the form used should be 
able to convey that a function does not return. Reading the 
source it should be easily determinable that a function does not 
return, use of an suitably named attribute or pragma (i.e. pragma 
(noreturn) or @noreturn) makes it immediately obvious. Returning 
a type named "Tbottom" absolutely does not, "never_t" as 
suggested in the draft review is better but is not strictly 
better than an attribute or pragma but, IMO is still worse.


The optimisation benefits provided by dead code elimination may 
be significant, but again this information is equally well 
conveyed to the compiler by an attribute or pragma. The hardcoded 
list of symbols, will provide the vast majority of those gains so 
extending this to user code will provide very marginal benefit, 
especially with a aggressively optimising compiler (e.g. LDC, 
GDC) that will propagate that information anyway.


The downsides of this DIP are the breaking changes and unneeded 
complexity. Generic code that checks `is(T==void)` or 
`is(ReturnType!F == void)` will break, as will code that uses the 
return value of a function that happens to be inferred to return 
no type, use of the ternary ?: will now no longer always be the 
common type of the second and third operands. The complexity will 
manifest itself as making error messages more confusing, making 
the learning curve steeper than it needs to be and the 
implementation.


The DIP makes the claim that:
 * "[@noreturn] has the awkward result of a function specifying 
it has a return type T, but never returns that type". When it is 
deliberate (such as annotating a fatal error function) the is 
almost exclusively `void` (I know of no examples to the contrary).


* "[With @noreturn] other potential uses of a bottom type will 
not be expressible". What other? Documentation and optimisation 
definitely can be, the are in LDC since a long time, there are no 
other substantiated benefits listed in the DIP.


If this DIP were to make the claim that type inference and 
propagation would catch bugs, then perhaps it would make more 
sense than an attribute or pragma, but it would have to be 
convincing that resulting code breakage would be worth it.




static foreach, expression-Based Contract Syntax and better error messages

2018-08-07 Thread Nicholas Wilson via Digitalmars-d

so the following
void foo(As...)(As as)
in
{
   static foreach (a ;as)
   assert(a>0);
}
do
{
}

void main()
{
 foo(1,2,3,4,5);
}

passes and compiles, whereas

void foo(As...)(As as)
static foreach (a ;as)
in(a>0)
{
}

void main()
{
 foo(1,2,3,4,5);
}

does not compile.  I suppose thats fair enough, there is after 
all a not very verbose workaround.


I only note this because in researching examples for my multiple 
template constraints DIP[1], I noticed while I can make 
individual clauses easier to understand, I realised that 
recursive templates clauses are still going to be horrible so it 
would be useful to be able to do


void foo(As...)(As as)
static foreach (alias A ;As)
if(isFoo!A)
{
//...
}

and this was the closest thing syntactically. (yes I know I could 
have use allSatisfy here but for thing like un-recursing
ptrdiff_t countUntil(alias pred = "a == b", R, Rs...)(R haystack, 
Rs needles)

if (isForwardRange!R
&& Rs.length > 0
&& isForwardRange!(Rs[0]) == isInputRange!(Rs[0])
&& is(typeof(startsWith!pred(haystack, needles[0])))
&& (Rs.length == 1
|| is(typeof(countUntil!pred(haystack, needles[1 .. 
$])

its not so simple)

Should this work? And is this something people would like to see 
added to the DIP?


[1]:https://github.com/thewilsonator/DIPs/blob/template-constraints/DIPs/DIP1xxx.md





Re: Is there any good reason why C++ namespaces are "closed" in D?

2018-08-07 Thread Nicholas Wilson via Digitalmars-d

On Tuesday, 7 August 2018 at 05:58:17 UTC, Walter Bright wrote:

On 8/6/2018 8:14 PM, Nicholas Wilson wrote:

Yes, but only for a single instance of the namespace.
In the general case no, see the first reply in 
https://forum.dlang.org/post/xdaedmlbbqtztiqcw...@forum.dlang.org


The idea is to not have a namespace


That is what we have been arguing for all thread...

I don't see what making an alias to a namespace has to do with 
it.


That was your suggested workaround, was it not? If not you have 
_really_ lost me.





Re: Is there any good reason why C++ namespaces are "closed" in D?

2018-08-06 Thread Nicholas Wilson via Digitalmars-d

On Tuesday, 7 August 2018 at 02:25:32 UTC, Walter Bright wrote:

Let's see if we can find some common ground.

The boilerplate I suggested seems to enable DPP to generate 
working code that behaves "as if" the namespace scope is not 
there, even for nested namespaces.


Is this correct?


Yes, but only for a single instance of the namespace.
In the general case no, see the first reply in 
https://forum.dlang.org/post/xdaedmlbbqtztiqcw...@forum.dlang.org


Re: Is there any good reason why C++ namespaces are "closed" in D?

2018-07-31 Thread Nicholas Wilson via Digitalmars-d

On Tuesday, 31 July 2018 at 23:02:16 UTC, Rubn wrote:
One thing I don't like is that the C++ namespaces takes the 
name. So if you try to import a module that has C++ namespace 
of the same with the existing module, then you'll get an error. 
For effectively no reason, because as you say that namespace is 
useless and just occupies a name that could otherwise be used 
for the module name.


Indeed, case in point: std


string literal string and immutable(char)* overload ambiguity

2018-07-31 Thread Nicholas Wilson via Digitalmars-d

is there any particular reason why

void foo(string a) {}
void foo(immutable(char)* b) {}

void bar()
{
foo("baz");
}

result in

Error: foo called with argument types (string) matches both:
foo(string a)
and:
foo(immutable(char)* b)

especially given the pointer overload is almost always
void foo(immutable(char)* b)
{
foo(b[0 .. strlen(b)]);
}
and if I really want to call the pointer variant I can with
foo("baz".ptr);
but I can't call the string overload with a literal without 
creating a temp.


I think we should make string literals prefer string arguments.



Re: Is there any good reason why C++ namespaces are "closed" in D?

2018-07-29 Thread Nicholas Wilson via Digitalmars-d

On Monday, 30 July 2018 at 02:53:43 UTC, Nicholas Wilson wrote:

On Monday, 30 July 2018 at 02:15:57 UTC, Walter Bright wrote:

On 7/29/2018 1:45 PM, Manu wrote:
There's no way you'll get a bug report from someone 
complaining they
can't multiply define symbols in the same scope. That's 
common sense.


But then you cannot interface with this C++ code:

namespace ab { void foo(); }
namespace cd { void foo(); }

Why would you find this acceptable?


But you can if ab and cd are in different modules. The point is 
to decouple the mangling from the scope, leave the scope to D's 
module system, leave the mangling to extern(C++, "foo")


Not that this alleviates Alita's issues at all.


Re: Is there any good reason why C++ namespaces are "closed" in D?

2018-07-29 Thread Nicholas Wilson via Digitalmars-d

On Monday, 30 July 2018 at 02:15:57 UTC, Walter Bright wrote:

On 7/29/2018 1:45 PM, Manu wrote:
There's no way you'll get a bug report from someone 
complaining they
can't multiply define symbols in the same scope. That's common 
sense.


But then you cannot interface with this C++ code:

namespace ab { void foo(); }
namespace cd { void foo(); }

Why would you find this acceptable?


But you can if ab and cd are in different modules. The point is 
to decouple the mangling from the scope, leave the scope to D's 
module system, leave the mangling to extern(C++, "foo")


Re: Is there any good reason why C++ namespaces are "closed" in D?

2018-07-29 Thread Nicholas Wilson via Digitalmars-d

On Monday, 30 July 2018 at 02:09:37 UTC, Walter Bright wrote:

On 7/29/2018 1:52 PM, Manu wrote:

On Sun, 29 Jul 2018 at 05:10, kinke via Digitalmars-d
 wrote:

[...]
so that a straight C++ namespace => D module hierarchy mapping
would probably be required in the general case:

```
// cppns/package.d
module cppns;
extern(C++, "cppns") { void foo(); }

// cppns/nested/package.d
module cppns.nested;
extern(C++, "cppns") extern(C++, "nested") { void foo(); }
```


It's beautiful!

(but I added the quotes in there for you; without quotes is 
existing

defined behaviour which introduces scopes)



But that works now, I suggested it, and you didn't find it 
acceptable !!?!!


No it doesn't. You missed

(but I added the quotes in there for you; without quotes is 
existing

defined behaviour which introduces scopes)


With the above extern(C++, "cppns") (note the quotes) defines the 
mangling, the D module defines the scope.
This is consistent with e.g. how the druntime bindings to C's 
standard library (with extern(C)) are used with extern(C) only 
affects the mangling, not introducing a scope, only that with 
extern(C++) you can have multiple things in different namespaces 
all called the same thing, so you actually need the scope as well 
as the mangling.


Re: Is there any good reason why C++ namespaces are "closed" in D?

2018-07-28 Thread Nicholas Wilson via Digitalmars-d

On Sunday, 29 July 2018 at 03:20:29 UTC, Walter Bright wrote:

On 7/28/2018 11:18 AM, Manu wrote:
Make a PR that implements namespace as a string... I will use 
that fork of D forever.


1. Look how it is mangled on the C++ side. (Use "grep" on the 
object file.)


2. Use:

   pragma(mangle, "the mangled name")


That a) doesn't scale in a real dynamic codebase (think 
templates), and b) is platform dependent and so isn't a proper 
solution.


Honestly the only problem with Manu's suggestion is you can't 
expose `a::foo` and `b::foo` with the same signature within the 
same module due to (D) name collisions, although I don't see any 
reason why we can't do both.


Then again I don't see any (non philosophical/compiler front end 
internal) issue why you can't reopen a namespace. D is supposed 
to be pragmatic, after all.


Re: Looking for the article comparing D to Ada and others

2018-07-25 Thread Nicholas Wilson via Digitalmars-d

On Thursday, 26 July 2018 at 02:21:58 UTC, Ali Çehreli wrote:

On 07/25/2018 04:27 PM, Nicholas Wilson wrote:

On Wednesday, 25 July 2018 at 21:59:52 UTC, Ali Çehreli wrote:


Somebody had posted an article here on how well different 
languages matched certain requirements of a certain coding 
safety standards.



I remember D was doing pretty well and I think Ada (or 
SPARK?) was included as well. What article? Where?


Thank you,
Ali


https://dlang.org/blog/2018/06/20/how-an-engineering-company-chose-to-migrate-to-d/



Thanks but no. :) The article I'm looking for was specifically 
for comparing languages against each paragraph (point?) of a 
safety spec.


Ali


Oh, I vaguely remember that too. I think it was the MISRA spec? 
Or was it JSF or something else? Can't quite remember, sorry.


Re: Looking for the article comparing D to Ada and others

2018-07-25 Thread Nicholas Wilson via Digitalmars-d

On Wednesday, 25 July 2018 at 21:59:52 UTC, Ali Çehreli wrote:


Somebody had posted an article here on how well different 
languages matched certain requirements of a certain coding 
safety standards.



I remember D was doing pretty well and I think Ada (or SPARK?) 
was included as well. What article? Where?


Thank you,
Ali


https://dlang.org/blog/2018/06/20/how-an-engineering-company-chose-to-migrate-to-d/


Re: DIP 1016--ref T accepts r-values--Community Review Round 1

2018-07-20 Thread Nicholas Wilson via Digitalmars-d

On Saturday, 21 July 2018 at 04:09:25 UTC, Jonathan M Davis wrote:
Honestly, I think we're just coming from points of view that 
are too different. IMHO, the core use case for ref is for a 
function to mutate an argument and have that result progagate 
to the argument,


I think the critical point here is that the the caller is free to 
ignore the refness of the arg by creating a temporary and not 
using it further.


and having ref accept rvalues is not only counter to that, but 
it risks bugs that are currently impossible.


A class of bugs I believe to be self-evident and incredibly 
sparse.



I think that having a way to accept rvalues by ref
for functions where you want to avoid copying is potentially 
useful but not particularly critical. On the other hand, you 
seem to see little or no value in having parameters that are 
intended to only accept lvalues


As the API author you can @disable the rvalue overload, but 
nothing you do can stop the caller supplying an unused temporary 
to the ref argument. Yes you can discourage them with 
docs/@disabled overload sets/ whatever, but you can't stop them. 
That is no different to today. This DIP may lessen your ability 
to discourage them from misusing it, but you can't stop a 
stubborn idiot, and that is not the audience D is targeting.


and see great value in having functions that accept rvalues by 
ref in order to avoid copying.


It is not just the avoiding copying, if it were I'm not sure I'd 
support it. For me the greatest benefit is the increase in 
readability due to not having useless temporaries everywhere in 
ref heavy code (that may not be under API user's control).


Re: DIP 1016--ref T accepts r-values--Community Review Round 1

2018-07-20 Thread Nicholas Wilson via Digitalmars-d

On Friday, 20 July 2018 at 23:35:46 UTC, Jonathan M Davis wrote:

On Friday, July 20, 2018 14:35:57 Manu via Digitalmars-d wrote:
Comparatively rare? It's exactly what most functions using 
output ranges need to do. For many output ranges, if the 
function copies the range instead of copying, then you have a 
serious bug, because then the data that gets put to the output 
range inside the function does not affect the function argument 
- or worse, if it's a pseudo-reference type, it can partially 
mutate the argument, putting it in an invalid state. So, unless 
a function that accepts an output range is supposed to be 
taking ownership of it, the function needs to mark the output 
range parameter with ref, and it would be a bug for it to 
accept an rvalue.


If anyone screws up and does something like return an output 
range from a function without that function returning ref and 
then passes it to a function that is intended to operate on an 
output range, they would currently get an error, whereas with 
this DIP, they would instead get subtle bugs with their 
severity depending on what type of ouput range it was and what 
the code was doing with it.


This is an interesting case not completely covered by Manu's 
prior reasoning (that you can't muck it up because you need to 
use it after e.g. appender). But for the case that you would not 
need it later either you already have it as a lvalue (e.g. from a 
function parameter) or its some kind of singleton (e.g. nullSink 
or put's to a global variable).


And yes, in most cases, programmers would not pass something 
other than a variable to a function that is clearly designed to 
take its argument by ref and mutate it, but with the heavy use 
of properties in a lot of D code, it can be trivial to operate 
on something that looks like an lvalue but isn't. Right now, 
such code gets caught, because it's an error to pass an rvalue 
to a ref parameter, but with this DIP, that would no longer be 
true. The situation gets even worse when you consider code 
maintenance issues like when someone initially has something be 
a variable and then later changes it to a property function and 
doesn't make it return by ref (and property functions usually 
don't return by ref). With this DIP, there could easily be 
silent code breakage as a result, whereas such breakage would 
not be silent with the current semantics for ref.


Honestly, I don't see how accepting rvalues by ref is anything 
but error-prone for any case where the ref is there because the 
argument is supposed to be mutated and then be used after the 
function call. And while you may very well want to use ref 
simply to avoid copying - and may do that frequently right now 
in spite of that being a pain with rvalues - I have exactly the 
opposite experience that you seem to with regards to how ref is 
used. In my experience, using ref to avoid copies is rare, and 
using it to have the argument be mutated is what's common.


So this problem is restricted output range @properties that 
somehow don't return by ref, aren't intended to be used after 
having data written to them _and_ aren't singleton like?




  1   2   3   4   >