www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - TLBB: The Last Big Breakage

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
D1's approach to multithreading was wanting. D2 executed a big departure 
from that with the shared qualifier and the default-thread-local 
approach to data.

We think this is a win, but D2 inherited a lot of D1's thread-related 
behavior by default, and some of the rules introduced by TDPL 
(http://goo.gl/9gtH0g) remained in the "I have a dream" stage.

Fixing that has not gained focus until recently, when e.g. 
https://github.com/D-Programming-Language/dmd/pull/3067 has come about. 
There is other more stringent control of shared members, e.g. 
"synchronized" is all or none, "synchronized" only makes direct member 
variables unshared, and more.

This will statically break code. It will refuse to compile code that is 
incorrect, but also plenty of code that is correct; the compiler will 
demand extra guarantees from user code, be they in the form of casts and 
stated assumptions.

I believe this is a bridge we do need to cross. One question is how we 
go about it: all at once, or gradually?


Andrei
Mar 15 2014
next sibling parent Daniel Kozak <kozzi11 gmail.com> writes:
--047d7bb03d387415f804f4b1d335
Content-Type: text/plain; charset=ISO-8859-1

ASAP please.
Dne 16. 3. 2014 5:10 "Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org>
napsal(a):

 D1's approach to multithreading was wanting. D2 executed a big departure
 from that with the shared qualifier and the default-thread-local approach
 to data.

 We think this is a win, but D2 inherited a lot of D1's thread-related
 behavior by default, and some of the rules introduced by TDPL (
 http://goo.gl/9gtH0g) remained in the "I have a dream" stage.

 Fixing that has not gained focus until recently, when e.g.
 https://github.com/D-Programming-Language/dmd/pull/3067 has come about.
 There is other more stringent control of shared members, e.g.
 "synchronized" is all or none, "synchronized" only makes direct member
 variables unshared, and more.

 This will statically break code. It will refuse to compile code that is
 incorrect, but also plenty of code that is correct; the compiler will
 demand extra guarantees from user code, be they in the form of casts and
 stated assumptions.

 I believe this is a bridge we do need to cross. One question is how we go
 about it: all at once, or gradually?


 Andrei

--047d7bb03d387415f804f4b1d335 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <p dir=3D"ltr">ASAP please.</p> <div class=3D"gmail_quote">Dne 16. 3. 2014 5:10 &quot;Andrei Alexandrescu&q= uot; &lt;<a href=3D"mailto:SeeWebsiteForEmail erdani.org">SeeWebsiteForEmai= l erdani.org</a>&gt; napsal(a):<br type=3D"attribution"><blockquote class= =3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd= ing-left:1ex"> D1&#39;s approach to multithreading was wanting. D2 executed a big departur= e from that with the shared qualifier and the default-thread-local approach= to data.<br> <br> We think this is a win, but D2 inherited a lot of D1&#39;s thread-related b= ehavior by default, and some of the rules introduced by TDPL (<a href=3D"ht= tp://goo.gl/9gtH0g" target=3D"_blank">http://goo.gl/9gtH0g</a>) remained in= the &quot;I have a dream&quot; stage.<br> <br> Fixing that has not gained focus until recently, when e.g. <a href=3D"https= ://github.com/D-Programming-Language/dmd/pull/3067" target=3D"_blank">https= ://github.com/D-<u></u>Programming-Language/dmd/pull/<u></u>3067</a> has co= me about. There is other more stringent control of shared members, e.g. &qu= ot;synchronized&quot; is all or none, &quot;synchronized&quot; only makes d= irect member variables unshared, and more.<br> <br> This will statically break code. It will refuse to compile code that is inc= orrect, but also plenty of code that is correct; the compiler will demand e= xtra guarantees from user code, be they in the form of casts and stated ass= umptions.<br> <br> I believe this is a bridge we do need to cross. One question is how we go a= bout it: all at once, or gradually?<br> <br> <br> Andrei<br> <br> </blockquote></div> --047d7bb03d387415f804f4b1d335--
Mar 15 2014
prev sibling next sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Sunday, 16 March 2014 at 04:08:15 UTC, Andrei Alexandrescu 
wrote:
 D1's approach to multithreading was wanting. D2 executed a big 
 departure from that with the shared qualifier and the 
 default-thread-local approach to data.

 We think this is a win, but D2 inherited a lot of D1's 
 thread-related behavior by default, and some of the rules 
 introduced by TDPL (http://goo.gl/9gtH0g) remained in the "I 
 have a dream" stage.

 Fixing that has not gained focus until recently, when e.g. 
 https://github.com/D-Programming-Language/dmd/pull/3067 has 
 come about. There is other more stringent control of shared 
 members, e.g. "synchronized" is all or none, "synchronized" 
 only makes direct member variables unshared, and more.

 This will statically break code. It will refuse to compile code 
 that is incorrect, but also plenty of code that is correct; the 
 compiler will demand extra guarantees from user code, be they 
 in the form of casts and stated assumptions.

 I believe this is a bridge we do need to cross. One question is 
 how we go about it: all at once, or gradually?


 Andrei

We should probably relax the restriction. synchronized classes can have public fields, but they can't be accessed on shared instances. That way no code is broken when shared isn't used. That should dramatically decrease the difficulty of introducing the change, and that doesn't make the construct any less safe. Or expressed as simpler rule: when a synchronized class is shared, public field become protected.
Mar 15 2014
prev sibling next sibling parent Russel Winder <russel winder.org.uk> writes:
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Sat, 2014-03-15 at 21:08 -0700, Andrei Alexandrescu wrote:
[=E2=80=A6]
 I believe this is a bridge we do need to cross. One question is how we=

 go about it: all at once, or gradually?

Given that it is a breaking change, the sooner the better and as much of it at once as possible. Perhaps changing the numbering system to loose the leading insignificant 0 as well. If D is to get into the "no breaking change during minor releases and bugfix releases", then all the breaking changes to Dv2 need to be done now if they are to happen to Dv2, otherwise they have to wait for Dv3. Java is the example of the mess that happens when you commit to no breaking changes. It is hugely irritating for "early adopter" types. Once the "if it ain't broke don't touch it" types get involved evolution becomes a Java like activity :-( --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Mar 16 2014
prev sibling next sibling parent Michel Fortin <michel.fortin michelf.ca> writes:
On 2014-03-16 04:08:18 +0000, Andrei Alexandrescu 
<SeeWebsiteForEmail erdani.org> said:

 Fixing that has not gained focus until recently, when e.g. 
 https://github.com/D-Programming-Language/dmd/pull/3067 has come about.

Synchronized classes should be trashed. The whole concept is very prone to mistakes that could cause deadlocks and offers no simple path to fix those errors once they're found. The concept encourage people to keep locks longer than needed to access the data. For one thing is bad for performance. It also makes callbacks happen while the lock is held, which has a potential for deadlock if the callback locks something else (through synchronized or other means). Sure, there are safe ways to implement a synchronized class: you have to use it solely as a data holder that does nothing else than store a couple of variables and provide accessors to that data. Then you build the business logic -- calculations, callbacks, observers -- in a separate class that holds your synchronized class but does the work outside of the lock. The problem is that it's a very unnatural way to think of classes. Also you have a lot of boilerplate code to write (synchronized class + accessors) for every piece of synchronized data you want to hold. I bet most people will not bother and won't realize that deadlocks could happen. Is there any example of supposedly well-written synchronized classes in the wild that I could review looking for that problem? -- Michel Fortin michel.fortin michelf.ca http://michelf.ca
Mar 16 2014
prev sibling next sibling parent luka8088 <luka8088 owave.net> writes:
On 16.3.2014. 5:08, Andrei Alexandrescu wrote:
 D1's approach to multithreading was wanting. D2 executed a big departure
 from that with the shared qualifier and the default-thread-local
 approach to data.
 
 We think this is a win, but D2 inherited a lot of D1's thread-related
 behavior by default, and some of the rules introduced by TDPL
 (http://goo.gl/9gtH0g) remained in the "I have a dream" stage.
 
 Fixing that has not gained focus until recently, when e.g.
 https://github.com/D-Programming-Language/dmd/pull/3067 has come about.
 There is other more stringent control of shared members, e.g.
 "synchronized" is all or none, "synchronized" only makes direct member
 variables unshared, and more.
 
 This will statically break code. It will refuse to compile code that is
 incorrect, but also plenty of code that is correct; the compiler will
 demand extra guarantees from user code, be they in the form of casts and
 stated assumptions.
 
 I believe this is a bridge we do need to cross. One question is how we
 go about it: all at once, or gradually?
 
 
 Andrei
 

+1 on fixing this!
Mar 16 2014
prev sibling next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Another breaking change could be the deprecation of the now 
nearly useless opApply() (only std.array.array works with it) and 
replacing it with a nice external iterator D syntax sugar to 
define a forward iterator:

http://journal.stuffwithstuff.com/2013/01/13/iteration-inside-and-out/

Another smaller breaking change could be the removal of some 
usages of the comma operator.

Another breaking change are related to changes to object.

Bye,
bearophile
Mar 16 2014
next sibling parent Benjamin Thaut <code benjamin-thaut.de> writes:
Am 16.03.2014 13:44, schrieb bearophile:
 Another breaking change could be the deprecation of the now nearly
 useless opApply() (only std.array.array works with it) and replacing it
 with a nice external iterator D syntax sugar to define a forward iterator:

 http://journal.stuffwithstuff.com/2013/01/13/iteration-inside-and-out/

 Another smaller breaking change could be the removal of some usages of
 the comma operator.

 Another breaking change are related to changes to object.

 Bye,
 bearophile

Wait what? I find opApply really usefull, especially because it passes a lambda in, and you have control over the program flow within opApply. This for example makes it possible to mark a container as "is currently iterated over" so you can assert when modifications are made to the container while it is currently used for iteration. In fact all of my custom container classes rely on opApply, so I do not agree at all, that it is useless. Also, as far as I know, std.paralellism heavily relies on opApply to actually be able to parallelise foreach loops. Could you please explain in a bit more detail why you think opApply should be deprecated? Kind Regards Benjamin Thaut
Mar 16 2014
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 3/16/14, 8:59 AM, bearophile wrote:
 (and some Rust people say D "scope" can't be very
 useful).

[citation needed] Andrei
Mar 16 2014
prev sibling next sibling parent "Mathias LANG" <pro.mathias.lang gmail.com> writes:
On Sunday, 16 March 2014 at 04:08:15 UTC, Andrei Alexandrescu 
wrote:
 I believe this is a bridge we do need to cross. One question is 
 how we go about it: all at once, or gradually?

IMHO, it would be better to do all-at-once. It would also be better to target a release to work on this issue (eg. 2.070). Then we can issue a massive, red "This break the world" warning.
Mar 16 2014
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Benjamin Thaut:

 Could you please explain in a bit more detail why you think 
 opApply should be deprecated?

To replace it with something better. But this discussion is off-topic for this thread, that is about "synchronized" or its alternatives. I didn't mean to derail the main thread. Bye, bearophile
Mar 16 2014
prev sibling next sibling parent "Andrea" <noneof yourbiz.com> writes:
I'm a newcomer to D so I may not be aware of many things that are 
going on in this community. If by any change I write anything 
stupid let me know. Also this may not be the right thread to post 
this and I'm sorry for that. That being said...

I'm seeing a lot a major breaking changes being discussed here on 
the forums and the proposal of a possible D3. As Walter and 
Andrei noted in another thread, I don't think D can take that 
hit. From my understanding, D is starting to get back on his feet 
after the D1->D2 transition *now*. Another major transition would 
mean killing it.

I propose an OpenGL-like route to deprecation through the use of 
profiles. DMD could implement a default core profile and an 
optional compatibility profile (adding/replacing in the core 
profile the otherwise broken features) to be activated with a 
flag. In a few years time the compatibility profile would be 
deprecated and DMD would enforce the new "best practices". In the 
short term the current "broken" code will still work without 
having to be rewritten.
Mar 16 2014
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 3/16/14, Andrea <noneof yourbiz.com> wrote:
 In the
 short term the current "broken" code will still work without
 having to be rewritten.

You'll end up in the same situation as Python 3. Most people will not only keep existing code, but continue to write *more of it*. By the time the "compatibility profile" is removed, it's going to become 100x harder to change all of that code, which means nobody will do it.
Mar 16 2014
prev sibling next sibling parent Russel Winder <russel winder.org.uk> writes:
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Sun, 2014-03-16 at 16:05 +0100, Andrej Mitrovic wrote:
[=E2=80=A6]
 You'll end up in the same situation as Python 3. Most people will not
 only keep existing code, but continue to write *more of it*. By the
 time the "compatibility profile" is removed, it's going to become 100x
 harder to change all of that code, which means nobody will do it.

Python 2 should be expunged from the planet, it is going to be the only way of getting people to stop writing more Python 2 code that doesn't work under Python 3. Java has the same problem in that there are people out there still running Java 1.4 just as Java 8 is about hit the streets. All JVM instances prior to JDK8 should self-annihilate on 2013-03-31. Whilst I agree large live systems do have to have carefully managed change, I think D is not in the same backward compatibility game as Python and Java. A big breaking change now is going to be much, much less pain than storing up problems for later. But I already said that in my earlier post. I guess I am just trying to bias the vote=E2=80=A6 ;-) =20 --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Mar 16 2014
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
 Another breaking change could be the

I think the implementation of "scope" could break quite more user code than the introduction of "final by default" class methods, because "in" function argument are common and they mean "scope const". There is not even a DIP for scope (and some Rust people say D "scope" can't be very useful). Bye, bearophile
Mar 16 2014
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:

 On 3/16/14, 8:59 AM, bearophile wrote:
 (and some Rust people say D "scope" can't be very
 useful).

[citation needed]

It was part of a much longer discussion on Reddit, few weeks ago. "scope" is a blunt tool compared to the region analysis of Rust. But this is not important, even less powerful tools can be useful, and they can be much more useful than not having them at all. I'd like someone to write a DIP for scope (I am not able to write it), and then discuss it a little (in another thread, because here it's off-topic), to see what it's supposed solve, and what it's not supposed to solve. Bye, bearophile
Mar 16 2014
prev sibling next sibling parent "Jesse Phillips" <Jesse.K.Phillips+D gmail.com> writes:
On Sunday, 16 March 2014 at 04:08:15 UTC, Andrei Alexandrescu 
wrote:
 I believe this is a bridge we do need to cross. One question is 
 how we go about it: all at once, or gradually?

I don't think this is quite the right question to ask. In the ideal, all changes would be placed in the compiler all at once and we'd have a perfect compiler. The only real answer is to do it all at once, if we can achieve that with synchronized that is great. The emphasis on gradual needs to be placed on the upgrade path. In the specific example it looks to be a very straight forward removal. In this case that just means deprecate first, then in the future remove. I think the upgrade path is so important that planning a sequence of changes is more important than "getting it over with" (which was valid in the past). To provide an example, if we were to go forward with the arr.length = 0 change, the path would look like. * Provide a way for people to write a "reset" array. This might mean a new function to handle the details, or require assumeSafeAppend() after assigning length to zero. * Later deprecate the use of arr.length = 0, in the case of requiring assumeSafeAppend() this can be the first step as it already exists. * Another later is to implement arr.length = 0 with the new semantics. * Further on we can deprecate the "reset" function we originally created, to eventually remove. The only change to this process that I see as we gain users is to extend how long each of these stages survives. This is based on the principle of code should be able to compile with the previous and current compiler. Regression fixes applied as a point release are exceptions.
Mar 16 2014
prev sibling next sibling parent reply Martin Nowak <code dawg.eu> writes:
On 03/16/2014 05:08 AM, Andrei Alexandrescu wrote:
 This will statically break code. It will refuse to compile code that is
 incorrect, but also plenty of code that is correct; the compiler will
 demand extra guarantees from user code, be they in the form of casts and
 stated assumptions.

 I believe this is a bridge we do need to cross. One question is how we
 go about it: all at once, or gradually?

Please think hard about this. Why does it need to break code? Can't we have a proper deprecation cycle? Until now it was always possible to add proper deprecation warnings and allow people to transition code at their own pace. I'm optimistic a solution can be found here too. Prominent examples for complex changes with working deprecation: https://d.puremagic.com/issues/show_bug.cgi?id=6652 https://d.puremagic.com/issues/show_bug.cgi?id=12359 By the way we've succeeded to release multiple version without major breakages. For the first time it was actually possible to compile the same code with an updated compiler :o. Next release 2.066 already risks to end this row by touching import rules and AAs.
Mar 16 2014
next sibling parent "Jesse Phillips" <Jesse.K.Phillips+D gmail.com> writes:
On Sunday, 16 March 2014 at 21:15:29 UTC, Martin Nowak wrote:
 Please think hard about this. Why does it need to break code?
 Can't we have a proper deprecation cycle?
 Until now it was always possible to add proper deprecation 
 warnings and allow people to transition code at their own pace. 
 I'm optimistic a solution can be found here too.

Deprecation is breaking code, it's a good way to to do it, but you shouldn't kid yourself that it isn't a breaking change.
Mar 16 2014
prev sibling next sibling parent "Andrea" <noneof yourbiz.com> writes:
On Monday, 17 March 2014 at 05:14:40 UTC, Marco Leise wrote:
 Am Mon, 17 Mar 2014 03:57:10 +0000
 schrieb "Jesse Phillips" <Jesse.K.Phillips+D gmail.com>:

 On Sunday, 16 March 2014 at 21:15:29 UTC, Martin Nowak wrote:
 Please think hard about this. Why does it need to break code?
 Can't we have a proper deprecation cycle?
 Until now it was always possible to add proper deprecation 
 warnings and allow people to transition code at their own 
 pace. I'm optimistic a solution can be found here too.

Deprecation is breaking code, it's a good way to to do it, but you shouldn't kid yourself that it isn't a breaking change.

It certainly is a subjective matter. I usually skim though the change log, install the new compiler and cross my fingers. Then if I get a few deprecation messages with IDE links to the source that's ok for me every two months or so. I just try to fix these locations immediately instead of changing the build options to include -d. Silent breaking changes are a totally different beast.

IMHO we have a bunch of breaking changes already planned for the future and it'll be a bit more difficult than that to fix the code. Maybe I'm not aware of it and it already exists, but we should create a page where deprecated features are listed, the reasons behind the deprecation briefly described and small examples on how to fix the code are provided. This way fixing the code will be much easier. Let's say I get deprecation messages on 2 of those major breaking changes spread across a medium-size project: searching through the forums for the right thread(s) and reading through pages of discussion just to get an idea of what exactly is broken in my code and then fix it is not realistic IMHO. That would definitely scare away a D newcomer trying to experiment with the language for a project. For example, not long ago I was struggling to find what changed from TDPL as of today. In the future it's gonna be even more difficult for a new comer to *learn* D, let alone use it in real world projects.
 But it certainly depends on time pressure, how much

 infrequently maintained libs you use etc.

I speak for myself here, so I maybe wrong. I'm under the impression that a lot of (bindings to) libraries *are* infrequently maintained (not all of them of course). This is a big problem for D's employment in real world projects, which is caused by D's lack of popularity among library developers and I'm pretty sure that some of that is due to D's lack of long term stability. This is seriously slowing down D's adoption IMO. In a recent project of mine I'm finding myself forced to go back to C++ (as much as I hate it) because of a lacking binding, which recently broke because the author introduced a change to the API and forgot to implement it in a few places and the shared libs precompiled binaries specific for the binding are severely outdated so my project doesn't even run. Now, I could submit a commit (I probably will) and spend half a day manually compiling the libraries, but why should I go through all of that when I can just download the latest official shared libs from the developer's website with templates for my favorite IDE, plenty of example code and the guarantee of a stable and reliable C++ API? Now, on top of that add the compiler spitting at me deprecation messages with me having a vague idea on how to fix them and I'm done with D for good.
 At the end of the day I see no way for D to evolve "correctly"
 with the man power it has and the demands for both a stable
 target and improvements to so many things from
 final-by-default over "scope" to "shared".
 If we collected all these bits in a list we would see that
 they can't all be fixed in one release and things are still
 going to break quite a few times in the future. TLBB? Not
 quite there yet! ;-)

I agree with that 100%.
Mar 17 2014
prev sibling next sibling parent "Jesse Phillips" <Jesse.K.Phillips+D gmail.com> writes:
On Monday, 17 March 2014 at 05:14:40 UTC, Marco Leise wrote:
 Deprecation is breaking code, it's a good way to to do it, but 
 you shouldn't kid yourself that it isn't a breaking change.

It certainly is a subjective matter.

I don't see how it is. How do you define a change which has broken code.
 I just try to
 fix these locations immediately instead of changing the build
 options to include -d.

You're code no longer compiles due to a compiler change, that is what I consider a breaking change.
 Silent breaking changes are a totally different beast.

Agreed.
 At the end of the day I see no way for D to evolve "correctly"
 with the man power it has and the demands for both a stable
 target and improvements to so many things from
 final-by-default over "scope" to "shared".
 If we collected all these bits in a list we would see that
 they can't all be fixed in one release and things are still
 going to break quite a few times in the future. TLBB? Not
 quite there yet! ;-)

Agreed. Just because we feel that D still needs breaking changes, doesn't mean we should change the definition so that we can tell the world we don't break code every release. "No civilian casualties! We just found it easier to declare all humans as combatants."
Mar 17 2014
prev sibling next sibling parent "Jesse Phillips" <Jesse.K.Phillips+D gmail.com> writes:
On Monday, 17 March 2014 at 08:48:36 UTC, Andrea wrote:
 IMHO we have a bunch of breaking changes already planned for 
 the future and it'll be a bit more difficult than that to fix 
 the code. Maybe I'm not aware of it and it already exists, but 
 we should create a page where deprecated features are listed, 
 the reasons behind the deprecation briefly described and small 
 examples on how to fix the code are provided.

The change log has been doing pretty good with this on for each release. Otherwise, DIPs are kind of supposed to cover this, which would also help on planned breaking changes. There is an old list, which isn't even too much out of date, if at all. http://www.prowiki.org/wiki4d/wiki.cgi?LanguageDevel#FutureDirections One of the biggest problems is that there doesn't tend to be any really clear statement of when a change has been approved. Usually it happens that someone implements it, and suddenly it is in the next compiler build. I feel that keeping the change log updated with this stuff is more important than the planning part.
Mar 17 2014
prev sibling parent "Nick Treleaven" <ntrel-public yahoo.co.uk> writes:
On Monday, 17 March 2014 at 08:48:36 UTC, Andrea wrote:
 IMHO we have a bunch of breaking changes already planned for 
 the future and it'll be a bit more difficult than that to fix 
 the code. Maybe I'm not aware of it and it already exists, but 
 we should create a page where deprecated features are listed, 
 the reasons behind the deprecation briefly described and small 
 examples on how to fix the code are provided.

We have: http://dlang.org/deprecate
Mar 17 2014
prev sibling next sibling parent Marco Leise <Marco.Leise gmx.de> writes:
Am Mon, 17 Mar 2014 03:57:10 +0000
schrieb "Jesse Phillips" <Jesse.K.Phillips+D gmail.com>:

 On Sunday, 16 March 2014 at 21:15:29 UTC, Martin Nowak wrote:
 Please think hard about this. Why does it need to break code?
 Can't we have a proper deprecation cycle?
 Until now it was always possible to add proper deprecation 
 warnings and allow people to transition code at their own pace. 
 I'm optimistic a solution can be found here too.

Deprecation is breaking code, it's a good way to to do it, but you shouldn't kid yourself that it isn't a breaking change.

It certainly is a subjective matter. I usually skim though the change log, install the new compiler and cross my fingers. Then if I get a few deprecation messages with IDE links to the source that's ok for me every two months or so. I just try to fix these locations immediately instead of changing the build options to include -d. Silent breaking changes are a totally different beast. But it certainly depends on time pressure, how much infrequently maintained libs you use etc. At the end of the day I see no way for D to evolve "correctly" with the man power it has and the demands for both a stable target and improvements to so many things from final-by-default over "scope" to "shared". If we collected all these bits in a list we would see that they can't all be fixed in one release and things are still going to break quite a few times in the future. TLBB? Not quite there yet! ;-) -- Marco
Mar 16 2014
prev sibling next sibling parent "Andrea" <noneof yourbiz.com> writes:
On Sunday, 16 March 2014 at 15:05:45 UTC, Andrej Mitrovic wrote:
 On 3/16/14, Andrea <noneof yourbiz.com> wrote:
 In the
 short term the current "broken" code will still work without
 having to be rewritten.

You'll end up in the same situation as Python 3. Most people will not only keep existing code, but continue to write *more of it*. By the time the "compatibility profile" is removed, it's going to become 100x harder to change all of that code, which means nobody will do it.

I was kind of expecting that argument. And yes, I do agree with that.
Mar 17 2014
prev sibling next sibling parent Marco Leise <Marco.Leise gmx.de> writes:
Am Mon, 17 Mar 2014 14:16:19 +0000
schrieb "Jesse Phillips" <Jesse.K.Phillips+D gmail.com>:

 On Monday, 17 March 2014 at 05:14:40 UTC, Marco Leise wrote:
 Deprecation is breaking code, it's a good way to to do it, but 
 you shouldn't kid yourself that it isn't a breaking change.

It certainly is a subjective matter.

I don't see how it is. How do you define a change which has broken code.
 I just try to
 fix these locations immediately instead of changing the build
 options to include -d.

You're code no longer compiles due to a compiler change, that is what I consider a breaking change.
 Silent breaking changes are a totally different beast.

Agreed.
 At the end of the day I see no way for D to evolve "correctly"
 with the man power it has and the demands for both a stable
 target and improvements to so many things from
 final-by-default over "scope" to "shared".
 If we collected all these bits in a list we would see that
 they can't all be fixed in one release and things are still
 going to break quite a few times in the future. TLBB? Not
 quite there yet! ;-)

Agreed. Just because we feel that D still needs breaking changes, doesn't mean we should change the definition so that we can tell the world we don't break code every release. "No civilian casualties! We just found it easier to declare all humans as combatants."

Ok, so you were looking at it from the public perception view point and I was thinking of the personal effect. Anyways it looks like Andrei is convinced that close to no breaking changes need to happen any more (excluding possibly already wrong code). If so - and it hasen't been communicated clearly - he and Walter should probably say so more clearly in the coming weeks or at Dconf14. Then we could stop discussing final-by-default and other things that potentially break code, like the changes to string handling and instead focus only on language additions. -- Marco
Mar 18 2014
prev sibling next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Sunday, 16 March 2014 at 04:08:15 UTC, Andrei Alexandrescu 
wrote:
 D1's approach to multithreading was wanting. D2 executed a big 
 departure from that with the shared qualifier and the 
 default-thread-local approach to data.

 We think this is a win, but D2 inherited a lot of D1's 
 thread-related behavior by default, and some of the rules 
 introduced by TDPL (http://goo.gl/9gtH0g) remained in the "I 
 have a dream" stage.

 Fixing that has not gained focus until recently, when e.g. 
 https://github.com/D-Programming-Language/dmd/pull/3067 has 
 come about. There is other more stringent control of shared 
 members, e.g. "synchronized" is all or none, "synchronized" 
 only makes direct member variables unshared, and more.

 This will statically break code. It will refuse to compile code 
 that is incorrect, but also plenty of code that is correct; the 
 compiler will demand extra guarantees from user code, be they 
 in the form of casts and stated assumptions.

 I believe this is a bridge we do need to cross. One question is 
 how we go about it: all at once, or gradually?


 Andrei

I still have zero understanding of what "synchronized" is supposed to mean an only vague guesses about "shared". Probably have never used either of those apart of "shared static this()" module constructors. Having some examples of how code is supposed to behave and what will break can help reason about it.
Mar 18 2014
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 3/18/14, 6:49 AM, Dicebot wrote:
 I still have zero understanding of what "synchronized" is supposed to
 mean an only vague guesses about "shared". Probably have never used
 either of those apart of "shared static this()" module constructors.
 Having some examples of how code is supposed to behave and what will
 break can help reason about it.

There are quite a few in TDPL. Andrei
Mar 18 2014
prev sibling next sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Tuesday, 18 March 2014 at 13:49:54 UTC, Dicebot wrote:
 I still have zero understanding of what "synchronized" is 
 supposed to mean an only vague guesses about "shared". Probably 
 have never used either of those apart of "shared static this()" 
 module constructors. Having some examples of how code is 
 supposed to behave and what will break can help reason about it.

Synchronized is supposed to remove the top level shared qualifier (but keep it for every indirections) withing member functions. Member function also acquire a mutex before doing anything. Andrei: please consider my proposal earlier in this thread. This is a relaxed version of the change that we are discussing here, which ensure the same level of safety, but with smaller breakage involved.
Mar 18 2014
prev sibling next sibling parent "Kagamin" <spam here.lot> writes:
On Sunday, 16 March 2014 at 13:55:24 UTC, bearophile wrote:
 Benjamin Thaut:

 Could you please explain in a bit more detail why you think 
 opApply should be deprecated?

To replace it with something better.

Don't even think, ranges are not better.
Mar 19 2014
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Kagamin:

 Don't even think, ranges are not better.

I am thinking about syntax sugar that the compiler uses to create a input/forward range similar to this: http://forum.dlang.org/post/awabysprjjnrxrhgqyee forum.dlang.org Bye, bearophile
Mar 19 2014
prev sibling parent "David Nadlinger" <code klickverbot.at> writes:
On Wednesday, 19 March 2014 at 10:41:59 UTC, bearophile wrote:
 Kagamin:
 Don't even think, ranges are not better.

I am thinking about syntax sugar that the compiler uses to create a input/forward range similar to this: http://forum.dlang.org/post/awabysprjjnrxrhgqyee forum.dlang.org

There is, however, a fundamental difference between ranges and opApply: Ranges use external iteration, whereas in opApply, it is the collection object that controls how iteration is performed. Features like transparent parallelization in std.parallelism would not be possible without this. David
Mar 19 2014