Re: DIP 1014

2018-10-02 Thread Andrei Alexandrescu via Digitalmars-d

On 10/2/18 1:51 PM, Manu wrote:

But dangling pointer is an instant crash/memory corruption... it's a
pretty bad 'bug'.


Yeah doesn't sound very brilliant. I think such a workaround wouldn't 
fare well. To keep momentum while we mull over a solution to this I 
suggest you look at porting other data structures.


Deep nesting vs early returns

2018-10-02 Thread Andrei Alexandrescu via Digitalmars-d
Kate Gregory makes a good argument on something I've often commented in 
code reviews: https://youtu.be/n0Ak6xtVXno?t=2682


Fwd: Copy Constructor DIP and implementation

2018-09-11 Thread Andrei Alexandrescu via Digitalmars-d

This should probably have been posted here. -- Andrei

 Forwarded Message 
Subject: Copy Constructor DIP and implementation
Date: Tue, 11 Sep 2018 15:08:33 +
From: RazvanN 
Organization: Digital Mars
Newsgroups: digitalmars.D.announce

Hello everyone,

I have finished writing the last details of the copy constructor DIP[1] 
and also I have published the first implementation [2]. As I wrongfully 
made a PR for the DIP queue in the early stages of the development of 
the DIP, I want to announce this way that the DIP is ready for the draft 
review now. Those who are familiar with the compiler, please take a look 
at the implementation and help me improve it!


Thanks,
RazvanN

[1] https://github.com/dlang/DIPs/pull/129
[2] https://github.com/dlang/dmd/pull/8688


Re: More fun with autodecoding

2018-09-10 Thread Andrei Alexandrescu via Digitalmars-d

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.



Re: Java also has chained exceptions, done manually

2018-09-08 Thread Andrei Alexandrescu via Digitalmars-d

On 9/7/18 7:15 PM, Tobias Mueller wrote:

On Thursday, 6 September 2018 at 14:39:12 UTC, Andrei Alexandrescu wrote:
Second, it does pay to keep abreast other languages. I had no idea 
(and am quite ashamed of it) that Java also has chained exceptions:


https://www.geeksforgeeks.org/chained-exceptions-java/


Now I'm surprised... is there a language (except C++) that supports 
exceptions that does _not_ have it?

Java: getCause()
C#: InnerException
PHP: getPrevious()
...


David Nadlinger wrote that Python also has them.

I think chained exception in D is semantically very different from other 
languages like Java.


In languages like Java or C# the exception chain has nothing to do with 
saving exceptions that are thrown in finally blocks.
Instead the chain is used for a layer model. The "outer" exception is 
the higher level exception and the "inner" exception is the lower level 
cause of the higher level exception.


Often a low level exception is quite meaningless when thrown over 
multiple levels in the call stack.
For example, imagine a program that uses a configuration file. While 
parsing the configuration, a misformatted number is encountered.
If the NumberFormatException is propagated to the top level, it is 
basically useless for programmatic error handling.

This is much better:
ConfigurationException -> JsonParsingException -> NumberFormatException

The higher level exceptions are therefore directly caused by the lower 
level exception and always thrown _directly_ in the catch block where 
the lower level exception is catched and readily available. Not in a 
finally block and not indirectly in a function called from the catch block.
Manually passing the inner exception to the constructor of the outer 
exception is trivial and IMO the right thing, because it's probably not 
always wanted.


Now in D, chained exceptions work differently.
The first exception that is thrown is deemed the "important" exception 
and later exceptions are simply chained to it. A direct semantic 
connection between the exceptions is not possible at all, since the 
later exception has no knowledge about the first exception at all.
It also means that the order of the exceptions is reversed. The first 
exception is the "outer" exception which is the exact opposite of how it 
is meant in Java.


When handling an exception, it's not clear at all what those additional 
exceptions mean and how they should be handled.


Personally I find the Java/C# model much more useful.


Well indeed the upper you are on the stack, the more likely you are in a 
high-level function. It's a good heuristic. Sadly we cannot change 
chaining semantics now, but it does stand to reason to print the last 
exception in a chain, instead of the head, as the most relevant cause. 
Guess we'd do good to have such functionality in the stdlib.



Andrei




Re: Java also has chained exceptions, done manually

2018-09-06 Thread Andrei Alexandrescu via Digitalmars-d

On 9/6/18 1:13 PM, Neia Neutuladh wrote:
The actual structure of the exceptions: `primary` has children `scope 2` 
and `scope 1`; `scope 2` has child `cause 2`; `scope 1` has child `cause 
1`. A tree.


No, it's a list.

The encoded structure: a linked list where only the first two positions 
have any structure-related meaning and the rest are just a sort of 
mish-mash.


This isn't a situation you get in Java because Java doesn't have a way 
to enqueue multiple independent actions at the end of the same block. 
You just have try/finally and try(closeable).


(As an aside, it does seem we could allow some weird cases where 
people rethrow some exception down the chain, thus creating loops. 
Hopefully that's handled properly.)


Not if you semi-manually create the loop:

auto e = new Exception("root");
scope (exit) throw new Exception("scope 1", e);
throw e;

Filed as https://issues.dlang.org/show_bug.cgi?id=19231


Thanks!


Andrei


Java also has chained exceptions, done manually

2018-09-06 Thread Andrei Alexandrescu via Digitalmars-d

In an earlier post, Don Clugston wrote:


When I originally implemented this, I discovered that the idea of
"chained exceptions" was hopeless naive. The idea was that while
processing one exception, if you encounter a second one, and you
chain them together. Then you get a third, fourth, etc.

The problem is that it's much more complicated than that. Each of the
exceptions can be a chain of exceptions themselves. This means that
you don't end up with a chain of exceptions, but rather a tree of
exceptions. That's why there are those really nasty test cases in the
test suite.

The examples in the test suite are very difficult to understand if
you expect it to be a simple chain!

On the one hand, I was very proud that I was able to work out the
barely-documented behaviour of Windows SEH, and it was really
thorough. In the initial implementation, all the complexity was
covered. It wasn't the bugfix-driven-development which dmd usually
operates under .

But on the other hand, once you can see all of the complexity,
exception chaining becomes much less convincing as a concept. Sure,
the full exception tree is available in the final exception which you
catch. But, is it of any use? I doubt it very much. It's pretty
clearly a nett loss to the language, it increases complexity with
negligible benefit. Fortunately in this case, the cost isn't really
high.


First off, there's no tree of exceptions simply because... well it's not 
there. There is on field "next", not two fields "left" and "right". It's 
a linear list, not a tree. During construction there might be the 
situation whereby two lists need to be merged. But they will be merged 
by necessity into a singly-linked list, not a tree, because we have no 
structural representation of a tree. (As an aside, it does seem we could 
allow some weird cases where people rethrow some exception down the 
chain, thus creating loops. Hopefully that's handled properly.)


Second, it does pay to keep abreast other languages. I had no idea (and 
am quite ashamed of it) that Java also has chained exceptions:


https://www.geeksforgeeks.org/chained-exceptions-java/

They implement them manually, i.e. the user who throws a new exception 
would need to pass the existing exception (or exception chain) as an 
argument to the new exception's constructor. Otherwise, an exception 
thrown from a catch/finally block obliterates the existing exception and 
replaces it with the new one:


https://stackoverflow.com/questions/3779285/exception-thrown-in-catch-and-finally-clause

So chaining exceptions in Java is a nice complementary mechanism to 
compensate for that loss in information: when you throw, you have the 
chance to chain the current exception so it doesn't get ignored. Because 
of that, D's chained exceptions mechanism can be seen as an automated 
way of doing "the right thing" in Java.


We should study similarities and distinctions with Java's mechanism and 
discuss them in our documentation.



Andrei


[OT] Leverage Points

2018-08-18 Thread Andrei Alexandrescu via Digitalmars-d

A friend recommended this article:

http://donellameadows.org/archives/leverage-points-places-to-intervene-in-a-system/

I found it awesome and would recommend to anyone in this community. 
Worth a close read - no skimming, no tl;rd etc. The question applicable 
to us - where are the best leverage points in making the D language more 
successful.



Andrei


Re: Signed DMD binaries

2018-08-16 Thread Andrei Alexandrescu via Digitalmars-d

On 8/15/18 7:44 PM, Manu wrote:

Indeed, it's the installer that's in critical need of being signed...
but all the binaries are worth signing if that's convenient.
But the installer is definitely priority #1!:)


Any chance we could delegate some of the effort of working on this to you?

Are other Windows users interested in helping?

Martin has spent a fair amount of time dealing with this, and he's not a 
Windows expert. We could definitely use some help here.




Re: High-level vision for 2018 H2?

2018-08-16 Thread Andrei Alexandrescu via Digitalmars-d

On 8/13/18 10:06 AM, walker wrote:
I am curious about the plan of 2018/H2 version also, the H1 is very 
promising and may be hard to summarize its output.


Thanks for the interest. We're behind this mainly because we're working 
on a HOPL submission. I'll try to delegate.




Re: Found on proggit: Nim receives funding from a company (D should be doing something like this)

2018-08-15 Thread Andrei Alexandrescu via Digitalmars-d

On 8/15/18 5:31 PM, Matheus wrote:

On Wednesday, 15 August 2018 at 20:45:34 UTC, Andrei Alexandrescu wrote:

... We are in talks with a few more students from Romania and Brazil...


I'm from Brazil and I use D for hobby projects. It would be nice to 
present them later, in fact I was interested to create D group around 
here and maybe these Brazilian students may help.


Matheus.


Will keep that in mind. BTW there's a fledgling idea to hold a 
C++/D/systems programming conference in Belo Horizonte.




Re: Found on proggit: Nim receives funding from a company (D should be doing something like this)

2018-08-15 Thread Andrei Alexandrescu via Digitalmars-d

On 8/13/18 5:50 AM, Joakim wrote:
Announced last week, the Nim team will be adding two full-time paid devs 
and setting up grants for needed projects with this new funding:


https://our.status.im/status-partners-with-the-team-behind-the-programming-language-nim/ 


https://nim-lang.org/blog/2018/08/07/nim-partners-with-status.html

D should also be trying to raise resources like this, though it doesn't 
have to be corporate funding from one source. This company funding Nim 
raised $100 million in an ICO last year to build some kind of 
cryptocurrency-oriented mobile apps platform:


https://www.inc.com/brian-d-evans/status-ico-raised-over-100-million-for-ethereum-powered-dapps-on-ios-and-androi.html 



There are risks, of course. This company could flame out, like many of 
these new cryptocurrency companies do, leaving Nim without ongoing 
funding. Their priorities may not align with the Nim core team.


However, there are other ways to raise funds. Companies using D could 
use the existing bountysource page to put up bounties for features/fixes 
or projects they need, to which community members who need some 
particular feature/fix could also donate:


https://www.bountysource.com/teams/d

There are two primary factors in the success of any project, design and 
resources. I'm reasonably happy with the design of D and how technical 
decisions are being made. I think this is a core strength of D.


However, it appears the D core team has so far been doing a horrible job 
in gathering resources for the project. I'm not privy to any internal 
discussions or if this is being discussed at all. But it needs to be a 
priority for the ongoing growth of this project.


Thanks for the info. That's good for Nim and something we could 
definitely benefit from as well. Currently, Sebastian Wilzbach and 
Razvan Nitu, both students, are working full time with the Foundation. 
Mike is our publishing and general PR person, working a reliable part 
time. We are in talks with a few more students from Romania and Brazil.


Our early experiments with bountysource were sadly unsuccessful. I'm not 
writing it off but we'd probably need a new angle for a new round of 
experimentation. Suggestions are welcome.


Regarding corporate sponsorship, we have been public about being 
interested, but we haven't exactly beaten off offers with a stick. I 
have personally asked our top users in several instances for assistance. 
There has been some, but not to the extent of allocating one or more 
full-time engineers. Shout out to Laeeth Isharc whose enterprise has 
been far and away the most generous, and to Weka as well for sharing 
with us some time and resources at a crucial juncture for the company.


We've always been glad to take suggestions from individual 
collaborators. Mike Parker would be the person to reach out to. What 
would be best is to get some concrete action; historically, the typical 
suggestion came in the form "here's this great idea, you go work on it". 
Even that is fine if the idea is fleshed out and argued convincingly. 
Better yet, there's no better proof that an idea is good than to 
actually execute it to demonstrable benefit.



Thanks,

Andrei


Re: std.experimental.collections.rcstring and its integration in Phobos

2018-07-17 Thread Andrei Alexandrescu via Digitalmars-d

On 7/17/18 12:58 PM, Jonathan M Davis wrote:

If it's not a range by default, why would you expect_anything_  which
operates on ranges to work with rcstring directly?


Many functions do not care about the range aspect, but do care about the 
string aspect. Consider e.g. chdir.


Re: Anyone can contact Dmitry Olshansky?

2018-07-17 Thread Andrei Alexandrescu via Digitalmars-d

Thanks, Dave, for the good points.

All: please refrain from commenting on the mental disposition of 
community members publicly.



Thanks,

Andrei


Re: Copy Constructor DIP

2018-07-17 Thread Andrei Alexandrescu via Digitalmars-d

On 7/17/18 12:04 AM, Manu wrote:

But that's the point, and the key advantage of the name ;)


[:nod:]


Shopping on Amazon on Prime Day (and beyond)? Support the D language!

2018-07-17 Thread Andrei Alexandrescu via Digitalmars-d

Amazon has a nonprofit arm:

https://smile.amazon.com

Go there and choose The D Language Foundation as your charity of choice, 
then shop normally through smile.amazon.com. A fraction of your 
expenditure will go to the Foundation.



Thanks,

Andrei


Re: Copy Constructor DIP

2018-07-17 Thread Andrei Alexandrescu via Digitalmars-d

On 7/16/18 8:57 PM, docandrew wrote:
I think in this case, a more obscure name like @copyctor is more 
descriptive.


On the contrary, it is redundant and uninformative. It applies to 
exactly a constructor that copies, so it adds no information. 
"@implicit" describes precisely what the attribute does.


Re: Copy Constructor DIP

2018-07-16 Thread Andrei Alexandrescu via Digitalmars-d

On 7/16/18 3:12 PM, ag0aep6g wrote:

On 07/16/2018 09:06 PM, Andrei Alexandrescu wrote:

On 7/14/18 11:26 AM, Jacob Carlborg wrote:

[...]
That's easily fixed by implementing a compiler recognized UDA. That 
would mean that it would only be a copy constructor if "implicit" is 
defined in core.attribute. This would also avoid any special syntax 
in the parser. The already existing @selector is implemented like this.


Affirmative. We're going that route, similar to "@safe" and "@nogc".


@safe and @nogc are not compiler recognized UDAs. If you implement 
@implicit like them, then you're not doing what Jacob suggests.


Then "negative" :o). In brief @implicit follows the same implementation 
as @safe and @nogc/


Re: Copy Constructor DIP

2018-07-16 Thread Andrei Alexandrescu via Digitalmars-d

On 7/14/18 11:26 AM, Jacob Carlborg wrote:

On Friday, 13 July 2018 at 01:18:48 UTC, Andrei Alexandrescu wrote:

On 7/12/18 2:30 PM, ag0aep6g wrote:


You're still potentially changing the semantics of existing code. 
`@implicit` can be a UDA today:



enum implicit = 0;
struct C
{
 @implicit this(ref C another) {}
}


Today, that's a normal constructor. With the DIP, it becomes a copy 
constructor.


That is correct and a liability of the current DIP. That should be 
mentioned in it.


That's easily fixed by implementing a compiler recognized UDA. That 
would mean that it would only be a copy constructor if "implicit" is 
defined in core.attribute. This would also avoid any special syntax in 
the parser. The already existing @selector is implemented like this.


Affirmative. We're going that route, similar to "@safe" and "@nogc".



Re: What determines if an algorithm goes in std.algorithm or std.range

2018-07-16 Thread Andrei Alexandrescu via Digitalmars-d

On 7/14/18 5:32 PM, aliak wrote:
Alo, I'm wondering how phobos devs view or determine what goes in to 
std.algorithm and what goes in to std.range.


To me some of them are quite obvious - well, most things can arguably be 
an algorithm. But for example "refRange" is clearly a range specific 
thing, but "transpose" is not. And things that create ranges from 
nothing also may "clearly" belong in the range module? (e.g. iota, 
generate and recurrence)


Also curious, are there any github PRs in phobos where certain 
algorithms were discussed as going in to where and what the reasonings 
were?


cheers
- Ali


There is no hard and fast rule. If it does something one would naturally 
associate with an algorithm (e.g. it would belong in a book on 
algorithms etc), it belongs in std.algorithm even if it processes 
ranges. If something is algorithmically trivial but support ranges, then 
it belongs in std.range.


Without looking: where should "chain" belong? It's a trivial algorithm 
but has a variety of intricacies for supporting different kinds of 
ranges. So it's in std.range.



Andrei


Re: Copy Constructor DIP

2018-07-14 Thread Andrei Alexandrescu via Digitalmars-d

On 7/14/18 5:03 AM, Luís Marques wrote:
If there is "no other meaning of @implicit" (other than the intersection 
of those two properties) why don't you just call it something like 
@copyctor?


I'm totally cool with giving the attribute a more obscure name such as 
@copyctor or anything people want really.


(What follows is a personal opinion.

I think it's better to choose a more general attribute name with reduced 
initial applicability. Then application of said attribute can be 
extended to other functions with ease. In contrast, an obscure attribute 
name is sure to be followed by more obscure attribute names. And don't 
get me started about inventing new syntax.


Regarding the hand-wringing over generality: we have an exceedingly poor 
record of paralysis of analysis, whereby we'd worry that every design 
decision potentially locks us out from all other as-of-yet-unchosen 
design decisions. If history is any indication, this sudden worry about 
vaguely-promising green pastures of the future is a sign of malady. We 
want copy construction. Conflating this with a very general schemata for 
implicit conversion would not be a wise decision in my opinion. I now 
deeply regret ever telling Razvan to mention future possible directions. 
This DIP must do implicit copy constructors and do it well, nothing less 
and nothing more.)



Andrei


Re: Copy Constructor DIP

2018-07-13 Thread Andrei Alexandrescu via Digitalmars-d

On 7/13/18 5:49 PM, rikki cattermole wrote:

On 14/07/2018 9:28 AM, Manu wrote:
I've already contributed other points to this DIP in the way you 
describe.

This one however is very strange, and I'm surprised you can find the
hand-wavy introduction of a new attribute without any sense of where
it's going to be okay. Or maybe, I'm surprised I'm the only one that
finds problem with that.


You are very much not alone.

I didn't articulate it very clearly, but I am super not happy with such 
a new attribute.


It's a very simple process - @implicit is not invented as much as a given.

We need to distinguish a constructor from other constructors.

The constructor supports attributes.

Attributes are a mechanism for distinguishing declarations from other 
declarations.


Ergo, an attribute is the mechanism of choice.

Done deal.

=

If we don't like the use of an attribute, it means we somehow failed in 
defining attributes in the first place. (I don't think we did; 
attributes as defined in D are brilliant and currently underused.) It's 
poor language design to define a mechanism for doing a category of Xs 
and then explicitly avoiding it exactly when the opportunity of doing X 
arises.


From that vantage point, the choice of an attribute to identify 
implicit copy construction is unassailably obvious, and elucubrated 
syntax inventions such as "@this", "this(ref this x)" are chucklesomely 
profligate and ridiculously baroque.



Andrei


Re: Copy Constructor DIP

2018-07-13 Thread Andrei Alexandrescu via Digitalmars-d

On 7/13/18 5:28 PM, Manu wrote:

As I originally said, my feedback is concrete: specify @implicit, this
DIP depends on it.


The specification of @implicit is in the DIP in full: a constructor that 
takes by reference a qualified typeof(this) and has the @implicit 
attribute will be callable implicitly by the compiler. There is no other 
meaning of @implicit. That completes the spec of @implicit.


Sadly we got to irreducible positions once again: you and I used 
different definitions for common terms like "define", "specify", 
"explain", "contribute", and then you use them to ask questions or make 
demands, all of which I'm sure you find reasonable. But I am unable to 
understand them, let alone take them under advisement when working on 
the DIP. (I did understand your reference to the assignment and will 
work on that, thanks much.) You will need to forgive me for the scarcity 
of my future answers - but believe me I will do my best to derive value 
from your feedback.



Andrei


Re: Copy Constructor DIP

2018-07-13 Thread Andrei Alexandrescu via Digitalmars-d

On 7/13/18 12:06 PM, xenon325 wrote:

 From the DIP:
The copy constructor declaration will be recognized by the parser when 
the tokens @, implicit, this are encountered exactly in this order


Regarding "exactly in this order". The code below would be allowed and 
define copy c'tor for `A` and usual c'tor for `B` ?



     struct implicit{}

     struct A {
     @safe @implicit this(ref A) {}
     }

     struct B {
     @implicit @safe this(ref B) {}
     }


We'll change that part to accept the standard attribute syntax.



Re: Copy Constructor DIP

2018-07-13 Thread Andrei Alexandrescu via Digitalmars-d

On 7/13/18 11:14 AM, Atila Neves wrote:

On Friday, 13 July 2018 at 14:12:59 UTC, Andrei Alexandrescu wrote:

On 7/13/18 8:31 AM, Atila Neves wrote:

On Friday, 13 July 2018 at 03:01:25 UTC, Manu wrote:

[...]


https://github.com/search?q=%22this%5C%28ref%22+language%3AD&type=Code

The answer seems to be: not many. Most of the results above are false 
positives because github won't let me escape the left parenthesis.


A proposal that just works without any user intervention would 
definitely be attractive.


The drawback is silent modification of code behavior. Consider:

import std.stdio;
struct A {
    this(ref immutable A obj) { writeln("x"); }
}
void main()
{
    immutable A a1;
    A a2 = A(a1);
    A a3 = a1;
}

With the current language, "x" is printed once. If we make the ctor 
implicit, "x" is printed twice.


In the "levels of hell" of semantics changes, probably the nicest is 
allowing code to compile that previously didn't. Then, refusing to 
compile code that previously did would be definitely bad. But if you 
want to drink the cup of disgrace to the bottom, you must reach for 
silent change of behavior.


I agree on the levels of hell. I wasn't aware the kind of change above 
would happen - methinks it should be in the DIP.


Great. Razvan, can you please add this example with discussion to the 
DIP (probably at the end of the Motivation section as an explanation why 
we need the addition of @implicit). Thanks.


I think I now even understand why `@implicit` is there to begin with. I 
still think it's confusing, so imagine someone new to the language.


Interesting. Coming from a C++ background makes the matter obvious 
because there's plenty of implicit vs. explicit discussion. To 
compensate for my bias - what do you think would be a better attribute name?



Andrei



Re: Copy Constructor DIP

2018-07-13 Thread Andrei Alexandrescu via Digitalmars-d

On 7/12/18 11:01 PM, Manu wrote:

What existing code are you changing the semantics of?
It's still not clear to me how accepting `this(ref T)` as a magic
signature that is a copy constructor can break existing code?
Is it the unlikely^^2 case that the function exists somewhere and
doesn't perform copy construction?
   1. the function is highly unlikely to exist because postblit; it's a
meaningless function to write. are there any known instances of that
signature in the wild?
   2. if the function does exist, it's highly unlikely that it doesn't
perform a valid copy construction; what else could it possibly do?
   3. remaining cases are broken by this DIP, but they are probably
crazy and deserve to be deprecated!

Is there any reasonable existing use of the signature that would be
legitimately broken by being invoked implicitly?
I feel like there's something that I'm missing... but if there's not,
then just change the semantic.

I reason; copy construction is something so fundamental. It will be
written by basically every programmer with relative high frequently,
and adding awkward syntax or weird language baggage to the concept
feels like a very poor choice.
By contrast, if there's 1 user out there who used the copy-constructor
signature to do some weird thing other than copy construction, and
their code is broken by this change, his use case does not balance the
imposition applied to every implementation of copy constructor forever
from this time forward.
This is so much more important than that, it's extremely fundamental
language stuff, and needs to be as friction-less as possible, and it
should certainly not reek of legacy drama.


Noted. So in summary you would be okay with changing semantics of 
existing code, under the intuition that the change is unlikely to be 
destructive anyway.


Re: Copy Constructor DIP

2018-07-13 Thread Andrei Alexandrescu via Digitalmars-d

On 7/12/18 11:45 PM, Manu wrote:
On Thu, 12 Jul 2018 at 20:15, Meta via Digitalmars-d 
 wrote:


On Friday, 13 July 2018 at 02:32:59 UTC, Manu wrote:

Seriously, if I was making this proposal to you, and you were in
my position... there is no way in hell that you'd allow any of
us to slip something so substantial by like that with the wave of
a hand. This DIP depends on @implicit. How can you argue
otherwise?


Nothing is being slipped by as far as I'm concerned. @implicit is 
solely introduced in the DIP as a marker for the copy constructor,

and it doesn't seem like it's intended for anything further than
avoiding breaking code. It feels to me like you're making a
mountain out of an ant hill.


That's the whole point though. We're debating whether "@implicit" is
a good idea. And it's the only detail of the DIP that feels
noteworthy or contentious to me. The rest is pretty much
common-sense, and long overdue.

I can see myself getting behind 2 possibilities, no @implicit, or 
@implicit done right.


A couple of simple ideas are making the process productive. One is to
rely on facts instead of feelings. "It's weird" or "I don't like it" are
less helpful than "semantics of this or that case are not covered".

Another is precision. Stating vague goals and standards ("I want
@implicit done well") and systematically asking others to actually put
in the work is less desirable than providing concrete, motivated, 
actionable feedback.


To the second point: we have a history of defining features too 
permissively, to then regret not having waited to accumulate experience. 
Starting with a restricted version then building on experience with it 
seems to be a much better strategy. From that perspective, introducing 
implicit only for restricted copy construction seems like a good step 
that doesn't take others, without precluding them.


I don't see myself getting behind introduction of @implicit on such 
terms that it's nothing but "a marker for the copy constructor". So 
this 'mountain' is critical to understanding whether I can support 
this DIP as proposed or not.


I'd put it a slightly different way. "Getting behind" and "supporting or 
not" suggests a position of power and an emphasis on the politics of the 
process. The natural counter to this would be asking whether your 
support is necessary, which put us all in a very unproductive position.


The right emphasis is not getting your support on a given DIP, but 
instead us all benefiting of your active contribution to a better DIP.



Thanks,

Andrei


Re: Copy Constructor DIP

2018-07-13 Thread Andrei Alexandrescu via Digitalmars-d

On 7/13/18 8:31 AM, Atila Neves wrote:

On Friday, 13 July 2018 at 03:01:25 UTC, Manu wrote:
On Thu, 12 Jul 2018 at 19:15, Andrei Alexandrescu via Digitalmars-d 
 wrote:


On 7/12/18 6:34 PM, Manu wrote:
> On Thu, 12 Jul 2018 at 06:50, Andrei Alexandrescu via > 
Digitalmars-d  wrote:

>>

[..]
doesn't perform copy construction?
  1. the function is highly unlikely to exist because postblit; it's a
meaningless function to write. are there any known instances of that
signature in the wild?


https://github.com/search?q=%22this%5C%28ref%22+language%3AD&type=Code

The answer seems to be: not many. Most of the results above are false 
positives because github won't let me escape the left parenthesis.


A proposal that just works without any user intervention would 
definitely be attractive.


The drawback is silent modification of code behavior. Consider:

import std.stdio;
struct A {
this(ref immutable A obj) { writeln("x"); }
}
void main()
{
immutable A a1;
A a2 = A(a1);
A a3 = a1;
}

With the current language, "x" is printed once. If we make the ctor 
implicit, "x" is printed twice.


In the "levels of hell" of semantics changes, probably the nicest is 
allowing code to compile that previously didn't. Then, refusing to 
compile code that previously did would be definitely bad. But if you 
want to drink the cup of disgrace to the bottom, you must reach for 
silent change of behavior.


Re: Copy Constructor DIP

2018-07-12 Thread Andrei Alexandrescu via Digitalmars-d

On 7/12/18 10:05 PM, Manu wrote:

On Thu, 12 Jul 2018 at 18:25, Andrei Alexandrescu via Digitalmars-d
 wrote:


On 7/12/18 4:29 PM, Manu wrote:

Being able to implement them both independently is*occasionally*
useful, but 95% of the time, destruct + copy-construct is an equally
efficient implementation for assignment. I'd suggest that this
destruct+copy-construct pattern is a perfectly good substitute for
assignment in most cases, and maybe the compiler should deploy the
pattern as an implicit copy constructor in lieu of an explicit one?
So, if the user specifies a complex copy constructor, but no
assignment operator (which just blits on copy), then they've almost
certainly introduced a bug on copying! Perhaps the compiler should
automatically emit an assignment operator implemented as above in
presence of a (suite of? [const/immutable/etc permutations]) 'complex'
copy constructor?


Not the charter of the current DIP.


In a post-blit world, with no opAssign specified, postblit will call
for copy construction AND for assignment, thereby assignment is always
correct.
Once postblit is swapped for a copy-constructor, absence of opAssign
will result in invalid behaviour on assignment.

Introduction of copy constructor breaks default assignment, it needs
to address it somehow. I think my suggestion is the only practical
solution.


Affirmative. The DIP needs to specify how assignment is handled if no 
opAssign is present but a copy ctor is present. Thanks!




Re: Copy Constructor DIP

2018-07-12 Thread Andrei Alexandrescu via Digitalmars-d

On 7/12/18 6:37 PM, Manu wrote:

On Thu, 12 Jul 2018 at 07:15, Andrei Alexandrescu via Digitalmars-d
 wrote:


On 07/12/2018 09:49 AM, Atila Neves wrote:

On Thursday, 12 July 2018 at 06:54:37 UTC, RazvanN wrote:


[...]



If by "come in pairs" you mean that you can define them both, then yes,
that is the case. Will add a paragraph in the DIP to specify this.

You mentioned that it's terrible that the assignment operator
and the copy constructor come in pairs. Why is that? Would you rather
have a copy constructor that is used also as an assignment operator?


Because, like in C++, now you have to implement both and make sure they
do the same thing. Boilerplaty and a recipe for disaster.

Atila


There's no meaningful way to avoid that. The two operations are
fundamentally different, are typechecked differently, and actually are
different in the presence of qualifiers on fields.

Introspection is a key helper here compared to C++.


As I've said elsewhere, opAssign() can be fabricated by:
   this.destroy(); emplace(&this, copyFrom);


Not if the object has immutable fields, is immutable itself, is assigned 
from an immutable object and has non-immutable indirections, etc.


One issue the DIP is addressing carefully is copying across qualifier 
combinations. It also emphasizes how the current postblit fails at that.



We should consider fabricating an implicit assignment operator in the
presence of an elaborate copy constructor.


Not in this DIP.


As you say, this interacts with qualifiers... I don't think it's
trivial, but I think it should be explored. Otherwise whenever anyone
forgets to implement an assignment operator, it'll just blit, which is
almost certainly incorrect.


Exploring is of course welcome. Are you talking about the D language? 
Assignment never did just blit, and this DIP does not propose that.



Andrei


Re: Copy Constructor DIP

2018-07-12 Thread Andrei Alexandrescu via Digitalmars-d

On 7/12/18 6:34 PM, Manu wrote:

On Thu, 12 Jul 2018 at 06:50, Andrei Alexandrescu via Digitalmars-d
 wrote:


On 07/11/2018 11:11 AM, Atila Neves wrote:

On Wednesday, 11 July 2018 at 07:40:32 UTC, RazvanN wrote:

But there's a super explicit `@implicit` thing written right there...
so should we expect that an *explicit* call to the copy constructor
is not allowed? Or maybe it is allowed and `@implicit` is a lie?


The @implicit is there to point out that you cannot call that method
explicitly; it gets called for you implicitly when you construct an
object
as a copy of another object.


How is this different from other types of constructors or destructors?


The main difference is that the compiler may insert calls to it implicitly.


You mean like ~this(), and op[Anything](), and front() and popFront()
and empty()?
I don't think we need this attribute.


I mentioned this, and patiently will mention it again: we need to 
introduce the attribute so as to avoid silently changing the semantics 
of existing code.


Re: Copy Constructor DIP

2018-07-12 Thread Andrei Alexandrescu via Digitalmars-d

On 7/12/18 7:15 PM, Manu wrote:

On Thu, 12 Jul 2018 at 08:36, Andrei Alexandrescu via Digitalmars-d
 wrote:


On 07/12/2018 11:14 AM, Luís Marques wrote:

On Thursday, 12 July 2018 at 14:56:33 UTC, Luís Marques wrote:

When designing D libraries than lean towards DSL style, I've
frequently felt impaired by the lack of implicit conversions in D. In
my experience, it's not that all types need to be implicitly
convertible to other types. Just being able to mark a few types as
implicitly convertible to some other specific types would go a long
way to alleviate the limitations I felt. It would also solve problems
like an arbitrary limit on the depth of implicit conversions.

I had imagined that maybe one day an implicit keyword could be
introduced to mark such permissible implicit conversions. Seeing an
implicit "keyword" being introduced here with different semantics than
I envisioned makes me even less hopeful that some day such implicit
conversions annotations could be introduced. So... maybe consider
choosing some other syntactic notation? Besides, the fact that the
compiler can implicitly introduce calls to the copy ctor doesn't
strike me as something particularly central to the concept, so it
seems like an odd choice for something to distinguish a copy ctor.


More details. The DIP says:

"The structName type needs to be identical to typeof(this); an error is
issued otherwise. This requirement may be relaxed in the future in order
to accomodate copying from objects of a different type"
(BTW, typo in "accomodate")

That would mean that if such a relaxation were introduced, then suddenly
*all* copy ctors would imply implicit conversion between the respective
types.


No, only constructors annotated with @implicit would be implicit. But
that's only a possible future direction not part of this DIP.

Also there are many complications related to allowing implicit
conversions across distinct types, and this DIP should not get embroiled
in those. That would be a different pursuit that I encourage you to
consider.


I feel like this DIP depends on an @implicit DIP, and that one needs
to come first...


Negative.



Re: Copy Constructor DIP

2018-07-12 Thread Andrei Alexandrescu via Digitalmars-d

On 7/12/18 4:29 PM, Manu wrote:

Being able to implement them both independently is*occasionally*
useful, but 95% of the time, destruct + copy-construct is an equally
efficient implementation for assignment. I'd suggest that this
destruct+copy-construct pattern is a perfectly good substitute for
assignment in most cases, and maybe the compiler should deploy the
pattern as an implicit copy constructor in lieu of an explicit one?
So, if the user specifies a complex copy constructor, but no
assignment operator (which just blits on copy), then they've almost
certainly introduced a bug on copying! Perhaps the compiler should
automatically emit an assignment operator implemented as above in
presence of a (suite of? [const/immutable/etc permutations]) 'complex'
copy constructor?


Not the charter of the current DIP.


Re: Copy Constructor DIP

2018-07-12 Thread Andrei Alexandrescu via Digitalmars-d

On 7/12/18 2:30 PM, ag0aep6g wrote:

On 07/12/2018 03:40 PM, Andrei Alexandrescu wrote:

On 07/10/2018 04:58 PM, Manu wrote:

[...]

1. Explain the need and reasoning behind `@implicit`.


Razvan: I think it would help to explain that the attribute is 
necessary to avoid changing semantics of existing code. Thanks.


You're still potentially changing the semantics of existing code. 
`@implicit` can be a UDA today:



enum implicit = 0;
struct C
{
     @implicit this(ref C another) {}
}


Today, that's a normal constructor. With the DIP, it becomes a copy 
constructor.


That is correct and a liability of the current DIP. That should be 
mentioned in it.


Re: Copy Constructor DIP

2018-07-12 Thread Andrei Alexandrescu via Digitalmars-d

On 7/12/18 11:42 AM, Luís Marques wrote:

On Thursday, 12 July 2018 at 15:33:03 UTC, Andrei Alexandrescu wrote:
Again: not the charter of this DIP, so you should ask yourself, not 
us, this question.


Look, I understand it can be frustrating to have a concrete design 
proposal derailed by a myriad of speculative questions. But if we 
suspect that design decision of a DIP might interact poorly with other 
plausible future D features, should we not at least express our concerns 
and hopes? By the time the other DIPs come out it might be too late to 
address the concerns.


In any case, I hope my comments were not too out of bounds of the 
discussion. If so, I'm sorry.


Definitely good topics to discuss. This is a collaborative process, not 
a confrontational one. If this DIP precludes good future decisions, 
that's definitely a meaningful discussion.


Re: Copy Constructor DIP

2018-07-12 Thread Andrei Alexandrescu via Digitalmars-d

On 07/12/2018 11:14 AM, Luís Marques wrote:

On Thursday, 12 July 2018 at 14:56:33 UTC, Luís Marques wrote:
When designing D libraries than lean towards DSL style, I've 
frequently felt impaired by the lack of implicit conversions in D. In 
my experience, it's not that all types need to be implicitly 
convertible to other types. Just being able to mark a few types as 
implicitly convertible to some other specific types would go a long 
way to alleviate the limitations I felt. It would also solve problems 
like an arbitrary limit on the depth of implicit conversions.


I had imagined that maybe one day an implicit keyword could be 
introduced to mark such permissible implicit conversions. Seeing an 
implicit "keyword" being introduced here with different semantics than 
I envisioned makes me even less hopeful that some day such implicit 
conversions annotations could be introduced. So... maybe consider 
choosing some other syntactic notation? Besides, the fact that the 
compiler can implicitly introduce calls to the copy ctor doesn't 
strike me as something particularly central to the concept, so it 
seems like an odd choice for something to distinguish a copy ctor.


More details. The DIP says:

"The structName type needs to be identical to typeof(this); an error is 
issued otherwise. This requirement may be relaxed in the future in order 
to accomodate copying from objects of a different type"

(BTW, typo in "accomodate")

That would mean that if such a relaxation were introduced, then suddenly 
*all* copy ctors would imply implicit conversion between the respective 
types.


No, only constructors annotated with @implicit would be implicit. But 
that's only a possible future direction not part of this DIP.


Also there are many complications related to allowing implicit 
conversions across distinct types, and this DIP should not get embroiled 
in those. That would be a different pursuit that I encourage you to 
consider.


Re: Copy Constructor DIP

2018-07-12 Thread Andrei Alexandrescu via Digitalmars-d

On 07/12/2018 11:29 AM, Luís Marques wrote:

On Thursday, 12 July 2018 at 15:25:10 UTC, Luís Marques wrote:

On Thursday, 12 July 2018 at 15:14:19 UTC, Luís Marques wrote:
BTW: Multiple alias this is still planned for inclusion in D, right? 
If so, what would be the (pratical?) difference between having copy 
ctors with such a relaxed type requirement and just defining an 
equivalent alias this method? In case the answer is that there's no 
significant difference, why not drop multiple alias this, then?


Sorry for the stream-of-conscience type posts. But, to clarify further: 
if alias this provides access to the members of the converted type 
(besides type conversion), couldn't that feature be folded into the same 
mechanism of the copy ctor (or vice-versa), to avoid mostly redundant 
features in the language, with subtle interactions?


The DIP mentions the interaction of @implicit with alias this.


Re: Copy Constructor DIP

2018-07-12 Thread Andrei Alexandrescu via Digitalmars-d

On 07/12/2018 11:25 AM, Luís Marques wrote:

On Thursday, 12 July 2018 at 15:14:19 UTC, Luís Marques wrote:

More details. The DIP says:

"The structName type needs to be identical to typeof(this); an error 
is issued otherwise. This requirement may be relaxed in the future in 
order to accomodate copying from objects of a different type"

(BTW, typo in "accomodate")

That would mean that if such a relaxation were introduced, then 
suddenly *all* copy ctors would imply implicit conversion between the 
respective types. Given D's stance on implicit conversions, I suspect 
that's not going to pass mustard. So I would prefer the any "implicit" 
keyword-like annotation to be reserved for explicitly approved 
implicit conversions.


BTW: Multiple alias this is still planned for inclusion in D, right? If 
so, what would be the (pratical?) difference between having copy ctors 
with such a relaxed type requirement and just defining an equivalent 
alias this method? In case the answer is that there's no significant 
difference, why not drop multiple alias this, then?


Again: not the charter of this DIP, so you should ask yourself, not us, 
this question.


Re: Copy Constructor DIP

2018-07-12 Thread Andrei Alexandrescu via Digitalmars-d

On 07/12/2018 11:22 AM, Timon Gehr wrote:

On 12.07.2018 15:29, Andrei Alexandrescu wrote:

On 07/11/2018 05:55 AM, Nick Treleaven wrote:

...

Removing `static` works. Otherwise I tried changing `ref` to `alias`:

Error: variable src cannot be read at compile time

But this shorter code seems to work fine:

this.tupleof = src.tupleof;


Odd. Timon, what would be the reason for that error? Razvan, can you 
please look into removing "static" for now. Thanks!


The reason for this specific error is that `src.i` is neither a symbol 
nor a constant value. tupleof is a case of built-in compiler magic, 
because it can produce an expression tuple that contains run-time values 
that are not symbols. The following (manually unrolled) code also does 
not work:


alias field0 = s.tupleof[0];
t.tupleof[0] = field0;
alias field1 = s.tupleof[1];
t.tupleof[1] = field1;
alias field2 = s.tupleof[2];
t.tupleof[2] = field2;

Error: alias `a` cannot alias an expression `tuple(s.a, s.b, s.c)[0]`
Error: alias `b` cannot alias an expression `tuple(s.a, s.b, s.c)[1]`
Error: alias `c` cannot alias an expression `tuple(s.a, s.b, s.c)[2]`

It could be argued that the `static foreach` implementation should 
produce the same error message. (The fact that the AliasDecl constructor 
takes a Dsymbol instead of an Expression has led to multiple 
reimplementations of parts of the aliasing logic in different parts of 
the DMD code, `static foreach` is using the same implementation also 
used by unrolled foreach, and it requires that all loop variables are 
either symbols or constant values, while unrolled foreach can fall back 
to introducing runtime variables for this special case.)


One way to fix is to lift all the unnecessary limitations that are 
introduced by the fact that the AliasDecl constructor takes a Dsymbol. 
I.e. that "you can only alias symbols".


Alternatively, it would be possible to redefine `static foreach` 
statements such that they work for any aggregate with statically known 
length and element types, and to allow run-time loop variables to be 
generated when iterating over run-time values.


Thanks!


Re: Copy Constructor DIP

2018-07-12 Thread Andrei Alexandrescu via Digitalmars-d

On 07/12/2018 10:54 AM, Jonathan M Davis wrote:

On Thursday, 12 July 2018 07:45:30 MDT Andrei Alexandrescu via Digitalmars-d
wrote:

I also very much dislike the syntax - it makes no sense to me at all. I
commented on the PR itself asking why it differs so much from C++ -
specifically, what's bad about the C++ way of doing things there that we
want to avoid?


C++ is at the other end of the spectrum - constructors are too implicit,
so the "explicit" keyword has been introduced with the advice to use it
in the vast majority of cases. If C++ could do it again, it would make
everything explicit and add an "implicit" keyword.


That's only an issue in C++, because C++ uses constructors for implicit
conversions unless you mark them with explicit. D doesn't ever do implicit
conversions like that. All constructors are effectively explicit. Is this
DIP proposing that we add such implicit conversions?


The DIP is proposing what's in the DIP :o). We actually clarify this in 
text:


"The type of the parameter to the copy constructor needs to be identical 
to typeof(this); an error is issued otherwise. This requirement may be 
relaxed in the future in order to accomodate implicit copying from 
objects of a different type:" [example follows]



I really don't understand what the purpose of @implicit is here. What's the
problem of just going off of the type of the constructor's single parameter
to determine whether it's a copy constructor?


That would silently change semantics of existing code, which is to be 
avoided.



Andrei


Re: Copy Constructor DIP

2018-07-12 Thread Andrei Alexandrescu via Digitalmars-d

On 07/12/2018 09:49 AM, Atila Neves wrote:

On Thursday, 12 July 2018 at 06:54:37 UTC, RazvanN wrote:


[...]



If by "come in pairs" you mean that you can define them both, then yes,
that is the case. Will add a paragraph in the DIP to specify this.

You mentioned that it's terrible that the assignment operator
and the copy constructor come in pairs. Why is that? Would you rather
have a copy constructor that is used also as an assignment operator?


Because, like in C++, now you have to implement both and make sure they 
do the same thing. Boilerplaty and a recipe for disaster.


Atila


There's no meaningful way to avoid that. The two operations are 
fundamentally different, are typechecked differently, and actually are 
different in the presence of qualifiers on fields.


Introspection is a key helper here compared to C++.


Re: Copy Constructor DIP

2018-07-12 Thread Andrei Alexandrescu via Digitalmars-d

On 07/11/2018 12:19 PM, vit wrote:

On Wednesday, 11 July 2018 at 07:40:32 UTC, RazvanN wrote:
But there's a super explicit `@implicit` thing written right there... 
so should we expect that an *explicit* call to the copy constructor 
is not allowed? Or maybe it is allowed and `@implicit` is a lie?


The @implicit is there to point out that you cannot call that method
explicitly; it gets called for you implicitly when you construct an 
object

as a copy of another object.


Can be explicit constructor overloaded with implicit constructor when 
both have same signature?


Thanks for this. Yes we need to add a mention.


Re: Copy Constructor DIP

2018-07-12 Thread Andrei Alexandrescu via Digitalmars-d

On 07/11/2018 05:28 PM, Manu wrote:

What's wrong with:
struct S {
   this(ref S copyFrom);
}

That looks like a perfectly good copy constructor declaration ;)
I'm just saying, the DIP needs to explain this.


Thanks, worth a paragraph discussing silent semantics change.


Right. This is all obvious and intuitive.
What I'm hearing is that under this proposal, copy constructors and
assignment operators DO come in pairs (just like in C++), but that's
not mentioned here in this DIP. Since this proposal will introduce
that recommended pattern from C++, it may be worth mentioning.


Shouldn't hurt to add 1-2 sentences to the effect. (Also an example.)



Re: Copy Constructor DIP

2018-07-12 Thread Andrei Alexandrescu via Digitalmars-d

On 07/12/2018 02:54 AM, RazvanN wrote:

What's wrong with:
struct S {
  this(ref S copyFrom);
}

That looks like a perfectly good copy constructor declaration ;) I'm 
just saying, the DIP needs to explain this.


That is actually a valid constructor, according to today's compiler. There
might be code out there that uses this syntax for the constructor and 
overnight

it will be turned into a copy constructor.

I agree that the current syntax is lacking. This was Andrei's proposition
and I was initially against it, but he said to put it in the DIP so that
we can discuss it as a community. Maybe this syntax is better:

@this(ref S a another)

It looks like the c++ copy constructor but the `@` makes it different from
a constructor, so we're good. What do you think?


We will not add syntax if we can help it.


Re: Copy Constructor DIP

2018-07-12 Thread Andrei Alexandrescu via Digitalmars-d

On 07/11/2018 11:11 AM, Atila Neves wrote:

On Wednesday, 11 July 2018 at 07:40:32 UTC, RazvanN wrote:
But there's a super explicit `@implicit` thing written right there... 
so should we expect that an *explicit* call to the copy constructor 
is not allowed? Or maybe it is allowed and `@implicit` is a lie?


The @implicit is there to point out that you cannot call that method
explicitly; it gets called for you implicitly when you construct an 
object

as a copy of another object.


How is this different from other types of constructors or destructors?


The main difference is that the compiler may insert calls to it implicitly.

I also very much dislike the syntax - it makes no sense to me at all. I 
commented on the PR itself asking why it differs so much from C++ - 
specifically, what's bad about the C++ way of doing things there that we 
want to avoid?


C++ is at the other end of the spectrum - constructors are too implicit, 
so the "explicit" keyword has been introduced with the advice to use it 
in the vast majority of cases. If C++ could do it again, it would make 
everything explicit and add an "implicit" keyword.


Re: Copy Constructor DIP

2018-07-12 Thread Andrei Alexandrescu via Digitalmars-d

On 07/10/2018 06:50 PM, Manu wrote:

On Tue, 10 Jul 2018 at 15:23, Jonathan M Davis via Digitalmars-d
 wrote:


On Tuesday, 10 July 2018 14:58:09 MDT Manu via Digitalmars-d wrote:

2. It looks like copy constructors are used to perform assignments
(and not constructions)... but, there is also opAssign. What gives?
 Eg:
   S b = a; // <- copy construction? looks like an assignment.
 And not:
   S b = S(a); // <- actually looks like a construction, but this
syntax seems to not be intended (and rightly so, it's pretty terrible)


S b = a;

has never been assignment in either C++ or D. It's initialization /
construction, which means that it calls a constructor - be that a postblit
constructor or a copy constructor. Assignment only occurs when you're giving
an existing object a new value.


I know this, but it's not syntactically obvious, it just depends on
the fact that you already know that fact... I feel a DIP about copy
construction needs to have some text explaining that, and where the
edges are.


The DIP is not a tutorial on existing related parts of the language. 
Copy initialization has been distinct from assignment for a long time in 
both C++ and D languages.



Is an initialisation assignment can use a copy constructor, why can't
a normal assignment implicitly use a copy constructor? (implicit
destruct then copy-construct)


Because assignment and construction were, and are, distinct operation. 
There is no need for the DIP to explain.



And why would

S b = S(a);

not be intended? Sure, it's kind of pointless if a is an S, but if you have
a copy constructor, it makes perfect sense that S(a) would work and would be
pretty bizarre if it didn't, since it's explicitly calling the copy
constructor.


But there's a super explicit `@implicit` thing written right there...
so should we expect that an *explicit* call to the copy constructor is
not allowed? Or maybe it is allowed and `@implicit` is a lie?


The "@implicit" attribute does not preclude explicit calls. Razvan: you 
may want to mention that.



It even works right now if you give S a constructor that takes
an S. It just isn't actually treated as a proper copy constructor at the
moment, since that's currently the postblit constructor's job.


Current language doesn't have `@implicit` written anywhere...


Misunderstanding that I assume has been cleared by now.


Andrei


Re: Copy Constructor DIP

2018-07-12 Thread Andrei Alexandrescu via Digitalmars-d

On 07/10/2018 04:58 PM, Manu wrote:

On Tue, 10 Jul 2018 at 03:50, RazvanN via Digitalmars-d
 wrote:


Hi everyone!

I managed to put together a first draft of the DIP for adding the
copy constructor to the language [1]. If anyone is interested,
please take a look. Suggestions and comments about technical
aspects and wording are all welcome.

Thanks,
RazvanN

[1] https://github.com/dlang/DIPs/pull/129


I feel there's some things missing.

1. Explain the need and reasoning behind `@implicit`.


Razvan: I think it would help to explain that the attribute is necessary 
to avoid changing semantics of existing code. Thanks.



3. In C++, copy constructors and copy assignment operators come in
pairs (which is totally lame!), but we don't see that same pattern
extend here, and it's not clear at all why.


The proposal does not affect or interfere with opAssign in any way.


4. Given the special rules where assignments are lifted to
constructions, I want to know when that occurs (maybe that is already
spec-ed wrt postblit?)


What special rules are you referring to? Thanks.



Re: Copy Constructor DIP

2018-07-12 Thread Andrei Alexandrescu via Digitalmars-d

On 07/11/2018 05:55 AM, Nick Treleaven wrote:

On Tuesday, 10 July 2018 at 10:47:04 UTC, RazvanN wrote:

[1] https://github.com/dlang/DIPs/pull/129


Thanks for making the DIP. I can't get this code to compile (my struct 
has an `int i` field):


static foreach (i, ref field; src.tupleof)
     this.tupleof[i] = field;

Error: constant value src.i cannot be ref

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

Removing `static` works. Otherwise I tried changing `ref` to `alias`:

Error: variable src cannot be read at compile time

But this shorter code seems to work fine:

this.tupleof = src.tupleof;


Odd. Timon, what would be the reason for that error? Razvan, can you 
please look into removing "static" for now. Thanks!


Re: Copy Constructor DIP

2018-07-10 Thread Andrei Alexandrescu via Digitalmars-d

On 07/10/2018 06:52 AM, Guillaume Piolat wrote:

On Tuesday, 10 July 2018 at 10:47:04 UTC, RazvanN wrote:

Hi everyone!

I managed to put together a first draft of the DIP for adding the copy 
constructor to the language [1]. If anyone is interested, please take 
a look. Suggestions and comments about technical aspects and wording 
are all welcome.


Thanks,
RazvanN

[1] https://github.com/dlang/DIPs/pull/129


Does it allow to remove the "T.init must always be valid for structs" rule?


That's not part of this proposal's charter.


Re: std.traits : Select - could it be better?

2018-07-05 Thread Andrei Alexandrescu via Digitalmars-d

On 7/5/18 2:50 PM, SrMordred wrote:

alias U = Select!( isPointer!T, PointerTarget!T, T );

This don´t compile if T are not a pointer;

so you have to do this:

static if( isPointer!T )
     alias U = PointerTarget!T;
else
     alias U = T;

Shouldnt the 'correct' way of Select to work is ignoring the choice that 
was not taken?


I love the idea of Select, but because of this I almost never use it.


mixin("alias U = " ~ Select!(isPointer!T, "PointerTarget!T", "T") ~ ";");

Ehm this is actually not better :o).

Andrei


Re: Phobos begat madness

2018-06-23 Thread Andrei Alexandrescu via Digitalmars-d

On 6/23/18 1:36 AM, Adam D. Ruppe wrote:

On Friday, 22 June 2018 at 22:28:17 UTC, Walter Bright wrote:

That would help, do you want to implement it?


I can't for at last two weeks, I'm about to fly tomorrow... and I'm 
getting married in August too so my life is kinda hectic.


Congratulations, Adam!

Andrei



The Case Against Annotations

2018-06-19 Thread Andrei Alexandrescu via Digitalmars-d
An interesting article. Most of the listed disadvantages of annotations 
are obviated by D's approach.


https://blog.softwaremill.com/the-case-against-annotations-4b2fb170ed67


Re: To the D Foundation Moderators

2018-06-14 Thread Andrei Alexandrescu via Digitalmars-d

On 6/14/18 11:02 AM, Duser wrote:

The problem with the D Foundations' new approach to 'moderating' is:

Who does the moderating?


Thanks for asking. Moderation is done by a small leadership group of 
which Walter and I are part. I won't name other names for the simple 
reason I forgot who the others are.



Who long does it take?


It's done on a best effort basis. Vladimir created a nice automated 
system that only flags a small number of posts for moderation, I'm sure 
he'd be glad to share details.


What exactly are these so called 'moderator' 'filtering', so that others 
cannot see it?


Without complete insight into this new model of moderating posts, then 
this is just a tool for abuse. Anything can be 'moderated'.


In which case, these forums become the D Foundations propaganda machine.


This is not a corporation that needs formal rules lest whatever CEO gets 
on board can abuse position. Also, it's not a mission-driven free speech 
platform where you have defined rights just by posting. That said, the 
sheer notion that Walter or myself would moderate away posts of which 
technical content disagree with is ridiculous. If you're trying to put a 
political spin on this, please leave this community.



Andrei


Re: stride in slices

2018-06-05 Thread Andrei Alexandrescu via Digitalmars-d

On 06/04/2018 07:08 PM, Ethan wrote:

On Monday, 4 June 2018 at 18:11:47 UTC, Steven Schveighoffer wrote:

BTW, do you have cross-module inlining on?


Just to drive this point home.

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

Manually implemented stride and fill with everything forced inline. 
Otherwise, the original code is unchanged.


17 ms, 891 μs, and 6 hnsecs
15 ms, 694 μs, and 1 hnsec
15 ms, 570 μs, and 9 hnsecs

My new stride outperformed std.range stride, and the manual for-loop. 
And, because the third test uses the new stride, it also benefited. But 
interestingly runs every so slightly faster...


BTW I've had this thought for a long time to implement stride with a 
compile-time step... never got around to implementing it. It would 
easily generalize the existing code without too much work. Essentially 
the step would be a template parameter; if that is 0, then use a 
run-time stride. Most of the code works unchanged.


An analysis of dimensional analysis

2018-05-24 Thread Andrei Alexandrescu via Digitalmars-d
...in various languages, including D: 
https://www.reddit.com/r/programming/comments/8lwfis/dimensional_analysis_in_programming_languages/


Re: Ideas for students' summer projects

2018-05-22 Thread Andrei Alexandrescu via Digitalmars-d

On 5/22/18 1:39 PM, jmh530 wrote:

On Tuesday, 22 May 2018 at 16:27:05 UTC, Eduard Staniloiu wrote:

Hello, everyone!

We, at UPB, have initiated D's participation to ROSEdu Summer of Code, 
see http://soc.rosedu.org/2018/.


I will be mentoring a student over the summer and I was wondering if 
you have
any suggestions for a project. If there is a library or feature that 
you would like

just drop an idea.

The proposed idea should be something that can be done in 8-10 weeks, 
though, ideally, we hope that the student/s will continue to 
contribute to the community after the summer ends.


Let the brainstorming begin!


GSOC ideas would obviously be a good place to start.
https://wiki.dlang.org/GSOC_2018_Ideas


We're looking at those, plus any fresh ideas.


Re: Sealed classes - would you want them in D? (v2)

2018-05-21 Thread Andrei Alexandrescu via Digitalmars-d
Hi folks, it looks like at least a few branches of this thread have run 
well past their useful course and into tedious territory.


We don't like to go about killing threads, so we kindly ask that you all 
refrain from posting in this thread going forward.



Thanks much!

Andrei


Re: Of possible interest: fast UTF8 validation

2018-05-17 Thread Andrei Alexandrescu via Digitalmars-d

On 05/17/2018 09:14 AM, Patrick Schluter wrote:
I'm in charge at the European Commission of the biggest translation 
memory in the world.


Impressive! Is that the Europarl?


Re: Benchmark Game

2018-05-17 Thread Andrei Alexandrescu via Digitalmars-d

On 05/17/2018 04:50 AM, Chris wrote:

For what it's worth, I came across this website:

https://benchmarksgame-team.pages.debian.net/benchmarksgame/

D is not there. Anyone interested, if it's worth it?


It would be well worth the effort.


Re: DIP 1011 library alternative

2018-05-17 Thread Andrei Alexandrescu via Digitalmars-d

On 05/15/2018 08:44 PM, Jonathan Marler wrote:

On Tuesday, 15 May 2018 at 21:25:05 UTC, Andrei Alexandrescu wrote:
Hello, I was reviewing again DIP 1011 and investigated a library 
solution. That led to


https://gist.github.com/run-dlang/18845c9df3d73e45c945feaccfebfcdc

It builds on the opening examples in:

https://github.com/dlang/DIPs/blob/master/DIPs/DIP1011.md

I'm displeased at two aspects of the implementation:

* Perfect forwarding is tedious to implement: note that makeDelegate 
hardcodes void as the return type and (int, float) as parameter types. 
Ideally it should accept any parameters that the alias passes.


* Pass-by-alias and overloading interact poorly. Does anyone know how 
to refer by alias to one specific overload?



Thanks,

Andrei


Now that I've had a chance to look the example you've shared, the only 
comment I'd make is that DIP1011 aims to allow applications to create 
"delegate-compatible" functions that don't require generating a wrapper 
function to forward a delegate call to the function at runtime  In this 
example, 2 functions have been defined that take a class and a struct 
pointer as the first argument, however, these function are not ABI 
compatible with the delegate ABI meaning you will have to generate a 
runtime "conversion" function to forward a delegate call to call the 
function.


Affirmative. The important matter here is the number of indirect calls, 
which is not increased; forwarding direct calls are often easy to inline 
and even if not are cheap (subject to the number and size of their 
arguments).


extern(delegate) allows the application to generate the function using 
the delegate ABI in the first place so no "conversion" is necessary. To 
achieve this with a libary solution, you need to modify the function 
definition itself, not just create a wrapper around it.


Affirmative. But that's just stating it. The question is how needed and 
useful that is.


At the least, this feedback prompts for changes the rationale and 
motivation of the DIP. The bulk of the current rationale rests on use 
cases and the disadvantages of inferior workarounds. (The consistency 
with UFCS rewrites argument is weaker but valid, and stays.) The DIP's 
rationale would need to be redone to compare the proposed feature with 
the best known library solution (derived from the proof of concept in 
this thread), and them build an argument that it is needed based on (a) 
remaining disadvantages of the library solution and (b) convenience for 
frequent/intensive use.


We're not rejecting the DIP outright but we point out that it needs 
rework in wake of this new evidence of competing alternatives. Feel free 
to reach out privately for further discussion.



Thanks,

Andrei


Re: Of possible interest: fast UTF8 validation

2018-05-16 Thread Andrei Alexandrescu via Digitalmars-d

On 5/16/18 1:18 PM, Joakim wrote:

On Wednesday, 16 May 2018 at 16:48:28 UTC, Dmitry Olshansky wrote:

On Wednesday, 16 May 2018 at 15:48:09 UTC, Joakim wrote:

On Wednesday, 16 May 2018 at 11:18:54 UTC, Andrei Alexandrescu wrote:
https://www.reddit.com/r/programming/comments/8js69n/validating_utf8_strings_using_as_little_as_07/ 



Sigh, this reminds me of the old quote about people spending a bunch 
of time making more efficient what shouldn't be done at all.


Validating UTF-8 is super common, most text protocols and files these 
days would use it, other would have an option to do so.


I’d like our validateUtf to be fast, since right now we do validation 
every time we decode string. And THAT is slow. Trying to not validate 
on decode means most things should be validated on input...


I think you know what I'm referring to, which is that UTF-8 is a badly 
designed format, not that input validation shouldn't be done.


I find this an interesting minority opinion, at least from the 
perspective of the circles I frequent, where UTF8 is unanimously 
heralded as a great design. Only a couple of weeks ago I saw Dylan 
Beattie give a very entertaining talk on exactly this topic: 
https://dotnext-piter.ru/en/2018/spb/talks/2rioyakmuakcak0euk0ww8/


If you could share some details on why you think UTF8 is badly designed 
and how you believe it could be/have been better, I'd be in your debt!



Andrei


Re: Sealed classes - would you want them in D?

2018-05-16 Thread Andrei Alexandrescu via Digitalmars-d

On 05/16/2018 04:28 AM, meppl wrote:
a pitfall-section about 'private' and 'protected' in 
https://dlang.org/spec/class.html wouldnt hurt.


Yah, improvements to the spec are always welcome and not difficult to 
effect. It's one of the areas in which crowdsourcing would work nicely.




Re: Sealed classes - would you want them in D?

2018-05-16 Thread Andrei Alexandrescu via Digitalmars-d

On 05/16/2018 04:42 AM, Dave Jones wrote:

On Wednesday, 16 May 2018 at 08:20:23 UTC, Uknown wrote:

On Wednesday, 16 May 2018 at 07:53:36 UTC, aliak wrote:

Just checked the rust spec [0]. private in rust => accessible from 
that module and its descendants, which is what package in D is. 
private in D would be to that module only.


[0]: https://doc.rust-lang.org/beta/reference/visibility-and-privacy.html


Dont know if its been mentioned before but in Delphi / Object Pascal 
private is accessible to everything in the same module. Same as D.


This is interesting, thanks for the info.


Re: Of possible interest: fast UTF8 validation

2018-05-16 Thread Andrei Alexandrescu via Digitalmars-d

On 05/16/2018 08:47 AM, Ethan Watson wrote:

On Wednesday, 16 May 2018 at 11:18:54 UTC, Andrei Alexandrescu wrote:
https://www.reddit.com/r/programming/comments/8js69n/validating_utf8_strings_using_as_little_as_07/ 



I re-implemented some common string functionality at Remedy using SSE 
4.2 instructions. Pretty handy. Except we had to turn that code off for 
released products since nowhere near enough people are running SSE 4.2 
capable hardware.


Is it workable to have a runtime-initialized flag that controls using 
SSE vs. conservative?


The code linked doesn't seem to use any instructions newer than SSE2, so 
it's perfectly safe to run on any x64 processor. Could probably be sped 
up with newer SSE instructions if you're only ever running internally on 
hardware you control.


Even better!

Contributions would be very welcome.


Andrei


Of possible interest: fast UTF8 validation

2018-05-16 Thread Andrei Alexandrescu via Digitalmars-d

https://www.reddit.com/r/programming/comments/8js69n/validating_utf8_strings_using_as_little_as_07/


DIP 1011 library alternative

2018-05-15 Thread Andrei Alexandrescu via Digitalmars-d
Hello, I was reviewing again DIP 1011 and investigated a library 
solution. That led to


https://gist.github.com/run-dlang/18845c9df3d73e45c945feaccfebfcdc

It builds on the opening examples in:

https://github.com/dlang/DIPs/blob/master/DIPs/DIP1011.md

I'm displeased at two aspects of the implementation:

* Perfect forwarding is tedious to implement: note that makeDelegate 
hardcodes void as the return type and (int, float) as parameter types. 
Ideally it should accept any parameters that the alias passes.


* Pass-by-alias and overloading interact poorly. Does anyone know how to 
refer by alias to one specific overload?



Thanks,

Andrei


Re: andrei - better breakdown of statistics for downloads by region, OS, kind of site (academic/large corporate/large financial/etc)

2018-05-08 Thread Andrei Alexandrescu via Digitalmars-d

On 05/08/2018 03:54 AM, Suliman wrote:

Stat out of date... Plz update it.


Done. Keep in mind those stats are noisy. They need to be improved, but 
couldn't find anyone to work on that.


I have talked to a consultant, he was very successful with showing 
near-real-time statistics about the project and its progress in a 
dashboard that was visible to all project participants. For example he 
had product sales in real time, which I thought was a very nice touch: 
developers could see the result of their work making money instantly. He 
told me that that's a classic method used in Agile methodology.


A very good project for us would be a near-real-time dashboard 
displaying downloads, site visits, github activity, and such. I know I'd 
keep such a page opened at all times.



Andrei



Re: Lightening cable?

2018-04-30 Thread Andrei Alexandrescu via Digitalmars-d

On 4/30/18 3:30 PM, Luís Marques wrote:
Hi. Can anyone staying at the conference hotel lend me an iPhone 
charging cable? Even just for a few minutes would help. I forgot mine :(


Me too, sigh...


Re: Space before parens in all function definitions

2018-04-10 Thread Andrei Alexandrescu via Digitalmars-d

On 04/09/2018 02:50 PM, Seb wrote:

On Monday, 9 April 2018 at 16:22:15 UTC, Andrei Alexandrescu wrote:

On 04/07/2018 07:01 AM, Sönke Ludwig wrote:

Am 07.04.2018 um 04:23 schrieb Andrei Alexandrescu:

Why is there a space before "(" in our /library/ docs?

https://dlang.org/library/std/stdio/file.tmpfile.html

The paren here has role similar to that in mathematics, not literary.


Thanks,

Andrei


Has been a regression during the diet-ng transition. Fix in DDOX:

https://github.com/rejectedsoftware/ddox/pull/203


Thanks! When will that be live?


Should happen soon -> https://github.com/dlang/dlang.org/pull/2335


Thanks folks!


Re: Space before parens in all function definitions

2018-04-09 Thread Andrei Alexandrescu via Digitalmars-d

On 04/07/2018 07:01 AM, Sönke Ludwig wrote:

Am 07.04.2018 um 04:23 schrieb Andrei Alexandrescu:

Why is there a space before "(" in our /library/ docs?

https://dlang.org/library/std/stdio/file.tmpfile.html

The paren here has role similar to that in mathematics, not literary.


Thanks,

Andrei


Has been a regression during the diet-ng transition. Fix in DDOX:

https://github.com/rejectedsoftware/ddox/pull/203


Thanks! When will that be live?


Space before parens in all function definitions

2018-04-06 Thread Andrei Alexandrescu via Digitalmars-d

Why is there a space before "(" in our /library/ docs?

https://dlang.org/library/std/stdio/file.tmpfile.html

The paren here has role similar to that in mathematics, not literary.


Thanks,

Andrei


[OT] Re: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, [your code here]

2018-04-06 Thread Andrei Alexandrescu via Digitalmars-d

On 04/06/2018 10:03 AM, Abdulhaq wrote:

On Friday, 6 April 2018 at 13:10:07 UTC, jason wrote:

what is this?


It's a perl program that converts D code into APL


Genius.


Re: DIP in making: ProtoObject

2018-04-04 Thread Andrei Alexandrescu via Digitalmars-d

On 04/04/2018 09:18 AM, 12345swordy wrote:

On Wednesday, 4 April 2018 at 04:49:10 UTC, Andrei Alexandrescu wrote:
I'm working on a simple older idea to get it out of the way in 
preparation for the more difficult DIPs to come:


https://github.com/andralex/DIPs/blob/ProtoObject/DIPs/DIP.md

This is not officially reviewable yet, but conveys the gist and could 
use some early feedback. Any insight will be appreciated.



Thanks,

Andrei


No attempts to make class deallocation @nogc attribute friendly? This is 
a major PIA for me. The current attempts at this involve various 
workarounds (See automem library for example), which even then does not 
solve all the problems it currently have.


Can you please give more detail on that? You mean the destructor of 
Object is automatically generated with a bad signature?


PR duty

2018-04-03 Thread Andrei Alexandrescu via Digitalmars-d

Hi folks, I was thinking of the following.

To keep the PR queue trim and in good shape, we'd need at least one 
full-time engineer minding it. I've done that occasionally, and the 
queue size got shorter, but I couldn't do much else during that time.


I was thinking, we can't afford a full-time engineer, and even if we 
did, we'd probably have other important matters for that engineer as 
well. However, what we can afford - and indeed already benefit from - is 
a quantum of time from each of many volunteers. By organizing that time 
better we may be able to get more output. Here's what I'm thinking.


Let's define a "PR duty" role that is one week long for each of a pool 
of volunteers. During that week, the person on PR duty focuses on 
minding github queues - merge trivial PRs, ping authors of old PRs, 
email decision makers for specific items in PRs, etc. Then the week ends 
and the role is handed off to the next person in the pool.


A calendar maintained by an impartial person - maybe we can ask Mike - 
would keep track of everything.


The most obvious candidates for PR duty engineers would be the most 
prolific contributors in the respective repositories.


One question would be how many distinct pools/tracks we should have. 
Presumably someone fluent with phobos is not necessarily fluent with 
dmd. So probably we need at least two tracks:


* dmd
* everything else (druntime, phobos, tools, site)

If there are a dozen of us in each pool, each would be on duty one week 
every three months. Even with eight, we'd be on duty a manageable week 
every other month.


Please share your thoughts.


Thanks,

Andrei


DIP in making: ProtoObject

2018-04-03 Thread Andrei Alexandrescu via Digitalmars-d
I'm working on a simple older idea to get it out of the way in 
preparation for the more difficult DIPs to come:


https://github.com/andralex/DIPs/blob/ProtoObject/DIPs/DIP.md

This is not officially reviewable yet, but conveys the gist and could 
use some early feedback. Any insight will be appreciated.



Thanks,

Andrei


Re: D compiles fast, right? Right??

2018-04-03 Thread Andrei Alexandrescu via Digitalmars-d

On 04/03/2018 05:53 PM, bachmeier wrote:

On Tuesday, 3 April 2018 at 21:17:35 UTC, Rubn wrote:
I feel that's probably the case for any comparisons across two 
languages, you are going to have a person that is more knowledgeable 
in one language than another. Mistakes are going to be made, but I 
think it should be blatantly obvious that one language is going to 
compiler slower if it is compiling all the unittests for a library 
compared to one that isn't. That's just blatant bias against D, not a 
mistake from misunderstanding Go.


Yeah, I don't understand that either. Unit tests can be arbitrarily 
large, so no matter how fast the compiler, it would always be possible 
to make it take longer than any other language.


Exactly, which is why I'm insisting this - and not compiler 
benchmarking, let alone idle chattaroo in the forums - is where we need 
to hit. What we have here, ladies and gentlemen, is a high-impact 
preapproved item of great general interest. Shall we start the auction?


Re: Deprecating this(this)

2018-04-03 Thread Andrei Alexandrescu via Digitalmars-d

On 04/03/2018 04:29 PM, ag0aep6g wrote:
But if postblit goes away for other reasons anyway (like the atomic copy 
thing, or another mechanism being simply superior), then there's no 
point in pursuing this, of course.


The DIP will definitely need to make a solid case supporting whatever it 
proposes.


Re: Deprecating this(this)

2018-04-03 Thread Andrei Alexandrescu via Digitalmars-d

On 04/03/2018 04:26 PM, ag0aep6g wrote:

On 04/03/2018 05:13 PM, Steven Schveighoffer wrote:
Unfortunately, I found out that it's not just "pre-filled with some 
values". Member postblits are run before the containing postblit.


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

So this means, the data that is available to the postblit has already 
been processed.


There's a similar situation with constructors: A constructor can call 
another constructor, which can lead to double initialization of fields.


Example:


class C
{
     int x;
     this() immutable
     {
     this(42); /* Initializes x. */
     x = 13; /* Breaking immutable, or ok? */
     }
     this(int x) immutable
     {
     this.x = x;
     }
}



Let's replace "int" with an UDT:

struct S
{
int x = -1;
this(int y) immutable { x = y; }
void opAssign(int) immutable;
}

class C
{
S x;
this() immutable
{
this(42); /* Initializes x. */
x = 13; /* Breaking immutable, or ok? */
}
this(int x) immutable
{
this.x = x;
}
}

This code compiles, and calls the constructor twice for the same object. 
Clearly that shouldn't be allowed to pass. I've submitted 
https://issues.dlang.org/show_bug.cgi?id=18719 - thanks! (The problem 
seems to occur even without immutable, it's endemic to forwarding 
constructors.)


Andre


Re: Deprecating this(this)

2018-04-03 Thread Andrei Alexandrescu via Digitalmars-d

On 04/03/2018 10:21 AM, ag0aep6g wrote:

On Tuesday, 3 April 2018 at 12:52:00 UTC, Andrei Alexandrescu wrote:

On 04/03/2018 07:36 AM, ag0aep6g wrote:
For constructors, we say that the first assignment is actually 
initialization. The compiler might or might not put the .init value 
down before calling the constructor. Doesn't matter, because the 
constructor will overwrite it anyway, and nothing of value is lost.


What happens in fact is you are guaranteed the .init value is there. 
Much later, well after semantic checking, the backend optimizer 
removes dead assignments on primitive data.


So constructors, including const/immutable ones, basically work the same 
as postblit already? You get an object pre-filled with some values, and 
then you can "initialize" the fields some more if you want.


Well... not really. This is because .init is really an inert state - 
null indirections, no state allocated etc. Makes typechecking easy, and 
calling constructor on top of .init is what happens already. In 
contrast, the postblit situash is very different - the fields already 
contain "interesting" data, allocated resources etc. Calling a 
constructor on top of that is not defined.


Re: Deprecating this(this)

2018-04-03 Thread Andrei Alexandrescu via Digitalmars-d

On 04/03/2018 07:36 AM, ag0aep6g wrote:
For constructors, we say that the first assignment is actually 
initialization. The compiler might or might not put the .init value down 
before calling the constructor. Doesn't matter, because the constructor 
will overwrite it anyway, and nothing of value is lost.


What happens in fact is you are guaranteed the .init value is there. 
Much later, well after semantic checking, the backend optimizer removes 
dead assignments on primitive data.


We can do the same with the postblit function: First assignment is 
actually initialization. When the compiler sees that the postblit 
function initializes a field, it can skip that field when blitting.


What if the user code reads the value?

* Often people use this(this) to bump a reference count a la "if (pcnt) 
++*pcnt;"


* People may pass the field by reference to an opaque function. What 
type does the field have?


But 
it can also just blit the whole struct, because it doesn't matter if the 
value just gets overwritten.


In other words, a postblit function can either:

1) use the blitted value as a starting point, like a constructor can use 
the .init value, or it can

2) initialize the field itself.

Would make perfect sense to me.


In case (1) things can get quite confusing. Inside a postblit,

field = TypeOfField(100);

is a call to the constructor, whereas

field = TypeOfField(field.x + 100);

is a call to the assignment operator.


Andrei


Re: Deprecating this(this)

2018-04-03 Thread Andrei Alexandrescu via Digitalmars-d

On 04/02/2018 02:47 PM, Marco Leise wrote:

Am Mon, 2 Apr 2018 11:57:55 -0400
schrieb Andrei Alexandrescu :


Problem is we don't have head-mutable in the language. Yes, for built-in
slices the mechanism is simple - just change qualifier(T[]) to
qualifier(T)[]. For a struct S, there is no way to convert from
qualifier(S) to tailqualifier(S).

I plan to attack this directly in the DIP - provide a way for structs to
express "here's what implicit conversion should be applied when doing
template matching".

Andrei


You are hitting a prominent type system flaw here. What may
look like a hurdle on the path to fix this(this) is also at
the core of getting "shared" into a good shape and probably
affects how we will discuss "immutable destructors" and their
kin in the future. The question is "How transitive is a
qualifier when we strip it top-level on an aggregate?"


Roger. My hope is to solve that for primitive types, then use that to 
typecheck constructors and destructors, then use the signatures of 
(typechecked) constructors and destructors to address composition. 
Ideally we'd get away without defining another kind of qualifier - 
@tail(const) or whatever. That would complicate the language a great deal.



Andrei



Re: What's up with ddoc on dlang.org?

2018-04-03 Thread Andrei Alexandrescu via Digitalmars-d

On 04/02/2018 06:13 PM, ag0aep6g wrote:

On 04/02/2018 11:36 PM, Steven Schveighoffer wrote:
Was just perusing dlang's library documentation, and here is the 
description it has for std.experimental.allocator.make:


Dynamically allocates (using ) and then creates in the memory 
allocated an object of type T, using (if any) for its initialization. 
Initialization occurs in the memory allocated and is otherwise 
semantically the same as T(). (Note that using .!(T[]) creates a 
pointer to an (empty) array of Ts, not an array. To use an allocator 
to allocate and initialize an array, use .makeArray!T described below.)


Seems there's a few things missing here? What's happening?


Looks like a mistake that happened with this change:
https://dlang.org/changelog/2.079.0.html#fix18361

PR to fix it:
https://github.com/dlang/dlang.org/pull/2326


Thanks, I'd just found that too.


Re: Deprecating this(this)

2018-04-02 Thread Andrei Alexandrescu via Digitalmars-d

On 04/02/2018 12:53 PM, Steven Schveighoffer wrote:

On 4/2/18 11:57 AM, Andrei Alexandrescu wrote:

On 04/02/2018 10:59 AM, ag0aep6g wrote:


That wouldn't be possible if `innocent` were only head-mutable in the 
postblit function, instead of fully mutable as it is currently (bug).


`innocent` would be typed as `immutable(int)[]`, and you could not 
assign it to the fully mutable `sneaky`.


Problem is we don't have head-mutable in the language.


This is the wrong way to look at it. Head mutable is a specialized 
concept already implemented in constructors:


struct S
{
    int x;
    int *ptr;
    int *ptr2;
    this(int xval, immutable int *ptrval, int *cantuse) immutable
    {
   x = xval; // ok, head mutable
   //x = x + 1; // error, immutable field initialized multiple times
   ptr = ptrval; // ok
   // ptr2 = cantuse; // error, can't assign mutable to immutable
    }
}


I've asked Razvan to document how immutable constructors are exactly 
typechecked. My understanding is that they don't rely on some form of 
internal "head const" but instead on simple data flow - the first 
assignment counts as a constructor call. Consider the following example, 
which contains opaque methods instead of built-ins:


struct S
{
int[] payload;
S* another;
this(int) immutable;
}

struct HasS
{
S member;
this(int  x) immutable
{
member = immutable S(1);
}
}

This fails to link; the assignment is just a call to the (declared but 
undefined) constructor.


Such behavior is nice and easy to generalize to copy construction.

We could have the same mechanism for postblit. Essentially, you should 
be able to assign immutable fields once, but they shouldn't lose their 
const protections (note the cantuse example).


Yes, with the distinction that is not "assign" but really "construction 
with assignment syntax".


As was mentioned, because postblit on an immutable (or const) is ONLY 
allowed for new data, there shouldn't be an issue.


The problem with postblit is there's "double construction", one done by 
the compiler, after which the user may want to assign something else. 
That's more difficult to typecheck than direct initialization.



Andrei



std/typecons.d(2010:36)[warn]: Left side of logical or is identical to right side.

2018-04-02 Thread Andrei Alexandrescu via Digitalmars-d

I'm seeing this in the CI runs, but the line is actually not in error:

https://github.com/dlang/phobos/blob/master/std/typecons.d#L2010

Where would be the problem?


Andrei


Re: Deprecating this(this)

2018-04-02 Thread Andrei Alexandrescu via Digitalmars-d

On 04/02/2018 12:14 PM, Paolo Invernizzi wrote:

On Monday, 2 April 2018 at 16:00:11 UTC, bachmeier wrote:

On Monday, 2 April 2018 at 15:30:23 UTC, Paolo Invernizzi wrote:



Andrei wrote in the message



I am looking for folks to assist me in creating a DIP for that.
There will be a _lot_ of work involved, so don't take it lightly.



Andrei is asking others to write a DIP to formalize a decision




There's not even an attempt made to pretend there's symmetry. The only 
way for Manu (and basically anyone else) to propose a change is to 
write a DIP. Andrei won't even participate in discussions without a 
DIP. That's probably a good idea. What's not a good idea is to make 
unilateral decisions about major breaking changes, posting in the 
forum, and then asking others to write the DIP. That's corporate 
software development, and it's very discouraging to potential 
contributors.


I think you are plain wrong on this: the 'P' in a DIP stands for 
Proposal, so any decision is not taken yet. And I'll bet:


- Andrei will be the main author or he will partecipate in the writing.
- the DIP will follow the usual proceeding, exactly like the others.


Affirmative. No need to discuss this further, it's a simple 
misunderstanding. I'd agree with bachmeier if his perception was correct.


Re: D compiles fast, right? Right??

2018-04-02 Thread Andrei Alexandrescu via Digitalmars-d

On 04/02/2018 12:22 PM, H. S. Teoh wrote:

Lately this has been mentioned more and more frequently.  So what's the
status on this?  Are we going to move forward with making it so that
-unittest only applies to modules supplied on the command-line?

Has there been an investigation into how __traits(getUnitTests) could be
made to work in spite of this change?


Walter and I are willing to go with the change assuming no showstopper 
presents itself, but we don't have time budgeted for it. So it needs a 
strong champion.


Re: D compiles fast, right? Right??

2018-04-02 Thread Andrei Alexandrescu via Digitalmars-d

On 04/02/2018 08:35 AM, Atila Neves wrote:

On Sunday, 1 April 2018 at 02:40:26 UTC, Walter Bright wrote:

On 3/30/2018 1:17 PM, Andrei Alexandrescu wrote:

Could be faster.


It's been a fair amount of time since somebody has done profiling of 
dmd. It needs to be done. There's probably plenty of low hanging 
fruit. Speculating about why it is slow is pointless without data.


I profiled it as soon as I had the numbers. I didn't bother to mention 
it because I thought I'd just work on making dmd faster instead.


I seem to be the one who feels the most pain by this, it'd be silly of 
me to expect anyone else to work on it.


A large and obvious time sink is that unittests in library code are 
built when user code is to be unittested. I'd recommend doing this 
before any other optimization.


Re: Deprecating this(this)

2018-04-02 Thread Andrei Alexandrescu via Digitalmars-d

On 04/02/2018 12:00 PM, bachmeier wrote:

On Monday, 2 April 2018 at 15:30:23 UTC, Paolo Invernizzi wrote:


Andrei wrote in the message


I am looking for folks to assist me in creating a DIP for that.
There will be a _lot_ of work involved, so don't take it lightly.


So, let's keep the discussion factual. I'm pretty sure that every 
aspect will be taken in account and pondered prior to a decision.


I'm +1 on major breaking changes if they drive D towards a better shape.


Andrei is asking others to write a DIP to formalize a decision he has 
already made. Yet when Manu posts here, he responds:


Apologies for the misunderstanding. I'll be the first author of the DIP 
and plan to dedicate a lot of time to it. I was just asking for others 
to join me in this important and urgent effort.


Andrei


Re: Deprecating this(this)

2018-04-02 Thread Andrei Alexandrescu via Digitalmars-d

On 04/02/2018 10:42 AM, ag0aep6g wrote:

On Monday, 2 April 2018 at 14:01:22 UTC, Kagamin wrote:

On Sunday, 1 April 2018 at 14:31:24 UTC, Andrei Alexandrescu wrote:
1. For immutable objects, typechecking in the presence of successive 
modifications of data (first assignment by the compiler, then 
modification by the user) is very difficult if not impossible. I 
don't know how to do it. The single initialization model (raw/cooked) 
used currently in regular immutable constructors works reasonably 
well and is robust.


Do the same as in const constructor.


The way it works in a const constructor is that `this.foo = bar;` is 
considered initialization, not assignment.


Affirmative. First assignment is a call to the member's constructor. We 
typecheck that reasonably well already in qualified constructors, and 
it's the most promising approach for the DIP.


In a postblit function, we can't say it's initialization, because the 
field already has a value that can't be ignored.


Affirmative. That's what makes it so darn difficult to typecheck. If we 
don't let the compiler do the initial blitting (and instead start with 
T.init), the copy ctor is typechecked exactly like the regular ctor.



Andrei


Re: Deprecating this(this)

2018-04-02 Thread Andrei Alexandrescu via Digitalmars-d

On 04/02/2018 10:59 AM, ag0aep6g wrote:


That wouldn't be possible if `innocent` were only head-mutable in the 
postblit function, instead of fully mutable as it is currently (bug).


`innocent` would be typed as `immutable(int)[]`, and you could not 
assign it to the fully mutable `sneaky`.


Problem is we don't have head-mutable in the language. Yes, for built-in 
slices the mechanism is simple - just change qualifier(T[]) to 
qualifier(T)[]. For a struct S, there is no way to convert from 
qualifier(S) to tailqualifier(S).


I plan to attack this directly in the DIP - provide a way for structs to 
express "here's what implicit conversion should be applied when doing 
template matching".


Andrei


Re: Deprecating this(this)

2018-04-02 Thread Andrei Alexandrescu via Digitalmars-d

On 4/2/18 4:04 AM, Shachar Shemesh wrote:

On 02/04/18 10:45, Jonathan M Davis wrote:
Honestly, I think at this point pure is easier to understand if you 
think of

it as @noglobal and don't think about functional purity at all.


That's fine. My point was that the only optimizations possible are 
possible on strictly pure functions (the immutable cast one included). 
Weakly pure functions add nothing.


But merely having them around means that when I annotate a function with 
"pure", I do not promise any guarantees that the compiler can actually 
use to perform optimizations.


Shachar


This is a good article motivating the relaxed purity model we have: 
http://klickverbot.at/blog/2012/05/purity-in-d/


Re: rvalues -> ref (yup... again!)

2018-04-01 Thread Andrei Alexandrescu via Digitalmars-d

On 3/28/18 7:50 AM, Timon Gehr wrote:
"The proposal could be amended to accept mutable ref's depending on the 
value-judgement balancing these 2 use cases. Sticking with const 
requires no such value judgement to be made at this time, and it's much 
easier to relax the spec in the future with emergence of evidence to do 
so."


Just get it right the first time. "const" is a serious API restriction, 
and it shouldn't be forced on anyone, even intermittently until they 
figure out that it is too restrictive (as well as viral).


A great way to move things forward here, Timon, is to write a pull 
request against the DIP with motivating text and examples.


Re: Deprecating this(this)

2018-04-01 Thread Andrei Alexandrescu via Digitalmars-d

On 4/1/18 10:59 AM, Nicholas Wilson wrote:

On Sunday, 1 April 2018 at 14:31:24 UTC, Andrei Alexandrescu wrote:
There's a mix of fundamental flaws and bugs. I'll get to the flaws in 
a second. About the bugs: people have altered their code in various 
ways to work with the bizarre semantics of this(this). Now, if we fix 
various bugs in this(this) by virtually redefining it, then we'll 
break a lot of code in a lot of ways. To wit, we fixed a small issue 
and it already created problems: 
https://github.com/dlang/dmd/pull/8032. That didn't contribute to the 
decision but is quite illustrative.


I found two fundamental flaws with this(this):

1. For immutable objects, typechecking in the presence of successive 
modifications of data (first assignment by the compiler, then 
modification by the user) is very difficult if not impossible. I don't 
know how to do it. The single initialization model (raw/cooked) used 
currently in regular immutable constructors works reasonably well and 
is robust.


2. For shared objects, the part done by the compiler and the part done 
by this(this) should be synchronized together. This makes it 
impossible for the user to e.g. define a struct that gets copied 
atomically.




See my other reply: but why is it necessary to consider the blit 
logically distinct from the postblit w.r.t to program flow observability?


for 1. consider
immutable foo = ...;
immutable bar = foo;
to be
immutable foo = ...;
immutable bar = () {mutable _ = bitcopy(foo); _.__postblit(); return _;}();


Negative. The problem is typechecking postblit itself, not its invocation.

for 2. you would have to synchronize anyway for shared, it makes no 
difference.


Negative. Consider:

shared struct Point
{
private long x, y, z;
private Mutex mutex;
...
}

Task: define the copy primitive of Point so atomically copy x, y, and z 
using mutex. The problem is, the compiler will memcpy the three longs 
non-atomically before the user even gets a crack at intercepting the 
operation.


There'd be an additional issue - this(this) is non-templated, which 
requires combinatorial additions when qualifiers are present on the 
source or destination side.


(Perhaps this is what you're referring to, but all you have said so far 
is "this doesn't work and we need to fix it") the post blit is surely 
like a destructor: there's only one way to do it, irrespective of the 
attributes, especially of the intermediate is considered mutable until 
the end of post blit, like static module constructors initialising 
global immutables.


Negative. Ignoring qualifiers during copying opens holes in the type 
system the size of China. Or at least Australia as it were :o). Consider:


int[] sneaky;
struct A
{
private int[] innocent;
this(this)
{
sneaky = innocent;
}
}
void main()
{
immutable a = A([1, 2, 3]);
auto b = a;
sneaky[1] = 42; // oops
import std.stdio;
writeln(a.innocent); // ops
}

Sadly this (and many similar ones) compiles and runs warning-free on 
today's compiler. We really need to close this loop, like, five years ago.


I agree that we should fix any type checking bugs that may be present, 
and that we should strive to not make the same mistake twice, however I 
wouldn't call either of the above cases a showstopper. You will need to 
show more of what is broken and why it is broken given the expected 
breakage.


Such discussions will be indeed present in the DIP.


Andrei


Re: __has_side_effects

2018-04-01 Thread Andrei Alexandrescu via Digitalmars-d

On 4/1/18 9:39 AM, Uknown wrote:

On Sunday, 1 April 2018 at 10:23:40 UTC, Andrei Alexandrescu wrote:

On 4/1/18 2:22 AM, Uknown wrote:

[...]


That's a great initiative, and a worthy trait for the stdlib. I think 
you'd have an easier time if you reasoned from the other end. A 
function is strongly pure if all of the following are true:


[...]


I got a working implementation that satisfies your requirements in about 
60 lines.

I will make a Pull Request as soon as I write the Docs and unittests.

Here's the implementation: https://run.dlang.io/is/kVpv36


Terrific, thanks!!


Re: __has_side_effects

2018-04-01 Thread Andrei Alexandrescu via Digitalmars-d

On 4/1/18 9:46 AM, Jonathan M Davis wrote:

In principle, a function which has const parameters could be treated as
strongly pure if it's given immutable arguments


I want to give coders leeway to cheat on that. I'll explain later 
(allocators).


Re: Deprecating this(this)

2018-04-01 Thread Andrei Alexandrescu via Digitalmars-d

On 4/1/18 9:37 AM, Jonathan M Davis wrote:

One issue is that postblit constructors fundamentally don't work with const.


Actually they do...


Re: Deprecating this(this)

2018-04-01 Thread Andrei Alexandrescu via Digitalmars-d

On 4/1/18 8:55 AM, ag0aep6g wrote:

On 04/01/2018 03:08 AM, Andrei Alexandrescu wrote:

On 3/31/18 8:32 PM, H. S. Teoh wrote:

[...]

What exactly is it about this(this) that blocks us from doing that?


See the updated docs. Too many bugs in design and implementation.


Removing this(this) is going to be a huge breaking change far bigger
than, say, removing autodecoding ever will be.


We're not removing it as much as evolving it: we define an alternate 
copying mechanism, and once that is in tip-top shape, we deprecate 
this(this).


Is there a fundamental flaw in the postblit idea, or are you just going 
to give postblit a new syntax, and try to avoid all the issues that 
`this(this)` currently has?


If there's a fundamental flaw, I'd be interested in what it is. I can't 
make it out in your additions to the spec, if it's in there. I can see 
that `this(this)` is  a mess, but it also looks like a lot could be 
fixed. For example, how it interacts with const/immutable is ridiculous, 
but that could probably be fixed.


If you're just going for a clean slate, I can see the appeal. You avoid 
dealing with the hard breakage that fixing `this(this)` would most 
probably bring.


There's a mix of fundamental flaws and bugs. I'll get to the flaws in a 
second. About the bugs: people have altered their code in various ways 
to work with the bizarre semantics of this(this). Now, if we fix various 
bugs in this(this) by virtually redefining it, then we'll break a lot of 
code in a lot of ways. To wit, we fixed a small issue and it already 
created problems: https://github.com/dlang/dmd/pull/8032. That didn't 
contribute to the decision but is quite illustrative.


I found two fundamental flaws with this(this):

1. For immutable objects, typechecking in the presence of successive 
modifications of data (first assignment by the compiler, then 
modification by the user) is very difficult if not impossible. I don't 
know how to do it. The single initialization model (raw/cooked) used 
currently in regular immutable constructors works reasonably well and is 
robust.


2. For shared objects, the part done by the compiler and the part done 
by this(this) should be synchronized together. This makes it impossible 
for the user to e.g. define a struct that gets copied atomically.


There'd be an additional issue - this(this) is non-templated, which 
requires combinatorial additions when qualifiers are present on the 
source or destination side.


Please note that fixing one or two of these issues doesn't make 
this(this) viable - I'm mentioning various issues, each of which is a 
showstopper. Nevertheless knowing them is necessary so we don't make the 
same mistake again!



Andrei


Re: Deprecating this(this)

2018-04-01 Thread Andrei Alexandrescu via Digitalmars-d

On 4/1/18 6:04 AM, Johannes Loher wrote:

This seems really sudden, april fool's joke? Not really sure, as there
are real problems with this(this)...


I'm glad I've sent it yesterday then at least in my time zone :o).

This looks sudden but isn't. Eduard and I have been blocked by this 
problem seriously whilst working on the collections library.



Andrei


Re: __has_side_effects

2018-04-01 Thread Andrei Alexandrescu via Digitalmars-d

On 4/1/18 2:22 AM, Uknown wrote:

On Sunday, 1 April 2018 at 05:27:38 UTC, Uknown wrote:

[...]

I knew I was missing something. Fixed it, thanks

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


Sorry for the spam, but I also managed to miss `immutable`, `const` and 
when T has mutable indirections


Final version that I'm sure covers all the cases:

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


That's a great initiative, and a worthy trait for the stdlib. I think 
you'd have an easier time if you reasoned from the other end. A function 
is strongly pure if all of the following are true:


* Each parameter:
  - is immutable, OR
  - can be converted automatically to immutable (i.e. has no mutable 
indirections) AND is passed by value

* The return type:
  - is immutable, OR
  - can be converted automatically to immutable

(We don't want to give const this much power yet for other reasons.)

The template should support taking the function name as a string, too, 
and the parameter types so as to easily distinguish across overloads.


This would be a great addition to std.traits. Once we have it, we'll 
have a precise unified definition of strongly pure across the language 
spec and the stdlib definition. Please follow up, thanks!



Andrei


Re: Deprecating this(this)

2018-03-31 Thread Andrei Alexandrescu via Digitalmars-d

On 3/31/18 8:32 PM, H. S. Teoh wrote:

On Sat, Mar 31, 2018 at 07:38:06PM -0400, Andrei Alexandrescu via Digitalmars-d 
wrote:
[...]

Once we have that, we can encapsulate desirable abstractions (such as
@nogc safe collections that work in pure code), regardless of how
difficult their implementations might be. It seems that currently
this(this) does not allow us to do that.


What exactly is it about this(this) that blocks us from doing that?


See the updated docs. Too many bugs in design and implementation.


Removing this(this) is going to be a huge breaking change far bigger
than, say, removing autodecoding ever will be.


We're not removing it as much as evolving it: we define an alternate 
copying mechanism, and once that is in tip-top shape, we deprecate 
this(this).



A lot of us here have essentially given up on const except for a few
very narrow cases.  The transitive nature of const makes it extremely
difficult to work with in the general case, even though the simplest use
cases are workable.


Immutable is where it's at, in terms of usefulness. Const is a mere 
servant of it (and of mutable).



One of the biggest stumbling blocks is that whenever ranges are
involved, const is practically out of the question, because even though
it can be made to work for most cases, there will almost always be that
one pathological case where it's impossible / too hard to work around,
and that ruins it for everything else, so that it's much simpler to just
avoid it altogether.


Yah, the DIP might address that, too. Consider:

void fun(R)(R arr)
{
pragma(msg, typeof(arr));
}
void main()
{
immutable(int[]) arr = [ 1, 2, 3 ];
pragma(msg, typeof(arr));
fun(arr);
}

The program prints during compilation:

immutable(int[])
immutable(int)[]

Interesting! So the type of the array changes during template matching, 
which is an exception to the rule that templates always glom to the 
exact type passed.


This is a hack introduced in the compiler in response to the issues you 
mention. But we don't need hacks and special casing - we need a means 
for types to say "here's what needs to happen when a template parameter 
is matched against this type".


So the DIP would address manipulating qualified ranges as a perk.


The one nagging question I've been having about pure is: how much are we
actually taking advantage of the guarantees provided by pure?


Very little, but that doesn't matter. The problem is it's 
underspecified. So now it's like a vague threat - whenever we mess with 
fear somebody comes asking, but what about an aggressive compiler doing 
some unexpected optimizations based on such and such interpretation?


We need to lock pure down.


Andrei


  1   2   3   4   5   6   7   8   9   10   >