www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - DIP 1028---Make safe the Default---Community Review Round 1

reply Mike Parker <aldacron gmail.com> writes:
This is the feedback thread for the first round of Community 
Review for DIP 1028, "Make  safe the Default":

https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688554b/DIPs/DIP1028.md

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

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

Anyone intending to post feedback in this thread is expected to 
be familiar with the reviewer guidelines:

https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md

*Please stay on topic!*

Thanks in advance to all who participate.
Jan 02 2020
next sibling parent Mike Parker <aldacron gmail.com> writes:
On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1028, "Make  safe the Default":
And to make it searchable: #DIP1028
Jan 02 2020
prev sibling next sibling parent WebFreak001 <d.forum webfreak.org> writes:
On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1028, "Make  safe the Default":

 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688554b/DIPs/DIP1028.md

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

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

 Anyone intending to post feedback in this thread is expected to 
 be familiar with the reviewer guidelines:

 https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md

 *Please stay on topic!*

 Thanks in advance to all who participate.
This is a simple but really powerful change. I think most issues you would have with safe right now would simply be gone as it's very often libraries which are not marked safe causing trouble, rather than actually using unsafe code. In my experience most code is written as safe code and only very rarely are the unsafe code features actually needed. Having aid by the compiler not accidentally using unsafe code will definitely help most users. Users writing a lot of system code like for example those writing OS drivers (very niche) will have issues that relatively easily can be fixed by placing system in the affected functions or add a system: on top of the file (which will not work that well with the other code though) As with all such changes there will be a lot of pain and silent breakage for those using __traits(compiles, {}) with something related with safe/ system. I don't think deprecations are shown in it so the transition period will also not help with that. I think having a system to mitigate this issue is really important, but that's rather part of another DIP and shouldn't interfere so much with this DIP. With these 'compiles' checks for safe/ system you most often call the function anyway, which will trigger the deprecation warnings so this is not that big of an issue in 98% of the cases. To fix code it will be minimal changes, which could probably even be automated by suggestions from the IDE. :) Overall I think the DIP is good as-is and will bring more positives than negatives to D.
Jan 02 2020
prev sibling next sibling parent reply Basile B. <b2.temp gmx.com> writes:
On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1028, "Make  safe the Default":

 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688554b/DIPs/DIP1028.md

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

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

 Anyone intending to post feedback in this thread is expected to 
 be familiar with the reviewer guidelines:

 https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md

 *Please stay on topic!*

 Thanks in advance to all who participate.
While I don't disapprove I suggest a very long deprecation phase, based on 1. a compiler switch for let's say 1 year, allowing to test and prepare 2. after that, the real deprecation, following what the official rule for D deprecation imply, and concerning what is not annotated 3. after that, non annotated funcs will be safe. 4. Maybe a compiler switch for backward compatibility should be added at the end. This could help in case someone use unmaintained libraries. Based on this comment, I suggest to amend the DIP to add a **very detailed plan**, a schedule, for how things would append. This is not clear for now. Finally a more technical remark is that maybe you should mention that annotating a whole module, after the module declaration, ` system:` makes the maintenance easy. For now the DIPS seems to suggest that all funcs should be annotated.
Jan 02 2020
parent Basile B. <b2.temp gmx.com> writes:
On Thursday, 2 January 2020 at 10:41:20 UTC, Basile B. wrote:
 On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1028, "Make  safe the Default":

 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688554b/DIPs/DIP1028.md

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

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

 Anyone intending to post feedback in this thread is expected 
 to be familiar with the reviewer guidelines:

 https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md

 *Please stay on topic!*

 Thanks in advance to all who participate.
While I don't disapprove I suggest a very long deprecation phase, based on 1. a compiler switch for let's say 1 year, allowing to test and prepare 2. after that, the real deprecation, following what the official rule for D deprecation imply, and concerning what is not annotated 3. after that, non annotated funcs will be safe. 4. Maybe a compiler switch for backward compatibility should be added at the end. This could help in case someone use unmaintained libraries. Based on this comment, I suggest to amend the DIP to add a **very detailed plan**, a schedule, for how things would append. This is not clear for now. Finally a more technical remark is that maybe you should mention that annotating a whole module, after the module declaration, ` system:` makes the maintenance easy. For now the DIPS seems to suggest that all funcs should be annotated.
actually dont take in account the final note. It would obviously not work for agregates (struct, class) only for module level free funcs. Sorry for that.
Jan 02 2020
prev sibling next sibling parent reply bachmeier <no spam.net> writes:
On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1028, "Make  safe the Default":

 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688554b/DIPs/DIP1028.md

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

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

 Anyone intending to post feedback in this thread is expected to 
 be familiar with the reviewer guidelines:

 https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md

 *Please stay on topic!*

 Thanks in advance to all who participate.
"This will likely break most code that has not already been annotated with safe, trusted, or system. Fortunately, the solution is easy, although tedious: annotate functions that aren't safe with trusted or system." Maybe I'm missing something, but the spec says "Trusted functions are guaranteed to not exhibit any undefined behavior if called by a safe function. Furthermore, calls to trusted functions cannot lead to undefined behavior in safe code that is executed afterwards. It is the responsibility of the programmer to ensure that these guarantees are upheld." If I want to make my code compile, I'd be forced to declare a function trusted *even if it shouldn't be*. In other words, if we go down this road, trusted loses its meaning. If I mark it system, that doesn't really help, because my code still isn't going to compile. Perhaps someone can explain where I'm wrong. If I'm correct, then it would make more sense to declare at the top of a file that this is legacy code and thus treated as trusted unless marked otherwise.
Jan 02 2020
next sibling parent bachmeier <no spam.net> writes:
On Thursday, 2 January 2020 at 11:10:38 UTC, bachmeier wrote:
 On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1028, "Make  safe the Default":

 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688554b/DIPs/DIP1028.md

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

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

 Anyone intending to post feedback in this thread is expected 
 to be familiar with the reviewer guidelines:

 https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md

 *Please stay on topic!*

 Thanks in advance to all who participate.
"This will likely break most code that has not already been annotated with safe, trusted, or system. Fortunately, the solution is easy, although tedious: annotate functions that aren't safe with trusted or system." Maybe I'm missing something, but the spec says "Trusted functions are guaranteed to not exhibit any undefined behavior if called by a safe function. Furthermore, calls to trusted functions cannot lead to undefined behavior in safe code that is executed afterwards. It is the responsibility of the programmer to ensure that these guarantees are upheld." If I want to make my code compile, I'd be forced to declare a function trusted *even if it shouldn't be*. In other words, if we go down this road, trusted loses its meaning. If I mark it system, that doesn't really help, because my code still isn't going to compile. Perhaps someone can explain where I'm wrong. If I'm correct, then it would make more sense to declare at the top of a file that this is legacy code and thus treated as trusted unless marked otherwise.
I want to make this comment in a new reply since it's separate from the previous comment. I dislike this proposal because it's too large without a corresponding move to D 3.0. It won't just break existing code, but also existing tutorials and documentation. I strongly support the change. Just not in D 2.* since that will be too confusing for new/occasional users of the language.
Jan 02 2020
prev sibling parent reply ag0aep6g <anonymous example.com> writes:
On 02.01.20 12:10, bachmeier wrote:
 If I want to make my code compile, I'd be forced to declare a function 
  trusted *even if it shouldn't be*. In other words, if we go down this 
 road,  trusted loses its meaning. If I mark it  system, that doesn't 
 really help, because my code still isn't going to compile.
Yes, you shouldn't blindly slap trusted on your non- safe functions. But you *can* blindly slap system on them. Non-annotated functions are already system by default; you're just making it explicit. Your code should compile the same as today.
 Perhaps someone can explain where I'm wrong. If I'm correct, then it 
 would make more sense to declare at the top of a file that this is 
 legacy code and thus treated as  trusted unless marked otherwise.
There's not really a way to do it for a whole file, but with ` system:` and ` system { ... }` the busywork might be tolerable. Though I would consider it better practice to mark each function individually. And legacy code should be treated as system, not as trusted.
Jan 02 2020
parent reply bachmeier <no spam.net> writes:
On Thursday, 2 January 2020 at 12:23:54 UTC, ag0aep6g wrote:

 Yes, you shouldn't blindly slap  trusted on your non- safe 
 functions.

 But you *can* blindly slap  system on them. Non-annotated 
 functions are already  system by default; you're just making it 
 explicit. Your code should compile the same as today.
What compiler do you use? I always get error messages when I try to call system functions from safe code.
 And legacy code should be treated as  system, not as  trusted.
Perfectly working legacy code should by default stop compiling?
Jan 02 2020
next sibling parent reply ag0aep6g <anonymous example.com> writes:
On 02.01.20 13:34, bachmeier wrote:
 On Thursday, 2 January 2020 at 12:23:54 UTC, ag0aep6g wrote:
[...]
 What compiler do you use? I always get error messages when I try to call 
  system functions from  safe code.
Why would you suddenly be calling system functions from safe code? If all functions in your call chain are currently not marked, then you mark them all as system for the DIP, and the code compiles just as it used to. If the calling function is currently marked as safe but the called function isn't, then the chain already doesn't compile.
 And legacy code should be treated as  system, not as  trusted.
Perfectly working legacy code should by default stop compiling?
Yes. And if you want your working unsafe program back, you have to add lots of system attributes. You might oppose the DIP on the grounds that that's too much hassle for too little gain. That's a reasonable position. Treating all legacy code as trusted (when it was clearly system before) would not be reasonable, in my opinion. All that said, you *can* slap ` trusted:` onto your modules, of course. You really shouldn't, but you can.
Jan 02 2020
parent reply Dominikus Dittes Scherkl <dominikus scherkl.de> writes:
On Thursday, 2 January 2020 at 13:21:17 UTC, ag0aep6g wrote:
 Why would you suddenly be calling  system functions from  safe 
 code?

 If all functions in your call chain are currently not marked, 
 then you mark them all as  system for the DIP, and the code 
 compiles just as it used to.

 If the calling function is currently marked as  safe but the 
 called function isn't, then the chain already doesn't compile.
Yes! I fully support this DIP. But at the same time, additionally trusted as a function attribute should be removed and replaced by trusted expressions. Because:
 Treating all legacy code as  trusted (when it was clearly 
  system before) would not be reasonable, in my opinion.
This should NOT be possible! We would lose a lot of safety if even a few library developers do that. trusted should be restricted to as few code as possible, at best only to the line of code where it is really necessary to make a function safe.
Jan 02 2020
parent reply ag0aep6g <anonymous example.com> writes:
On 02.01.20 14:47, Dominikus Dittes Scherkl wrote:
 But at the same time, additionally  trusted as a function attribute 
 should be removed and replaced by  trusted expressions. Because:
[...]
  trusted should be restricted to as few code as possible, at best only 
 to the line of code where it is really necessary to make a function  safe.
One step at a time. As it is, the DIP may be disruptive but it's simple. Improvements to trusted can go in another DIP. Applying trusted to as little code as possible sounds good, but it's often done incorrectly with the effect that safe is weakened. Here's a quick example from a GitHub search on Phobos [1]: auto p = (() trusted => fakePureMmap(null, bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0))(); /* ... stuff ... */ return (() trusted => p[0 .. bytes])(); Strictly speaking, that second lambda cannot be trusted. Its safety relies on `p` and `bytes` being compatible. But an unlucky contributor might accidentally set `p = new byte;` or `bytes = 1024^^3;` in "stuff". Those mistakes would pass as safe, but they would likely lead to memory corruption. The corruption would happen after an edit that only touched safe code. That's exactly what D's safety system is supposed to prevent. But I agree that applying trusted to the function signature is ugly and misleading. For a caller, there is zero difference between these two functions: void f() trusted { /* ... stuff ... */ } void f() safe { () trusted { /* ... the same stuff ... */ } (); } Having trusted visible in the function signature just gives people wrong ideas about what it means. [1] https://github.com/dlang/phobos/blob/5e6fe2f9c8f72f4c3b0497dc363fc61d823ff489/std/experimental/allocator/mmap_allocator.d#L38-L45
Jan 02 2020
parent Dominikus Dittes Scherkl <dominikus scherkl.de> writes:
On Thursday, 2 January 2020 at 14:43:50 UTC, ag0aep6g wrote:
 On 02.01.20 14:47, Dominikus Dittes Scherkl wrote:
 But at the same time, additionally  trusted as a function 
 attribute should be removed and replaced by  trusted 
 expressions. Because:
[...]
  trusted should be restricted to as few code as possible, at 
 best only to the line of code where it is really necessary to 
 make a function  safe.
One step at a time. As it is, the DIP may be disruptive but it's simple. Improvements to trusted can go in another DIP.
But it is also simple (you just don't need the two pairs of parents at the start and the end of a trusted lambda anymore) and it affects pretty much exactly the same places as this DIP. The deprecation period will be rather long, so I think it would be a good idea to do both in one wash.
 Applying  trusted to as little code as possible sounds good, 
 but it's often done incorrectly
That won't change. You still need to trust things marked as trusted (or better: check them again!). This will only be easier if less code is marked such.
 For a caller, there is zero difference between these two 
 functions:

     void f()  trusted { /* ... stuff ... */ }
     void f()  safe { ()  trusted { /* ... the same stuff ... */ 
 } (); }

 Having  trusted visible in the function signature just gives 
 people wrong ideas about what it means.
Exactly. That's why forbidding trusted at function level is a gain. You loose nothing (you can always replace all trusted functions in the way you illustrated here), but you can improve code a lot. And you avoid that plenty of new trusted functions suddenly pop up, with no resources to check if they are really safe or why exactly they are not.
Jan 02 2020
prev sibling parent reply jmh530 <john.michael.hall gmail.com> writes:
On Thursday, 2 January 2020 at 12:34:05 UTC, bachmeier wrote:
 [snip]

 What compiler do you use? I always get error messages when I 
 try to call  system functions from  safe code.
 [snip]
Nothing prevents you from going function by function to verify if you can make things trusted or safe. It would be a big time commitment for legacy code, of course. Or, you can just make main system as well. I think what you are really trying to say is more about interacting between legacy code that was system by default and new code that is safe by default. But system code can call safe code without any problem. So maybe just write the new code as you please, but then make main system? There is value in this point. I think most people think it will be quite disruptive.
Jan 02 2020
parent reply bachmeier <no spam.net> writes:
On Thursday, 2 January 2020 at 13:49:43 UTC, jmh530 wrote:
 On Thursday, 2 January 2020 at 12:34:05 UTC, bachmeier wrote:
 [snip]

 What compiler do you use? I always get error messages when I 
 try to call  system functions from  safe code.
 [snip]
Nothing prevents you from going function by function to verify if you can make things trusted or safe. It would be a big time commitment for legacy code, of course. Or, you can just make main system as well. I think what you are really trying to say is more about interacting between legacy code that was system by default and new code that is safe by default. But system code can call safe code without any problem. So maybe just write the new code as you please, but then make main system? There is value in this point. I think most people think it will be quite disruptive.
You would have to go through every function in every library you call as well. That's not realistic, so the outcome would be a programming language where you sometimes have a main function, and sometimes you have a system main function, and sometimes it matters if you choose one or the other, and sometimes it doesn't. Surely there has to be a better way. I don't find it helpful to say everything is system now. That might be true, but it's possible to write trusted functions right now without attaching the hideous attribute to your function. It's much better to be able to declare that a file contains legacy code and treat everything in that file as trusted. If you have to add system to main, that's not only a horrible design, it also defeats the purpose of safe as the default. If at all possible, this should be handled in such a way that you can continue using code already written, but that disappears as code gets written for safe by default. The solutions I've seen in this thread are the equivalent of using a chain saw to remove a sliver, and while that would get the job done, it would be worse than no change and also completely unnecessary. Just to be clear: my proposal is that you add legacy at the top of a file and everything in there will be trusted if it's not marked otherwise. If you want compiler errors, don't do anything and the compiler will tell you which functions are not compatible with safe. You can then mark them trusted or system or mark main as system if you want. But let's not force that crazy solution on everyone.
Jan 02 2020
parent reply jmh530 <john.michael.hall gmail.com> writes:
On Thursday, 2 January 2020 at 15:25:15 UTC, bachmeier wrote:
 [snip]

 Just to be clear: my proposal is that you add  legacy at the 
 top of a file and everything in there will be  trusted if it's 
 not marked otherwise. If you want compiler errors, don't do 
 anything and the compiler will tell you which functions are not 
 compatible with  safe. You can then mark them  trusted or 
  system or mark main as  system if you want. But let's not 
 force that crazy solution on everyone.
Your legacy is really no different than putting trusted: at the top. I agree with others who are concerned about marking all current code as trusted, rather than system. To your other point about it being ugly to mark main as system, I recall Walter considering, at some point, keeping main as system. Perhaps give main more time before changing the default to safe?
Jan 02 2020
parent bachmeier <no spam.net> writes:
On Thursday, 2 January 2020 at 16:19:00 UTC, jmh530 wrote:
 On Thursday, 2 January 2020 at 15:25:15 UTC, bachmeier wrote:
 Your  legacy is really no different than putting  trusted: at 
 the top. I agree with others who are concerned about marking 
 all current code as  trusted, rather than  system.
It would be treated that way. In practice, it would mean something very different from trusted, because all you can infer from the lack of attributes at this point is that there was never a decision made with respect to safe, trusted, or system. If you put trusted at the top of a file, that should mean you've made the decision to call it trusted after evaluating and testing the code. Going forward, anything marked trusted really would be trusted if we had legacy.
 To your other point about it being ugly to mark main as 
  system, I recall Walter considering, at some point, keeping 
 main as  system. Perhaps give main more time before changing 
 the default to  safe?
That would certainly be better. It would still not prevent unnecessarily breaking (many millions of lines of) working code.
Jan 02 2020
prev sibling next sibling parent reply jmh530 <john.michael.hall gmail.com> writes:
On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1028, "Make  safe the Default":
I believe this DIP should be not be accepted until 1) it is possible to write a safe RC type, 2) someone writes a tool that adds system to every function that is not annotated safe or trusted (or already system) (probably not that hard).
Jan 02 2020
next sibling parent reply bachmeier <no spam.net> writes:
On Thursday, 2 January 2020 at 11:19:52 UTC, jmh530 wrote:
 On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1028, "Make  safe the Default":
I believe this DIP should be not be accepted until 1) it is possible to write a safe RC type, 2) someone writes a tool that adds system to every function that is not annotated safe or trusted (or already system) (probably not that hard).
If a function is not annotated, why should it default to system? That has a specific meaning that probably shouldn't apply to most code.
Jan 02 2020
parent jmh530 <john.michael.hall gmail.com> writes:
On Thursday, 2 January 2020 at 11:31:59 UTC, bachmeier wrote:
 [snip]
 I believe this DIP should be not be accepted until 1) it is 
 possible to write a  safe RC type, 2) someone writes a tool 
 that adds  system to every function that is not annotated 
  safe or  trusted (or already  system) (probably not that 
 hard).
If a function is not annotated, why should it default to system? That has a specific meaning that probably shouldn't apply to most code.
I'm thinking about the transition. (non-template) Functions are currently implicitly system, but that will change to safe. So there should be a way to easily transition from the old default to the new one. Not really different from what someone mentioned above with putting system: at the top of the file.
Jan 02 2020
prev sibling next sibling parent reply Dominikus Dittes Scherkl <dominikus scherkl.de> writes:
On Thursday, 2 January 2020 at 11:19:52 UTC, jmh530 wrote:
 On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1028, "Make  safe the Default":
I believe this DIP should be not be accepted until [...] someone writes a tool that adds system to every function that is not annotated safe or trusted (or already system) (probably not that hard).
Yes, yes! But this tool should not slap system on every function, but only on those that don't compile with the new default - the rest was already safe but the proper annotation was missing, so this is the benefit we get. Don't waste it!
Jan 02 2020
parent reply jmh530 <john.michael.hall gmail.com> writes:
On Thursday, 2 January 2020 at 14:37:02 UTC, Dominikus Dittes 
Scherkl wrote:
 [snip]

 Yes, yes!
 But this tool should not slap  system on every function, but 
 only on those that don't compile with the new default - the 
 rest was already  safe but the proper annotation was missing, 
 so this is the benefit we get. Don't waste it!
You should probably also check that the unittests still pass too...especially if the behavior of the function can change depending on whether something is safe or not. For instance, in the code below, if you add in system for foo and baz, then the unittests still compile, but if you make foo and baz safe, then the unittests no longer pass. import std; int foo(int x) { static if (isSafe!baz) { return baz(x); } else { return bar(x); } } safe int bar(int x) { return x + 1; } int baz(int x) { return x + 2; } unittest { int x = 5; int y = foo(x); assert(y == 6); }
Jan 02 2020
parent reply Dominikus Dittes Scherkl <dominikus scherkl.de> writes:
On Thursday, 2 January 2020 at 15:02:07 UTC, jmh530 wrote:
 On Thursday, 2 January 2020 at 14:37:02 UTC, Dominikus Dittes 
 Scherkl wrote:
 [snip]

 Yes, yes!
 But this tool should not slap  system on every function, but 
 only on those that don't compile with the new default - the 
 rest was already  safe but the proper annotation was missing, 
 so this is the benefit we get. Don't waste it!
You should probably also check that the unittests still pass too...especially if the behavior of the function can change depending on whether something is safe or not. For instance, in the code below, if you add in system for foo and baz, then the unittests still compile, but if you make foo and baz safe, then the unittests no longer pass. import std; int foo(int x) { static if (isSafe!baz) { return baz(x); } else { return bar(x); } } safe int bar(int x) { return x + 1; } int baz(int x) { return x + 2; } unittest { int x = 5; int y = foo(x); assert(y == 6); }
No, this should not be necessary. baz() compiles with safe as default, so it should not be annotated system automatically. And if it doesn't compile, that would be a bug in the original code, so it is a good thing that the test now fails.
Jan 02 2020
parent reply jmh530 <john.michael.hall gmail.com> writes:
On Thursday, 2 January 2020 at 15:08:41 UTC, Dominikus Dittes 
Scherkl wrote:
 [snip]

 No, this should not be necessary. baz() compiles with  safe as 
 default, so it should not be annotated  system automatically. 
 And if it doesn't compile, that would be a bug in the original 
 code, so it is a good thing that the test now fails.
Under current behavior, baz is system by default, but that will change to safe with this DIP. If both baz and foo are annotated with either safe or system, then the program (excluding the UTs) compiles without errors. The problem is that the behavior of foo changes if baz is marked safe rather than system. You might argue that this is a bug, but it wasn't a bug originally. Your approach would have turned a bug-free program into a buggy one.
Jan 02 2020
next sibling parent reply Dominikus Dittes Scherkl <dominikus scherkl.de> writes:
On Thursday, 2 January 2020 at 15:29:38 UTC, jmh530 wrote:
 On Thursday, 2 January 2020 at 15:08:41 UTC, Dominikus Dittes 
 Scherkl wrote:
 [snip]

 No, this should not be necessary. baz() compiles with  safe as 
 default, so it should not be annotated  system automatically. 
 And if it doesn't compile, that would be a bug in the original 
 code, so it is a good thing that the test now fails.
Under current behavior, baz is system by default, but that will change to safe with this DIP. If both baz and foo are annotated with either safe or system, then the program (excluding the UTs) compiles without errors. The problem is that the behavior of foo changes if baz is marked safe rather than system. You might argue that this is a bug, but it wasn't a bug originally. Your approach would have turned a bug-free program into a buggy one.
No, I argue the program was originally buggy: is got the false information that baz is nor safe, but it is only due to a missing annotation (e.g. if buz were a template, it would have been assumed to be safe) I hope that very few code out there actually use such bad mechanisms (e.g. call different functions depending on there safe annotation)-
Jan 02 2020
parent Dominikus Dittes Scherkl <dominikus scherkl.de> writes:
On Thursday, 2 January 2020 at 15:38:22 UTC, Dominikus Dittes 
Scherkl wrote:
 [...]
Woah, writing fast is not my thing :-/ Again, hopefully with less typos:
 No, I argue the program was originally buggy: it got the false 
 information that baz() is not safe, but this is only due to a 
 missing annotation (e.g. if baz() were a template, it would 
 have been inferred to be  safe)

 I hope that very few code out there actually use such bad 
 mechanisms (e.g. call different functions depending on their 
  safe annotation).
Jan 02 2020
prev sibling parent reply mipri <mipri minimaltype.com> writes:
On Thursday, 2 January 2020 at 15:29:38 UTC, jmh530 wrote:
 The problem is that the behavior of foo changes if baz is 
 marked  safe rather than  system.
So, +1 migration task: - [ ] audit uses of isSafe et al. Excepting assertions, in Phobos, std.range RefRange uses it to conditionally add trusted and std.datetime uses it in some deprecated code. My response to this DIP was "that sounds great but I hope it doesn't take forever for the default-default to change." I think a list of things to check, like this, would help. These measures may also help: * --legacy=systemdefault=[fakesafe|system] flag where 'fakesafe' presents unannotated functions *without* this flag as if they were trusted. * dub.pm stale-package designation. If a module hasn't been updated since some date, then dub warns that it's stale while turning the previous flag on for it. This lets the default-default change *sooner*, which is *better* as it reduces the truly sucky period of things being up in the air. * other stuff?
Jan 02 2020
parent jmh530 <john.michael.hall gmail.com> writes:
On Thursday, 2 January 2020 at 15:50:29 UTC, mipri wrote:
 [snip]
 So, +1 migration task:

 - [ ] audit uses of isSafe et al.
The et al should probably include at least __traits(getFunctionAttributes, XXX) hasFunctionAttributes functionAttributes SetFunctionAttributes isUnsafe
Jan 02 2020
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/2/2020 3:19 AM, jmh530 wrote:
 I believe this DIP should be not be accepted until 1) it is possible to write
a 
  safe RC type,
Issues that don't get put in bugzilla don't get fixed. Please tag all issues about safe with the `safe` keyword. Here is the current list: https://issues.dlang.org/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&keywords=safe&keywords_type=allwords&list_id=229570&query_format=advanced Issues with safe that are not about making safe the default (i.e. not about the DIP) are off-topic. Please start a new thread with them.
Jan 02 2020
parent jmh530 <john.michael.hall gmail.com> writes:
On Friday, 3 January 2020 at 01:27:11 UTC, Walter Bright wrote:
 [snip]

 Issues that don't get put in bugzilla don't get fixed. Please 
 tag all issues about  safe with the `safe` keyword. Here is the 
 current list:

 https://issues.dlang.org/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&keywords=safe&keywords_type=allwords&list_id=229570&query_format=advanced

 Issues with  safe that are not about making  safe the default 
 (i.e. not about the DIP) are off-topic. Please start a new 
 thread with them.
You made the argument further down that we shouldn't need to act serially, but I don't think I'm the only one who disagrees with that stance. It is a question of strategy. I strongly believe that questions of strategy are on-topic for discussing this DIP, particularly when the strategy is not laid out in the DIP itself. Going back several years, there are have been Vision documents that highlight a goal of moving away from the GC and instead using Reference Counted types. However, it has been found to be difficult to do this safe-ly. This is not something I am pulling out of thin air. This is something you, Andrei, and others have talked about extensively and certainly know a lot more about than I do. As a result, there have been a series of language enhancements aimed at strengthening safe. More recently, there was a blog post where Atila laid out his Vision for making safe by default. From a strategic perspective, I wonder, has the language been enhanced to the point that it makes sense for safe to be the default. This is not addressed in the DIP. It seems to me that we are not to the point where it is possible to do safe RC, which I assumed was a major long-term goal for the language. So I wonder if it is appropriate to make the change, given the breakage and the fact that safe is still on track to be strengthened further. Others have argued for making it opt-in until these other language improvements are ready. I consider that an on-topic valid point as well.
Jan 03 2020
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/2/20 6:19 AM, jmh530 wrote:
 On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community Review 
 for DIP 1028, "Make  safe the Default":
I believe this DIP should be not be accepted until 1) it is possible to write a safe RC type, 2) someone writes a tool that adds system to every function that is not annotated safe or trusted (or already system) (probably not that hard).
So I spent about 3 days to try and bring a large project into the realm of ` safe` [1]. I'm still not done there, but it's both eminently possible, and satisfying to have something to show for "you can just mark all your stuff safe". However, one of the biggest costs we are going to have for this DIP (and I 100% support this DIP), is that deprecations are not going to be easy. It's not always easy to take your well-crafted API, and make it usable in both ` safe` and ` system` code. The two large issues I ran into (and these I think we need to have fixed in concurrence with this release): 1. std.variant.Variant cannot be safe. We need a SafeVariant. I went with TaggedAlgebraic due to the nice generative features there. 2. Object.opXXX is NOT marked safe. This means doing operators with objects (especially opEquals). In my PR, because I no longer needed to compare objects since I was moving away from Variant (which uses TypeInfo for checking runtime type), this problem kind of went away. But it's definitely something that is concerning. These are likely not the only problems that will happen. And most likely we will see a lot of these little things crop up. The DIP should address not just schedules, but prerequisites for moving to the next stage of the process (e.g. Object must be usable with safe before an official deprecation is added to the compiler). If you read through the discussions on making MySQL safe (see the referenced issue report [2]), the biggest difficulty for me is if you need to change return types (as I did from Variant to TaggedAlgebraic). Now, your API needs to necessarily adjust because you can't overload based on return type in D. If that were possible, then the API updates and deprecations would be easy. Is it even feasible to overload something like return type based on the context called from? i.e. if you call from a system function, you get type A, if you call from a safe function, you get type B. -Steve [1] https://github.com/mysql-d/mysql-native/pull/214 [2] https://github.com/mysql-d/mysql-native/issues/175
Jan 03 2020
prev sibling next sibling parent Les De Ridder <les lesderid.net> writes:
On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1028, "Make  safe the Default":

 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688554b/DIPs/DIP1028.md
The rationale seems a bit lacking.
Jan 02 2020
prev sibling next sibling parent ag0aep6g <anonymous example.com> writes:
On 02.01.20 10:47, Mike Parker wrote:
 This is the feedback thread for the first round of Community Review for 
 DIP 1028, "Make  safe the Default":
 
 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688
54b/DIPs/DIP1028.md 
There's this paragraph in the DIP: "This will likely break most code that has not already been annotated with safe, trusted, or system. Fortunately, the solution is easy, although tedious: annotate functions that aren't safe with trusted or system." The last part there can be read as advice to D programmers on how to adjust their code. I'm afraid it will be interpreted as: "Just slap trusted on your unsafe code." Which is terrible advice. I suggest changing the part after the colon to something like: "annotate that code with system." I.e.: 1) Don't use "safe" without an sign. It's too fuzzy a word. 2) Don't recommend trusted. It's not needed to get the code working again.
Jan 02 2020
prev sibling next sibling parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1028, "Make  safe the Default":

 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688554b/DIPs/DIP1028.md

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

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

 Anyone intending to post feedback in this thread is expected to 
 be familiar with the reviewer guidelines:

 https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md

 *Please stay on topic!*

 Thanks in advance to all who participate.
This dip, doesn't describe how to make the destroy function for classes safe, as the class deconstructors don't inherent the attributes from the parent class. This issue is major blocking point on why I don't use D for serious software development for gaming development.(It also the reason why you can't call the destroy function for classes in nogc and nothrow context either) -Alex
Jan 02 2020
next sibling parent reply Guillaume Piolat <first.last gmail.com> writes:
On Thursday, 2 January 2020 at 14:39:56 UTC, 12345swordy wrote:
 This dip, doesn't describe how to make the destroy function for 
 classes safe, as the class deconstructors don't inherent the 
 attributes from the parent class. This issue is major blocking 
 point on why I don't use D for serious software development for 
 gaming development.(It also the reason why you can't call the 
 destroy function for classes in nogc and nothrow context either)
This is a serious concern (destruction and attributes), for example if you have the runtime disabled (say you make nogc shared libraries :) ) you NEED to do this in order to have class objects: https://github.com/AuburnSounds/Dplug/blob/master/core/dplug/core/nogc.d#L85 And then live in your own little D-- universe. Some hope that ProtoObject would solve this... --------- About that DIP ------------- - Never needed memory-safety, don't see the point, customers are not crying. Will not need it in the future. - I'll just slap trusted everywhere and call is a day - this will break every one of the 100kloc I maintain for no benefit to me, so well I sure hope the future memory-safe future does materialize... I doubt it, in this one real world view, lots of customer care about specific bugs not whole classes of bugs. In this regards I think type system "fanciness" is a form of early optimization (there, I said it). - I don't think D defaults are wrong, they let you write code that is as-crappy-as-needed and gets better later. - on intel-intrinsics I've already broken trusted by slapping it (had no choice in most cases), as under safe you can't do things like being passed a pointer and access the 3rd element. This more or less guarantees no safe-based optimization? Type-system with trusted gives really no guarantee at scale. Replace with slices everywhere? Well we like to pass pointers around for audio buffers, not multiple time the same length. Example: void processStuff(const(float)* input, float* output, int n) vs void processStuff(const(float)[] input, float[] output) There is a performance difference. Also there is a reason you've said "no" to pure and nogc as type constructor and they stayed function attributes. Again, like shared and pure, like TLS-by-default, this is one feature with very little Return on Investment (RoI) but with considerable hype on internet forums. ---------------->3----------------------
Jan 02 2020
next sibling parent reply JN <666total wp.pl> writes:
On Thursday, 2 January 2020 at 17:06:44 UTC, Guillaume Piolat 
wrote:
 - I don't think D defaults are wrong, they let you write code 
 that is as-crappy-as-needed and gets better later.
Personally, I don't care for memory safety either, I don't write any critical software or anything like that so crashes are not much of a concern for me. But I think there is value in forcing default and allow unsafe sections, when you encounter a crash, usually all you have to do is just go over the unsafe sections (which should be rare and limited in size) to find the culprit. I don't believe in "write crappy as needed and get better later" methodology, because that later usually never happens. And if you didn't write the safe code from the start, it's much harder to convert a codebase. Meanwhile, if you're writing it safe from the scratch, it's much easier as long as you follow some rules.
Jan 02 2020
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Thursday, 2 January 2020 at 21:29:48 UTC, JN wrote:
 encounter a crash, usually all you have to do is just go over 
 the unsafe sections (which should be rare and limited in size) 
 to find the culprit.
or just open the debugger and it tells you exactly where it happened. I'm slightly in favor of this dip, I've said before that as it is, the annotations are more hassle than they are worth, but think the swapped defaults would push it slightly over the edge. (I kinda feel the same about pure, nothrow, etc but it does get murkier there, especially since there's no equivalent to system and trusted there!) But the aid in debugging I don't think would help that much, it would be more about just making it lower cost for small library functions to adopt them, which would hopefully fan up to to other levels too.
Jan 02 2020
next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Jan 03, 2020 at 01:46:20AM +0000, Adam D. Ruppe via Digitalmars-d wrote:
[...]
 I'm slightly in favor of this dip, I've said before that as it is, the
 annotations are more hassle than they are worth, but think the swapped
 defaults would push it slightly over the edge. (I kinda feel the same
 about pure, nothrow, etc but it does get murkier there, especially
 since there's no equivalent to  system and  trusted there!)
[...] I'm for this DIP, but have reservations about the extent of code breakage it's going to cause and how to mitigate that. Just out of curiosity, I took one of my current projects this morning and started putting safe: on top of every file, just to see how far I got. I quickly ran into the issue that delegates are system by default, so I have to manually stick safe onto every one of them, which is a hassle, but I suppose wouldn't be a problem once safe becomes default. But it also leads to another issue: generic code can't reasonably just throw safe onto every delegate type, because sometimes you *want* to support system delegates. There are various ways of mitigating this, of course, but it involves a lot more code rewriting than I'd like to have when this DIP takes effect. Another issue is that taking the address of locals is verboten in safe code. It's generally found in self-contained code, but becomes a problem across 3rd party library API boundaries: if an API requires a pointer there's not much you can do about it without waiting for an upstream fix (which will break API with older code). I suppose trusted lambdas would be a workaround, but it does greatly uglify otherwise already-working code and again requires effort to rewrite/work around. So we better have a good, practical implementation schedule before merging this DIP. T -- Three out of two people have difficulties with fractions. -- Dirk Eddelbuettel
Jan 02 2020
next sibling parent Mathias Lang <pro.mathias.lang gmail.com> writes:
On Friday, 3 January 2020 at 07:40:14 UTC, H. S. Teoh wrote:
 Another issue is that taking the address of locals is verboten 
 in  safe code.
You can actually use DIP1000 to allow this. That's why it would be great to have a fully-working ' safe' before making it the default.
Jan 02 2020
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/2/2020 11:40 PM, H. S. Teoh wrote:
 Another issue is that taking the address of locals is verboten in  safe
 code. It's generally found in self-contained code, but becomes a problem
 across 3rd party library API boundaries: if an API requires a pointer
 there's not much you can do about it without waiting for an upstream fix
 (which will break API with older code).
In my experience, the fix for such things is to use `ref T` instead of `T*`. I know you can't change 3rd party code, so simply label those as system and move on after filing an enhancement request to the 3rd party. Or you can do this: ---- from 3rd Party ---- module fromThirdParty; system U thirdParty(T* p); ---- your code ---- import fromThirdParty; trusted U thirdParty(ref T t) { return fromThirdParty.thirdParty(&t); } ... safe void myParty() { T local; thirdParty(local); } Inlining will remove the wrapper call.
Jan 03 2020
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/2/2020 5:46 PM, Adam D. Ruppe wrote:
 or just open the debugger and it tells you exactly where it happened.
Oh, if only that were true. (I have decades of experience with this.)
Jan 03 2020
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Friday, 3 January 2020 at 11:31:43 UTC, Walter Bright wrote:
 Oh, if only that were true. (I have decades of experience with 
 this.)
I've had a few times when things got outright corrupted in D and those are indeed very difficult to find. But like my last snarky email said, D is different because we have RangeError. It is very rare that things get out of control here. Even in cases where we want to bypass range error, it can easily be done in isolation meaning the checks still protect you. This is both good and bad for this dip. Good: I suspect a majority of D code already qualifies for safe. The pain impact is likely to be small, and with the default set correctly, more libraries will work and those benefits can bubble up to user code. Bad: It is a bit of a hassle to deal with breakage when it comes up and the benefit is likely to be small, since most code is already free of the trouble it aims to solve. I fall a bit on the "yes" side since I do think the good slightly outweighs the bad. But let's not unfairly trash D as it stands to make this case stronger. We're already streets ahead of C++ even without this dip so talking about bad experiences and overall statistics from C and C++ don't necessarily apply to D.
Jan 03 2020
parent Atila Neves <atila.neves gmail.com> writes:
On Friday, 3 January 2020 at 14:36:26 UTC, Adam D. Ruppe wrote:

 Good: I suspect a majority of D code already qualifies for 
  safe.
Correct.
 The pain impact is likely to be small,
This is also my prediction.
 and with the default set correctly, more libraries will work 
 and those benefits can bubble up to user code.
Correct.
 Bad: It is a bit of a hassle to deal with breakage when it 
 comes up and the benefit is likely to be small, since most code 
 is already free of the trouble it aims to solve.
This can be gauged easily. Walter already has a PR, all we (me in all likelihood) have to do is try it on Phobos then packages from code.dlang.org.
 I fall a bit on the "yes" side since I do think the good 
 slightly outweighs the bad.
safe by default is strategically important for the language.
 But let's not unfairly trash D as it stands to make this case 
 stronger. We're already streets ahead of C++ even without this 
 dip so talking about bad experiences and overall statistics 
 from C and C++ don't necessarily apply to D.
One never knows how code in the wild is written, but with DIP1000 turned on and using only the GC, it's extremely rare for me to write code that doesn't qualify as safe even if not explicitly marked that way (but I always do).
Jan 03 2020
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/2/2020 9:06 AM, Guillaume Piolat wrote:
 - Never needed memory-safety, don't see the point, customers are not crying. 
 Will not need it in the future.
Buffer overflows (memory unsafety) are consistently at the top of the list of bugs leading to vulnerable software.
 - I'll just slap  trusted everywhere and call is a day
Arguably better to slap system everywhere.
 - I don't think D defaults are wrong, they let you write code that is 
 as-crappy-as-needed and gets better later.
That was indeed the idea behind unsafety as the default. But the programming world has changed. We don't have a choice.
    There is a performance difference.
Add system where you must.
Jan 03 2020
next sibling parent reply Guillaume Piolat <first.last gmail.com> writes:
On Friday, 3 January 2020 at 11:29:47 UTC, Walter Bright wrote:
 On 1/2/2020 9:06 AM, Guillaume Piolat wrote:
 - Never needed memory-safety, don't see the point, customers 
 are not crying. Will not need it in the future.
Buffer overflows (memory unsafety) are consistently at the top of the list of bugs leading to vulnerable software.
I think what will be useful is accepting the change as -preview, let us build with it and then see how many actual bugs it catched.
 - I'll just slap  trusted everywhere and call is a day
Arguably better to slap system everywhere.
Absolutely.
 That was indeed the idea behind unsafety as the default. But 
 the programming world has changed. We don't have a choice.
Well yes this sounds like the sort of decision that can avoid loss of millions in the far future. It's just a bit annoying, no biggie.
Jan 03 2020
next sibling parent Atila Neves <atila.neves gmail.com> writes:
On Friday, 3 January 2020 at 13:03:52 UTC, Guillaume Piolat wrote:
 On Friday, 3 January 2020 at 11:29:47 UTC, Walter Bright wrote:
 On 1/2/2020 9:06 AM, Guillaume Piolat wrote:
 - Never needed memory-safety, don't see the point, customers 
 are not crying. Will not need it in the future.
Buffer overflows (memory unsafety) are consistently at the top of the list of bugs leading to vulnerable software.
I think what will be useful is accepting the change as -preview, let us build with it and then see how many actual bugs it catched.
This has been how every other DIP has been introduced, I don't expect this one to be any different.
Jan 03 2020
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/3/2020 5:03 AM, Guillaume Piolat wrote:
 I think what will be useful is accepting the change as -preview, let us build 
 with it and then see how many actual bugs it catched.
That's what the DIP says!
 That was indeed the idea behind unsafety as the default. But the programming 
 world has changed. We don't have a choice.
Well yes this sounds like the sort of decision that can avoid loss of millions in the far future. It's just a bit annoying, no biggie.
Yes. Although it will break a lot of code, the fix (annotate with system where the compiler indicates) is straightforward.
Jan 03 2020
prev sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Friday, 3 January 2020 at 11:29:47 UTC, Walter Bright wrote:
 Buffer overflows (memory unsafety) are consistently at the top 
 of the list of bugs leading to vulnerable software.
You should try this new programming language I like a lot. It has built in range checking on this cool feature called slices. Instead of C style array, you slice the pointer and then the language knows the length and will check it on any access, throwing a range error if you go out of bounds. And with its built in dynamic arrays they are all slices so you don't even need to think about it. It is an awesome programming language and solves these problems with almost zero programming effort! Check it out some time at https://dlang.org/
Jan 03 2020
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/2/2020 6:39 AM, 12345swordy wrote:
 This issue is major blocking point
Issues that don't get put in bugzilla don't get fixed. Please tag all issues about safe with the `safe` keyword. Here is the current list: https://issues.dlang.org/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&keywords=safe&keywords_type=allwords&list_id=229570&query_format=advanced
Jan 02 2020
parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 3 January 2020 at 01:23:01 UTC, Walter Bright wrote:
 On 1/2/2020 6:39 AM, 12345swordy wrote:
 This issue is major blocking point
Issues that don't get put in bugzilla don't get fixed. Please tag all issues about safe with the `safe` keyword. Here is the current list: https://issues.dlang.org/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&keywords=safe&keywords_type=allwords&list_id=229570&query_format=advanced
Done, https://issues.dlang.org/show_bug.cgi?id=15246
Jan 02 2020
parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/2/2020 6:00 PM, 12345swordy wrote:
 Done,
 https://issues.dlang.org/show_bug.cgi?id=15246
Thank you.
Jan 03 2020
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/2/2020 6:39 AM, 12345swordy wrote:
 This dip, doesn't describe how to make the destroy function for classes safe,
as 
 the class deconstructors don't inherent the attributes from the parent class. 
Issues with safe that are not about making safe the default (i.e. not about the DIP) are off-topic. Please start a new thread with them.
Jan 02 2020
parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 3 January 2020 at 01:24:17 UTC, Walter Bright wrote:
 On 1/2/2020 6:39 AM, 12345swordy wrote:
 This dip, doesn't describe how to make the destroy function 
 for classes safe, as the class deconstructors don't inherent 
 the attributes from the parent class.
Issues with safe that are not about making safe the default (i.e. not about the DIP) are off-topic. Please start a new thread with them.
What about bugs for safe that require an DIP to fix then? Your dip doesn't address this at all. Your strategy seems to make it safe by default and not worry about any code that may be broken from using unsafe language features that can not be simply fix with a pull request. I don't see how this is in any way off-topic here. Is your current workaround for this is to abused the trusted feature?
Jan 02 2020
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/2/2020 6:42 PM, 12345swordy wrote:
 What about bugs for  safe that require an DIP to fix then? Your dip doesn't 
 address this at all.
Because this DIP is about making safe the default, not changing the behavior of safe.
 Your strategy seems to make it safe by default and not 
 worry about any code that may be broken from using unsafe language features
that 
 can not be simply fix with a pull request. I don't see how this is in any way 
 off-topic here. Is your current workaround for this is to abused the  trusted 
 feature?
I don't really understand what the problem is. Making code safe by default will not cause code to regress into bugginess. What it will do is necessitate labeling code with system that were always system already.
Jan 03 2020
parent reply bachmeier <no spam.net> writes:
On Friday, 3 January 2020 at 10:37:15 UTC, Walter Bright wrote:
 I don't really understand what the problem is.
That a lot of working code will no longer compile without wasting a lot of time fixing it, including having to make changes to code you didn't write but are calling.
 Making code  safe by default will not cause code to regress 
 into bugginess.
But it won't compile, even though it does *exactly* what it's supposed to do. I don't think this is a complicated point. And the fact that all the documentation and forum posts currently on the internet will be broken. And the fact that this makes it harder for people to learn the language.
 What it will do is necessitate labeling code with  system that 
 were always  system already.
I'll send you my code and hopefully you can make all the necessary changes in a timely manner. Frankly, I'm shocked that you all of a sudden think major breaking changes in the language are no big deal. What really has me puzzled is that this is a change with such a limited benefit. D already has safe. If you want to make safe by default an option, add a -safe flag to the compiler and the problem is solved with no code breakage and no confusion, and you can appeal to the tiny sliver of programmers Rust was created for and that will never be interested in D anyway. Breaking changes can be good, but careful thought needs to be used to minimize the cost of those changes.
Jan 03 2020
parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/3/2020 12:02 PM, bachmeier wrote:
 What it will do is necessitate labeling code with  system that were always 
  system already.
I'll send you my code and hopefully you can make all the necessary changes in a timely manner. Frankly, I'm shocked that you all of a sudden think major breaking changes in the language are no big deal.
No refactoring, changing data structures, anything like that, will be required. It's just adding system where the compiler indicates. Most of the job will be simply adding: system: to the beginning of the file. Something similar to this was done to the DMD backend after it was converted to D - a bunch of `nothrow:` lines were inserted at the beginning of the modules. Didn't take more than a few minutes.
 What really has me puzzled is that this is a change with such a limited
benefit. 
 D already has  safe. If you want to make safe by default an option, add a
-safe 
 flag to the compiler
This feature is enabled with -preview=safedefault. You'll have years to it which to pick a time to annotate with system as required.
 and the problem is solved with no code breakage and no 
 confusion, and you can appeal to the tiny sliver of programmers Rust was
created 
 for and that will never be interested in D anyway. Breaking changes can be
good, 
 but careful thought needs to be used to minimize the cost of those changes.
Rust has changed the conversation. Major languages are all already safe by default, or are moving that direction. We don't have a choice.
Jan 03 2020
prev sibling next sibling parent reply Arine <arine123445128843 gmail.com> writes:
  Fortunately, the solution is easy, although tedious: annotate 
 functions that aren't safe with  trusted or  system.
If you could annotate the module with system to use the old behavior, this will ease the transition period. This is better than simply having a compiler flag that changes behavior, as you can see in the code that is using the old behavior. You can also disable it per module, not either on or off for everything. system module std.stdio; // or similar require hacks like using a lambda to declare a section of code as unsafe as you have to do in D. safe void foo() { // ... () trusted { // ... } (); // ... } Since this DIP is so bare bones anyways, I'd be inclined to include these changes as part of this DIP.
Jan 02 2020
next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Jan 02, 2020 at 05:27:22PM +0000, Arine via Digitalmars-d wrote:
  Fortunately, the solution is easy, although tedious: annotate
  functions that aren't safe with  trusted or  system.
If you could annotate the module with system to use the old behavior, this will ease the transition period. This is better than simply having a compiler flag that changes behavior, as you can see in the code that is using the old behavior. You can also disable it per module, not either on or off for everything. system module std.stdio; // or similar
You can already do this today: module blah; system: ... // everything here defaults to system Of course, today this does nothing because system is the default, but you can already mark an entire module as safe the same way, for example. T -- This is not a sentence.
Jan 02 2020
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/2/20 12:38 PM, H. S. Teoh wrote:
 On Thu, Jan 02, 2020 at 05:27:22PM +0000, Arine via Digitalmars-d wrote:
   Fortunately, the solution is easy, although tedious: annotate
   functions that aren't safe with  trusted or  system.
If you could annotate the module with system to use the old behavior, this will ease the transition period. This is better than simply having a compiler flag that changes behavior, as you can see in the code that is using the old behavior. You can also disable it per module, not either on or off for everything. system module std.stdio; // or similar
You can already do this today: module blah; system: ... // everything here defaults to system Of course, today this does nothing because system is the default, but you can already mark an entire module as safe the same way, for example.
This is erroneous. It marks all templates system, which would otherwise be inferred safe. And it does not mark member functions. I think the idea of marking a module system is good, but the usage is confusing. What you want to affect is the *default* assumption. You need a pragma. -Steve
Jan 03 2020
parent reply Eugene Wissner <belka caraus.de> writes:
On Friday, 3 January 2020 at 15:38:02 UTC, Steven Schveighoffer 
wrote:
 This is erroneous. It marks all templates  system, which would 
 otherwise be inferred  safe.

 And it does not mark member functions.
I think it applies only to other attributes. import std.traits; system: struct S { void func()() { } } static assert(!isSafe!(S.func!()));
Jan 03 2020
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/3/20 10:48 AM, Eugene Wissner wrote:
 On Friday, 3 January 2020 at 15:38:02 UTC, Steven Schveighoffer wrote:
 This is erroneous. It marks all templates  system, which would 
 otherwise be inferred  safe.

 And it does not mark member functions.
I think it applies only to other attributes. import std.traits; system: struct S {   void func()()   {   } } static assert(!isSafe!(S.func!()));
It seems you are right! But I could have sworn I had to mark member functions as safe when modifying projects to be safe. I'll have to re-check and see if there are cases where it doesn't work. -Steve
Jan 03 2020
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/2/2020 9:27 AM, Arine wrote:
 If you could annotate the module with  system to use the old behavior, this
will 
 ease the transition period. This is better than simply having a compiler flag 
 that changes behavior, as you can see in the code that is using the old 
 behavior. You can also disable it per module, not either on or off for
everything.
 
       system module std.stdio; // or similar
We already have that in starting a module with: system:

 like using a lambda to declare a section of code as unsafe as you have to do
in D.
 
 
  safe void foo() {
 
      // ...
 
      ()  trusted {
          // ...
      } ();
 
      // ...
 }
 
 Since this DIP is so bare bones anyways, I'd be inclined to include these 
 changes as part of this DIP.
This DIP is not about changing how trusted code is inserted. If you'd like to discuss that, please start a separate thread. Please keep this thread on-topic about the DIP.
Jan 02 2020
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 03.01.20 02:31, Walter Bright wrote:
 On 1/2/2020 9:27 AM, Arine wrote:
 If you could annotate the module with  system to use the old behavior, 
 this will ease the transition period. This is better than simply 
 having a compiler flag that changes behavior, as you can see in the 
 code that is using the old behavior. You can also disable it per 
 module, not either on or off for everything.

       system module std.stdio; // or similar
We already have that in starting a module with:     system:
This will not result in the old behavior. It will disable inference of safe in that module.
Jan 02 2020
parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/2/2020 6:11 PM, Timon Gehr wrote:
 On 03.01.20 02:31, Walter Bright wrote:
 On 1/2/2020 9:27 AM, Arine wrote:
 If you could annotate the module with  system to use the old behavior, this 
 will ease the transition period. This is better than simply having a compiler 
 flag that changes behavior, as you can see in the code that is using the old 
 behavior. You can also disable it per module, not either on or off for 
 everything.

       system module std.stdio; // or similar
We already have that in starting a module with:      system:
This will not result in the old behavior. It will disable inference of safe in that module.
Ah, you're right for template code.
Jan 03 2020
prev sibling parent reply Arine <arine123445128843 gmail.com> writes:
On Friday, 3 January 2020 at 01:31:26 UTC, Walter Bright wrote:
 This DIP is not about changing how trusted code is inserted. If 
 you'd like to discuss that, please start a separate thread. 
 Please keep this thread on-topic about the DIP.
If issues with safe aren't going to be considered with this DIP, then I'd say this DIP should be delayed until issues with safe are resolved before forcing it as the default. Don't think I can think of a language that is safe by default that needs to use a hack with a separate language feature to get desired behavior.
Jan 02 2020
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/2/2020 9:20 PM, Arine wrote:
 On Friday, 3 January 2020 at 01:31:26 UTC, Walter Bright wrote:
 This DIP is not about changing how trusted code is inserted. If you'd like to 
 discuss that, please start a separate thread. Please keep this thread on-topic 
 about the DIP.
If issues with safe aren't going to be considered with this DIP, then I'd say this DIP should be delayed until issues with safe are resolved before forcing it as the default.
No. We don't have time to do all development serially.
 Don't think I can think of a language that is safe by default 
 that needs to use a hack with a separate language feature to get desired
behavior.
Issues not in bugzilla do not get fixed. Please put all issues with safe in bugzilla and mark them with the `safe` keyword. Then, when bringing up a problem or set of problems, link to the corresponding issues. There's NOTHING AT ALL anyone can do with statements like "needs to use a hack" because nobody has any idea what you're referring to.
Jan 03 2020
parent reply Arine <arine123445128843 gmail.com> writes:
On Friday, 3 January 2020 at 11:20:35 UTC, Walter Bright wrote:
On Friday, 3 January 2020 at 11:20:35 UTC, Walter Bright wrote:
 On 1/2/2020 9:20 PM, Arine wrote:
 On Friday, 3 January 2020 at 01:31:26 UTC, Walter Bright wrote:
 This DIP is not about changing how trusted code is inserted. 
 If you'd like to discuss that, please start a separate 
 thread. Please keep this thread on-topic about the DIP.
If issues with safe aren't going to be considered with this DIP, then I'd say this DIP should be delayed until issues with safe are resolved before forcing it as the default.
No. We don't have time to do all development serially
Then this would be better served as an opt in feature. This is going to be a big breaking change, and if you are going to do the same thing with `nothrow`, that's way too much breakage for very little benefit just to follow a trend. Especially if steps aren't going to be taken to ensure it is easy to maintain backwards compatibility. As someone else mentions system: does not give the same behavior and will still break code.
 Issues not in bugzilla do not get fixed. Please put all issues 
 with  safe in bugzilla and mark them with the `safe` keyword.

 Then, when bringing up a problem or set of problems, link to 
 the corresponding issues.

 There's NOTHING AT ALL anyone can do with statements like 
 "needs to use a hack" because nobody has any idea what you're 
 referring to.
There's probably already an issue filed for it. It comes up often. I don't have the time right now to search through tens of thousands of unmanaged issues for you. I already gave an example in my preview post.
Jan 03 2020
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/3/2020 5:57 AM, Arine wrote:
 Then this would be better served as an opt in feature.
It will be opt-in for a time, that's why it will be enabled with -preview=safedefault
 This is going to be a big 
 breaking change, and if you are going to do the same thing with `nothrow`, 
 that's way too much breakage for very little benefit just to follow a trend.
There are compelling reasons for nothrow by default. I suggest deferring this discussion until the DIP is put forward for review.
 Especially if steps aren't going to be taken to ensure it is easy to maintain 
 backwards compatibility. As someone else mentions
 
  system:
 
 does not give the same behavior and will still break code.
It's still easy to deal with.
 There's probably already an issue filed for it. It comes up often. I don't
have 
 the time right now to search through tens of thousands of unmanaged issues for 
 you. I already gave an example in my preview post.
Spending time guessing and speculating on what it might be does a disservice to those who do spend the time filing issues, on which I and others do spend effort to address.
 tens of thousands of unmanaged issues
This is why there are bugzilla keywords for categorizing issues, like `safe` for all safety related issues: https://issues.dlang.org/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&keywords=safe&keywords_type=allwords&list_id=229608&query_format=advanced
Jan 03 2020
next sibling parent reply Johan <j j.nl> writes:
On Friday, 3 January 2020 at 22:59:53 UTC, Walter Bright wrote:
 On 1/3/2020 5:57 AM, Arine wrote:
 Then this would be better served as an opt in feature.
It will be opt-in for a time, that's why it will be enabled with -preview=safedefault
Yes please.
 Especially if steps aren't going to be taken to ensure it is 
 easy to maintain backwards compatibility. As someone else 
 mentions
 
  system:
 
 does not give the same behavior and will still break code.
It's still easy to deal with.
I expect the change of default to be a _lot_ of work to deal with at Weka. I think it will not be easy at all, because there is a lot of templated code and code checking whether something compiles or not (`__traits(compiles)`). Every compiler update changes what compiles and does not compiles, and it is almost always very hard to track down how that changes the behavior of Weka's code. (If something doesn't compile, the error happens in a template that cannot be instantiated because some template 5 layers down is not instantiatable for example. The error won't say that of course...) With the safe change, I'm expecting 100s of templates that will no longer compile or change behavior, and for very few of the compile errors will it be obvious what is going on. As said before, ` system:` is not going to help. I have no opinion on whether this is a good change or not. I just very much would like to get the message across that this change will be very disruptive and so please provide a long deprecation time (e.g. something like 2 years). -Johan
Jan 03 2020
parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/3/2020 3:30 PM, Johan wrote:
 I expect the change of default to be a _lot_ of work to deal with at Weka. I 
 think it will not be easy at all, because there is a lot of templated code and 
 code checking whether something compiles or not (`__traits(compiles)`). Every 
 compiler update changes what compiles and does not compiles, and it is almost 
 always very hard to track down how that changes the behavior of Weka's code.
(If 
 something doesn't compile, the error happens in a template that cannot be 
 instantiated because some template 5 layers down is not instantiatable for 
 example. The error won't say that of course...)
 With the  safe change, I'm expecting 100s of templates that will no longer 
 compile or change behavior, and for very few of the compile errors will it be 
 obvious what is going on. As said before, ` system:` is not going to help.
Templates without an explicit safe/ trusted/ system will still get their safety attributes inferred as before.
 I have no opinion on whether this is a good change or not. I just very much 
 would like to get the message across that this change will be very disruptive 
 and so please provide a long deprecation time (e.g. something like 2 years).
That's probably a good idea. Keep in mind that even when it is no longer a -preview feature, there'll be a -revert switch there for a long time to continue to use the old behavior. I am interested to hear about your experience with this on Weka's codebase, and am open to your advice on the timing.
Jan 03 2020
prev sibling next sibling parent Arine <arine123445128843 gmail.com> writes:
On Friday, 3 January 2020 at 22:59:53 UTC, Walter Bright wrote:
 On 1/3/2020 5:57 AM, Arine wrote:
 Then this would be better served as an opt in feature.
It will be opt-in for a time, that's why it will be enabled with -preview=safedefault
No one is going to really use that, they'll just wait til it's required. I'm already dreading some of the deprecations that there already are. It'll break my code and the fixes for it will make it worse than it was. At which point when it becomes an error I'll probably just stick with an older version, or build my own variant with a patch to turn it off.
 This is going to be a big breaking change, and if you are 
 going to do the same thing with `nothrow`, that's way too much 
 breakage for very little benefit just to follow a trend.
There are compelling reasons for nothrow by default. I suggest deferring this discussion until the DIP is put forward for review.
 Especially if steps aren't going to be taken to ensure it is 
 easy to maintain backwards compatibility. As someone else 
 mentions
 
  system:
 
 does not give the same behavior and will still break code.
It's still easy to deal with.
It's more work. It doesn't matter if it is easy. I worked for a company where one of the developers REALLLY hated warnings. So much so that he changed all the variable and class names because the standard. Part of the problem was the serialization used reflection so changing the variable/class names was a breaking change for this API. This API interfaced with our software and it was the only way to interface with our software. The only way to get data into our software to use was through this API. So now for our customers to use our software they had to wait for an updated version with our partners. The thing is, the partners were telling their customers to not upgrade to the newest version of our software. It was a mess for our customers and the companies we partnered with. He didn't listen to reason, having no warnings was more important to him, and another companies problem was their problem. Sure changing the names is easy, but it's boring tedious grunt work that's a waste of time for very little to no benefit.
 There's probably already an issue filed for it. It comes up 
 often. I don't have the time right now to search through tens 
 of thousands of unmanaged issues for you. I already gave an 
 example in my preview post.
Spending time guessing and speculating on what it might be does a disservice to those who do spend the time filing issues, on which I and others do spend effort to address.
 tens of thousands of unmanaged issues
This is why there are bugzilla keywords for categorizing issues, like `safe` for all safety related issues: https://issues.dlang.org/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&keywords=safe&keywords_type=allwords&list_id=229608&query_format=advanced
That doesn't mean those categorizations are used. No body is ensuring they are set. Anyone can set them, they can set them incorrectly, no one checks for duplicates, no one is making sure that an issue is even relevant or accomplish-able. There's issues that are 5+ years old, some of them with no comments. Some of them with comments promising to get it fixed. I don't know how you can point to a list of categories and just because they exist, claim that the issue list isn't an unmanaged mess.
Jan 04 2020
prev sibling parent reply Arine <arine123445128843 gmail.com> writes:
On Friday, 3 January 2020 at 22:59:53 UTC, Walter Bright wrote:
 This is going to be a big breaking change, and if you are 
 going to do the same thing with `nothrow`, that's way too much 
 breakage for very little benefit just to follow a trend.
There are compelling reasons for nothrow by default. I suggest deferring this discussion until the DIP is put forward for review.
An expression comes to mind, "death by a thousand cuts". If you are only going to look at each DIP on it's own, without also taking into consideration other DIPs, then you aren't going to realize just how much breakage the accumulation of all the DIPs is actually causing. There's been a lot of DIPs that cause a bunch of breaking changes recently. They are all small, but it's all starting to add up. And the breakage is starting to outweigh the benefits that they bring. To me personally for my projects, they don't really bring any benefit, but they still break my code.
Jan 04 2020
parent IGotD- <nise nise.com> writes:
On Saturday, 4 January 2020 at 16:16:30 UTC, Arine wrote:
 On Friday, 3 January 2020 at 22:59:53 UTC, Walter Bright wrote:
 This is going to be a big breaking change, and if you are 
 going to do the same thing with `nothrow`, that's way too 
 much breakage for very little benefit just to follow a trend.
There are compelling reasons for nothrow by default. I suggest deferring this discussion until the DIP is put forward for review.
An expression comes to mind, "death by a thousand cuts". If you are only going to look at each DIP on it's own, without also taking into consideration other DIPs, then you aren't going to realize just how much breakage the accumulation of all the DIPs is actually causing. There's been a lot of DIPs that cause a bunch of breaking changes recently. They are all small, but it's all starting to add up. And the breakage is starting to outweigh the benefits that they bring. To me personally for my projects, they don't really bring any benefit, but they still break my code.
We need to have a separate discussion about the strategy for breaking changes. We might even agree with the change but the change has an impact on the current codebase that wants to us to disagree with the change. Walter have hinted several ideas about changing the D syntax, several of the that I agree with but just changing the current compiler causes problems. In the pipeline are changes like "nothrow" by default, "final" by default which is like to see but perhaps it is time to start working on D3 and leave the current compiler in maintenance mode. By doing this we can speed up the development of the "new D" instead of being held back by compatibility worries.
Jan 04 2020
prev sibling next sibling parent IGotD- <nise nise.com> writes:
On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1028, "Make  safe the Default":

 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688554b/DIPs/DIP1028.md

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

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

 Anyone intending to post feedback in this thread is expected to 
 be familiar with the reviewer guidelines:

 https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md

 *Please stay on topic!*

 Thanks in advance to all who participate.
Since this breaks virtually all code out there I suggest that safe by default will be a compiler option only. Anyone who wants the functions to be safe by default must specify so in the compiler options or the build system. Also many people here don't care about this "safe" trend right now. The feature is good but cannot be enforced because of backwards compatibility. Maybe in D3.
Jan 02 2020
prev sibling next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/2/2020 1:47 AM, Mike Parker wrote:
 This is the feedback thread for the first round of Community Review for DIP 
 1028, "Make  safe the Default":
 
 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688554b/DIPs/DIP1028.md
Implementation: https://github.com/dlang/dmd/pull/10709
Jan 02 2020
prev sibling next sibling parent reply Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1028, "Make  safe the Default":

 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688554b/DIPs/DIP1028.md
I think the DIP should specify the depreciation plan. Currently it only mentions it would be available through --preview (is it not expect to go further?
Jan 02 2020
next sibling parent Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
On Friday, 3 January 2020 at 05:57:09 UTC, Jesse Phillips wrote:
 On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1028, "Make  safe the Default":

 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688554b/DIPs/DIP1028.md
I think the DIP should specify the depreciation plan. Currently it only mentions it would be available through --preview (is it not expect to go further?
I think this could even be as simple as, "a new DIP will be created defining a plan for timing and requirements to make this default" I think many are hung up on the fact that this DIP is only specifying a preview switch and not the actual change to the language. Rightly so, DIPs are about the end game. We don't have a good plan for making these larger breaking changes. I did try to start such a discussion because I saw these coming. https://forum.dlang.org/post/bfgpindcvbjmxscsgudh forum.dlang.org Other replies please us a separate thread to discuss release planning. Let's help to define the DIP improvement so Walter can move forward.
Jan 03 2020
prev sibling parent reply Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
On Friday, 3 January 2020 at 05:57:09 UTC, Jesse Phillips wrote:
 On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1028, "Make  safe the Default":

 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688554b/DIPs/DIP1028.md
I think the DIP should specify the depreciation plan. Currently it only mentions it would be available through --preview (is it not expect to go further?
Another thought to depreciation, the compiler could deprecated system functions which aren't marked system. This depreciation would ignore all method calls. This basically means functions utilizing unsafe language features must declare that use in the signature. The next part I'll need to think on is if there is a way to build out the trusted annotations.
Jan 03 2020
parent Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
On Saturday, 4 January 2020 at 05:43:25 UTC, Jesse Phillips wrote:
 On Friday, 3 January 2020 at 05:57:09 UTC, Jesse Phillips wrote:
 On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1028, "Make  safe the Default":

 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688554b/DIPs/DIP1028.md
I think the DIP should specify the depreciation plan. Currently it only mentions it would be available through --preview (is it not expect to go further?
Another thought to depreciation, the compiler could deprecated system functions which aren't marked system. This depreciation would ignore all method calls. This basically means functions utilizing unsafe language features must declare that use in the signature. The next part I'll need to think on is if there is a way to build out the trusted annotations.
With the above rule in place and taking precedence, the next depreciation would be that unmarked methods could not call into system methods. This would cause a chain effect until a method was marked trusted or the marking of system was added to main. There was an effort to show projects build state if safe was default. These depreciations should have no ill effect on building projects as they will not have unmarked system code. One of the main benefits here is that it creates a resolution from the bottom up instead of the top down. If safe were just made default then resolution for what code is trusted would likely favor higher in the call chain will this depreciation approach encourages creation of a trusted interface quickly.
Jan 08 2020
prev sibling next sibling parent reply Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1028, "Make  safe the Default":

 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688554b/DIPs/DIP1028.md
I would part of the rational would be: A large portion of functions should find themselves performing safe operations. Leaving off prevents the use of safe functions which were not evaluated for safety (safe functions remain usable in system functions). This would be the same rational to apply nothrow by default. Though it may not have the same qualities of benefits.
Jan 02 2020
parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/2/2020 10:14 PM, Jesse Phillips wrote:
 I would part of the rational would be: A large portion of functions should
find 
 themselves performing safe operations. Leaving off prevents the use of safe 
 functions which were not evaluated for safety (safe functions remain usable in 
 system functions).
 
 This would be the same rational to apply nothrow by default. Though it may not 
 have the same qualities of benefits.
There's another DIP coming that will make nothrow the default. Please, anyone replying to this, start another thread for it.
Jan 03 2020
prev sibling next sibling parent reply Mathias Lang <pro.mathias.lang gmail.com> writes:
On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1028, "Make  safe the Default":
On paper, this sounds like a great idea. Make ' safe' the default so people have to opt out of memory safety rather than opt-in. However, we have extensive experience with those changes (and how they are handled), and I am not, as it stands, in favor of it. First, because ' safe', and attributes by extension, is currently not a practical tool, and even not usable in some cases. It is currently painful to mix differently-attributed code if you are not going full template (e.g. classes, delegates). I've worked for two companies using D, and none of them used safe, and were more on the low-level side of things. In fact, safe wouldn't even have prevented most of the bug we had, as they were fibers stack overflow (I'm sure any fiber user know what I'm talking about). Second because those kind of changes have historically been badly handled, as the impact is not fully assessed. For such a large and impactful change, I would expect the proposer of the DIP to assess the impact of this change on a few projects, in order to provide a data point. Either go with major D projects, and/or pull a sample for the dub registry, to gauge the hassle, performance and readability degradation it can bring. Yet DMD is not safe. Neither is druntime. DUB, Vibe.d ? Neither. And I've seen countless places where ' safe' is either forced on the user (by forcing the user to provide ' safe' routines), or just bypassed by means of ' trusted'. Just take a look at Vibe.d. Side note, using this flag to compile Phobos would most likely result in link failures, like it did with DIP1000. Third, we start to have a few DIPs piling up in the -preview section. DIP25, DIP1000, DIP1008. Some libraries use it, some don't, and adding more features there will only balkanize the language more. Let's not repeat the `std.experimental` experience with the compiler, and actually finish what we started. TL;DR: Disruptive change that requires every D user to put some work to support it (possibly many months worth of work), yet no evidence that a single large-scale project have been experimented with while writing this DIP.
Jan 02 2020
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/2/2020 10:31 PM, Mathias Lang wrote:
 On paper, this sounds like a great idea. Make ' safe' the default so people
have 
 to opt out of memory safety rather than opt-in. However, we have extensive 
 experience with those changes (and how they are handled), and I am not, as it 
 stands, in favor of it.
Modules can be labeled as system by beginning them with: system:
 First, because ' safe', and attributes by extension, is currently not a 
 practical tool, and even not usable in some cases.
Issues not in bugzilla do not get fixed. Please add issues that make it not practical or usable to bugzilla and mark them with the `safe` keyword.
 It is currently painful to 
 mix differently-attributed code if you are not going full template (e.g. 
 classes, delegates). I've worked for two companies using D, and none of them 
 used  safe, and were more on the low-level side of things.
It is true that using safe successfully will often entail some level of refactoring to separate the safe code from unsafe code. It is perfectly fine if you choose to not use safe.
 In fact,  safe wouldn't even have prevented most of the bug we had,
Most is not all, and the bugs it does uncover tend to be the ugly ones. I recently spent 3 days trying to track down a memory corruption bug in DMD. These are not happy hours for me. Detecting problems at compile time is infinitely cheaper. It's also the future. It's clear where languages are going. Unsafe languages are going on the ash heap of history. We can either get in front of this sea change, or get run over by it.
 Second because those kind of changes have historically been badly handled, as 
 the impact is not fully assessed. For such a large and impactful change, I
would 
 expect the proposer of the DIP to assess the impact of this change on a few 
 projects, in order to provide a data point. Either go with major D projects, 
 and/or pull a sample for the dub registry, to gauge the hassle, performance
and 
 readability degradation it can bring.
 Yet DMD is not  safe. Neither is druntime. DUB, Vibe.d ? Neither. And I've
seen 
 countless places where ' safe' is either forced on the user (by forcing the
user 
 to provide ' safe' routines), or just bypassed by means of ' trusted'. Just
take 
 a look at Vibe.d.
The simplest way to be compatible with the switch is to simply label things that don't compile as system. Or just put system: at the beginning. As for DMD, I intend to take advantage of this feature as soon as it is accepted. Keep in mind that DMD was originally a "C with Classes" program, with no notion of safe (or const, pure, nothrow, or nogc).
 Side note, using this flag to compile Phobos would most likely result in link 
 failures, like it did with DIP1000.
We fixed the link failures with DIP1000.
 Third, we start to have a few DIPs piling up in the -preview section. DIP25, 
 DIP1000, DIP1008. Some libraries use it, some don't, and adding more features 
 there will only balkanize the language more.
All programming languages improve or die.
 actually finish what we started.
All issues need to go into bugzilla. Issues not in bugzilla do not get fixed.
 TL;DR: Disruptive change that requires every D user to put some work to
support 
 it (possibly many months worth of work), yet no evidence that a single 
 large-scale project have been experimented with while writing this DIP.
Nobody will try it, either, unless and until it is actually put into the compiler.
Jan 03 2020
next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/3/20 6:06 AM, Walter Bright wrote:
 On 1/2/2020 10:31 PM, Mathias Lang wrote:
 On paper, this sounds like a great idea. Make ' safe' the default so 
 people have to opt out of memory safety rather than opt-in. However, 
 we have extensive experience with those changes (and how they are 
 handled), and I am not, as it stands, in favor of it.
Modules can be labeled as system by beginning them with:    system:
This does not work for member functions (also a valid criticism of the suggestion to mark a module safe) It also is almost always not what you want, as this then forces templates to be system. In other words, marking safe: at the top makes sense, you can fix all the compiler errors that result. Putting system: at the top is not going to have the same effect, things that really are safe will work when marked as system. You want as LITTLE as possible to be marked system, not a blanket marking. This should not be a suggestion. Take the time to assess why a function is not working, and mark it system only if it needs to be. -Steve
Jan 03 2020
parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/3/2020 7:29 AM, Steven Schveighoffer wrote:
 You want as LITTLE as possible to be marked  system, not a blanket marking.
Sure, but if you want to do as little work as possible, blanket marking will do most of the job.
Jan 03 2020
prev sibling parent reply Mathias Lang <pro.mathias.lang gmail.com> writes:
On Friday, 3 January 2020 at 11:06:32 UTC, Walter Bright wrote:
 Modules can be labeled as  system by beginning them with:

     system:
As mentioned countless times already, this has a widely different effect.
 First, because ' safe', and attributes by extension, is 
 currently not a practical tool, and even not usable in some 
 cases.
Issues not in bugzilla do not get fixed. Please add issues that make it not practical or usable to bugzilla and mark them with the `safe` keyword.
https://issues.dlang.org/show_bug.cgi?id=17953 This affects object.Throwable.toString. I'm not asking for that specific syntax, but we do need a way to say "delegate attributes in, delegate attributes out".
 It is currently painful to mix differently-attributed code if 
 you are not going full template (e.g. classes, delegates). 
 I've worked for two companies using D, and none of them used 
  safe, and were more on the low-level side of things.
It is true that using safe successfully will often entail some level of refactoring to separate the safe code from unsafe code. It is perfectly fine if you choose to not use safe.
Except that I do not control all the code I write. Some libraries will use ` safe` everywhere, some won't. And mixing them becomes a nightmare. For example, I'd be very happy to live without ` safe`, but I use Vibe.d, which forces ` safe` on me because some people wanted to be able to use ` safe` in the first place. This is the kind of ecosystem split people keep talking about.
 In fact,  safe wouldn't even have prevented most of the bug we 
 had,
Most is not all, and the bugs it does uncover tend to be the ugly ones. I recently spent 3 days trying to track down a memory corruption bug in DMD. These are not happy hours for me. Detecting problems at compile time is infinitely cheaper.
In terms of cost/benefit ratio, it does not cross the mark for me. I also recently spent 3 days debugging a memory corruption issue, happening because of a stack overflow, something ` safe` can't prevent. So here's another anecdotal evidence for your anecdotal evidence.
 It's also the future. It's clear where languages are going. 
 Unsafe languages are going on the ash heap of history. We can 
 either get in front of this sea change, or get run over by it.
If I wanted to be using Rust, I would be using Rust.
 The simplest way to be compatible with the switch is to simply 
 label things that don't compile as  system. Or just put 
  system: at the beginning.

 As for DMD, I intend to take advantage of this feature as soon 
 as it is accepted. Keep in mind that DMD was originally a "C 
 with Classes" program, with no notion of  safe (or const, pure, 
 nothrow, or nogc).
And I invite you to try it already (you don't need it to be merged to start fixing ` safe`ty issues) to see the effect. Note that DMD is not a library and has almost no dependency, which makes fixing issues much simpler.
 Side note, using this flag to compile Phobos would most likely 
 result in link failures, like it did with DIP1000.
We fixed the link failures with DIP1000.
Because `scope` is ignored for mangling. ` safe` cannot be ignored, so the same solution cannot be used.
 Third, we start to have a few DIPs piling up in the -preview 
 section. DIP25, DIP1000, DIP1008. Some libraries use it, some 
 don't, and adding more features there will only balkanize the 
 language more.
All programming languages improve or die.
I don't disagree with improving the language, I disagree with the way of doing it. If ` safe` was hassle-free we wouldn't be having this conversation, but it's not, and making it the default just switch the hassle to someone else.
 actually finish what we started.
All issues need to go into bugzilla. Issues not in bugzilla do not get fixed.
There's a trove of issues in bugzilla to pick from. But put in simpler terms: Where is ` safe` reference counting ?
 TL;DR: Disruptive change that requires every D user to put 
 some work to support it (possibly many months worth of work), 
 yet no evidence that a single large-scale project have been 
 experimented with while writing this DIP.
Nobody will try it, either, unless and until it is actually put into the compiler.
And then, nobody will try it unless druntime / Phobos is compiled with it. But then we're back to the point where it's not really opt-in because of link failures. I'll add more of that on the PR itself.
Jan 07 2020
parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/7/2020 10:38 AM, Mathias Lang wrote:
 Except that I do not control all the code I write. Some libraries will use 
 ` safe` everywhere, some won't. And mixing them becomes a nightmare. For 
 example, I'd be very happy to live without ` safe`, but I use Vibe.d, which 
 forces ` safe` on me because some people wanted to be able to use ` safe` in
the 
 first place. This is the kind of ecosystem split people keep talking about.
Defaulting to safe will ironically mitigate these types of issues. I understand this will cause some disruption. I don't know of any way to avoid it. The best we've come up with is -preview/-revert switches. The worst you'll have to do is manually add system to individual functions.
 If I wanted to be using Rust, I would be using Rust.
I don't want to use Rust, either.
 But put in simpler terms: Where is ` safe` reference counting ?
There have been a number of DIPs which help in that direction.
 And then, nobody will try it unless druntime / Phobos is compiled with it. But 
 then we're back to the point where it's not really opt-in because of link 
 failures. I'll add more of that on the PR itself.
For Phobos to work with and without the -preview switch, it'll likely need specific system/ trusted/ safe annotations on all non-inferred functions. It's mostly done already anyway, this will just help us finish the job.
Jan 07 2020
prev sibling next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2020-01-02 10:47, Mike Parker wrote:
 This is the feedback thread for the first round of Community Review for 
 DIP 1028, "Make  safe the Default":
 
 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688
54b/DIPs/DIP1028.md 
With a DIP causing this large breakage I expect the DIP to be accompanied with a tool that will do the following automatically: * Annotate the source code to retain the current semantics, i.e. basically annotate all non-inferred functions with system * Annotate all non-inferred functions in the source code with safe where it would compile -- /Jacob Carlborg
Jan 03 2020
parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/3/2020 12:59 AM, Jacob Carlborg wrote:
 With a DIP causing this large breakage I expect the DIP to be accompanied with
a 
 tool that will do the following automatically:
 
 * Annotate the source code to retain the current semantics, i.e. basically 
 annotate all non-inferred functions with  system
 
 * Annotate all non-inferred functions in the source code with  safe where it 
 would compile
Such a tool would indeed be welcome. Please write it! (Perhaps modify dfix?)
Jan 03 2020
prev sibling next sibling parent Dennis <dkorpel gmail.com> writes:
On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688554b/DIPs/DIP1028.md

The rationale is short and makes claims without any motivation, such as:
 the costs of unsafe code have become ever more apparent and 
 expensive
 Users expect safety to be opt-out, not opt-in
It doesn't answer questions such as: - how many D users actually prefer safe by default, and how many prefer system? - how many memory corruption bugs actually happen in D code that is system, and how many in code that is safe? - how much existing D code can be marked safe but currently isn't? Consequently the DIP does not give the reader enough information to judge whether this is a good idea. The DIP author guidelines state:
 It is vital to research any alternative approaches to solving 
 the same problem and explain why the proposed choice is 
 superior.
There currently is no mention of any alternatives however. Some things that can be considered: - A linting tool that automatically inserts ` safe` annotations where possible. Any time a D library can be marked ` safe` but the author forgot to annotate functions with ` safe`, a Pull Request can easily be made adding the missing annotations. - Adding an option to specify safe/ system by default in code, such as ` safe module foo;` or ` system module foo;`. Note that this is not the same as putting ` safe:` or ` system:` on top, since: ``` system: auto canBeSafe() {} // is system, would be safe without the above ` system:` struct S { void memberFunc(); // unaffected by module-level annotation } ``` These options don't have the code breakage that the proposed solution has, while arguably solving most of the same issues. Interestingly, 3.5 years ago you said safe by default would break too much code and adding ` safe:` on top of a module is very doable: https://forum.dlang.org/post/nj73gp$1q3k$1 digitalmars.com It makes me wonder why safe becoming the default is deemed necessary now. What changed?

The DIP doesn't mention how functions without a body will implicitly become ` trusted`. ``` import std; extern(C) size_t strlen(const(char)*); // safe by default void main() { strlen(new char).writeln; // this now passes as safe } ```
 Functions such as template functions, nested functions, and 
 lambdas that are not annotated currently have their  safe / 
  system attribute inferred.
Functions with return type `auto` also have attributes inferred. I think they should be mentioned in there too, unless you want functions with `auto` return type to always be assumed safe:
 Any other unannotated function that will now be assumed to be 
  safe rather than  system.
Jan 03 2020
prev sibling next sibling parent reply Manu <turkeyman gmail.com> writes:
On Thu, Jan 2, 2020 at 7:50 PM Mike Parker via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 This is the feedback thread for the first round of Community
 Review for DIP 1028, "Make  safe the Default":

 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688554b/DIPs/DIP1028.md

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

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

 Anyone intending to post feedback in this thread is expected to
 be familiar with the reviewer guidelines:

 https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md

 *Please stay on topic!*

 Thanks in advance to all who participate.
FWIW, I'm not emotional about this, but it seems like a really good opportunity to change system to unsafe, since system appears almost nowhere in existing code (because is default). 'system' is a weird name for 'unsafe'. I've had lots of colleagues tell me they think it doesn't make sense... and I agree. It's a silly name, and defies the industries established terminology for no reason. We have exactly one opportunity to correct this, and this is it.
Jan 03 2020
next sibling parent David Gileadi <gileadisNOSPM gmail.com> writes:
On 1/3/20 6:43 AM, Manu wrote:
 FWIW, I'm not emotional about this, but it seems like a really good
 opportunity to change  system to  unsafe, since  system appears almost
 nowhere in existing code (because is default).
 'system' is a weird name for 'unsafe'. I've had lots of colleagues
 tell me they think it doesn't make sense... and I agree. It's a silly
 name, and defies the industries established terminology for no reason.
 We have exactly one opportunity to correct this, and this is it.
+1
Jan 03 2020
prev sibling next sibling parent reply Dennis Cote <private secret.com> writes:
On Friday, 3 January 2020 at 13:43:27 UTC, Manu wrote:
 'system' is a weird name for 'unsafe'. ...
 We have exactly one opportunity to correct this, and this is it.
I was going to give this a +1, but upon further reflection, I think system is more correct. The code that would be marked unsafe is only "potentially unsafe". In most cases, the code that would be marked as unsafe is bug-free and perfectly safe to execute. system is intended as a warning that this code requires careful consideration before making changes. It is a "here be dragons" type warning, not an indication that there are problems in this piece of code. There could be a better name than system, but I don't think unsafe is a better choice because it implies there "is" a problem with the code rather than just saying "be cautious". Dennis Cote
Jan 03 2020
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Friday, 3 January 2020 at 19:03:46 UTC, Dennis Cote wrote:
 The code that would be marked  unsafe is only "potentially 
 unsafe". In most cases, the code that would be marked as 
  unsafe is bug-free and perfectly safe to execute.
"unsafe" is the defacto terminology for code that isn't type checked, i.e. verified. "safe" means that it is verified: type-safety, memory-safety etc. An unsafe type system is a type system that can be broken if you make an effort to break it. It is still unsafe if nobody ever wrote any code that broke it. Type safety is about providing mechanical guarantees that cannot be broken no matter what code you write.
 but I don't think  unsafe is a better choice because it implies 
 there "is" a problem with the code rather than just saying "be 
 cautious".
It tells the compiler that the code is intended to not be type checked for memory safety, so it intentionally unsafe (e.g. unchecked). Code is not safe until it has been mechanically verified. This is standard usage of the term safe and unsafe.
Jan 03 2020
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/3/2020 5:43 AM, Manu wrote:
 FWIW, I'm not emotional about this, but it seems like a really good
 opportunity to change  system to  unsafe, since  system appears almost
 nowhere in existing code (because is default).
 'system' is a weird name for 'unsafe'. I've had lots of colleagues
 tell me they think it doesn't make sense... and I agree. It's a silly
 name, and defies the industries established terminology for no reason.
 We have exactly one opportunity to correct this, and this is it.
Andrei and I talked about this for a while before coming up with 'system'. We both felt that calling it 'unsafe' had undeserved negative connotations.
Jan 03 2020
parent reply Manu <turkeyman gmail.com> writes:
On Sat, Jan 4, 2020 at 2:30 PM Walter Bright via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On 1/3/2020 5:43 AM, Manu wrote:
 FWIW, I'm not emotional about this, but it seems like a really good
 opportunity to change  system to  unsafe, since  system appears almost
 nowhere in existing code (because is default).
 'system' is a weird name for 'unsafe'. I've had lots of colleagues
 tell me they think it doesn't make sense... and I agree. It's a silly
 name, and defies the industries established terminology for no reason.
 We have exactly one opportunity to correct this, and this is it.
Andrei and I talked about this for a while before coming up with 'system'. We both felt that calling it 'unsafe' had undeserved negative connotations.
Okay. Well all feedback I've received is that it fails at the rule of least surprise. Definitely not intuitive what it means. I think it may be possible to see and consider the situation differently when looking from a safe-by-default perspective; today where 'system' is default, you wouldn't want to advertise the language as "unsafe by default"... but if safe is default, than 'unsafe' feels a lot more reasonable for the exceptions. I reckon the change in default may change your judgement that you describe above.
Jan 06 2020
next sibling parent reply Max Samukha <maxsamukha gmail.com> writes:
On Monday, 6 January 2020 at 23:59:28 UTC, Manu wrote:

 Well all feedback I've received is that it fails at the rule of 
 least
 surprise.
admitted publicly that "unsafe" was a misnomer.
Jan 06 2020
next sibling parent reply Paulo Pinto <pjmlp progtools.org> writes:
On Tuesday, 7 January 2020 at 06:24:11 UTC, Max Samukha wrote:
 On Monday, 6 January 2020 at 23:59:28 UTC, Manu wrote:

 Well all feedback I've received is that it fails at the rule 
 of least
 surprise.
admitted publicly that "unsafe" was a misnomer.
The very first systems programming language that introduced the concept of unsafe blocks was ESPOL, followed by NEWP for the Burrougs B5500, in 1961. Other idea that they introduced, at the OS level, was that any binary containing unsafe code was tainted and required clearance from the system admin to be executable. 8 years before C was even an idea. Unsafe has a long tradition in safe systems programming languages, and D is one of very few exceptions that has chosen something else.
Jan 06 2020
next sibling parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 7 January 2020 at 07:14:43 UTC, Paulo Pinto wrote:
 The very first systems programming language that introduced the 
 concept of unsafe blocks was ESPOL, followed by NEWP for the 
 Burrougs B5500, in 1961.
Thanks for sharing, some fun stuff (Wikipedia): «The original designer of the project was a Texan and soon started to describe the name as the answer to the question, "Is it done yet?". NEWP sounded like a West Texas version of "nope". Once the project was released, the name was "redefined" to stand for "No Executive Washroom Privileges" - a description of the type of person who would likely use the language.» Love how some obscure internal office humour 60 years later makes it into an encyclopedia... :-D
Jan 06 2020
parent Paulo Pinto <pjmlp progtools.org> writes:
On Tuesday, 7 January 2020 at 07:57:06 UTC, Ola Fosheim Grøstad 
wrote:
 On Tuesday, 7 January 2020 at 07:14:43 UTC, Paulo Pinto wrote:
 The very first systems programming language that introduced 
 the concept of unsafe blocks was ESPOL, followed by NEWP for 
 the Burrougs B5500, in 1961.
Thanks for sharing, some fun stuff (Wikipedia): «The original designer of the project was a Texan and soon started to describe the name as the answer to the question, "Is it done yet?". NEWP sounded like a West Texas version of "nope". Once the project was released, the name was "redefined" to stand for "No Executive Washroom Privileges" - a description of the type of person who would likely use the language.» Love how some obscure internal office humour 60 years later makes it into an encyclopedia... :-D
It is also one of the oldest OS still being developed, nowadays it is known as ClearPath MCP, sold by Unisys, and security is naturally their main selling point.
Jan 07 2020
prev sibling parent reply Max Samukha <maxsamukha gmail.com> writes:
On Tuesday, 7 January 2020 at 07:14:43 UTC, Paulo Pinto wrote:

 The very first systems programming language that introduced the 
 concept of unsafe blocks was ESPOL, followed by NEWP for the 
 Burrougs B5500, in 1961.

 Other idea that they introduced, at the OS level, was that any 
 binary containing unsafe code was tainted and required 
 clearance from the system admin to be executable.

 8 years before C was even an idea.

 Unsafe has a long tradition in safe systems programming 
 languages, and D is one of very few exceptions that has chosen 
 something else.
introduce the concept or name. I said that I didn't like the name is really a tradition, which is arguable.
Jan 07 2020
parent Paulo Pinto <pjmlp progtools.org> writes:
On Tuesday, 7 January 2020 at 10:22:08 UTC, Max Samukha wrote:
 On Tuesday, 7 January 2020 at 07:14:43 UTC, Paulo Pinto wrote:

 The very first systems programming language that introduced 
 the concept of unsafe blocks was ESPOL, followed by NEWP for 
 the Burrougs B5500, in 1961.

 Other idea that they introduced, at the OS level, was that any 
 binary containing unsafe code was tainted and required 
 clearance from the system admin to be executable.

 8 years before C was even an idea.

 Unsafe has a long tradition in safe systems programming 
 languages, and D is one of very few exceptions that has chosen 
 something else.
introduce the concept or name. I said that I didn't like the there is really a tradition, which is arguable.
If we count the amount of safe system programming languages that have used unsafe and the others that have used something else, unsafe leads. D ( system), Ada (Unchecked), Oberon variants (SYSTEM pseudo-module) are the only ones that occur to me as not following up on unsafe.
Jan 07 2020
prev sibling next sibling parent reply Manu <turkeyman gmail.com> writes:
On Tue, Jan 7, 2020 at 4:25 PM Max Samukha via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On Monday, 6 January 2020 at 23:59:28 UTC, Manu wrote:

 Well all feedback I've received is that it fails at the rule of
 least
 surprise.
admitted publicly that "unsafe" was a misnomer.
And 'system' is more logical and self-explanatory? Perhaps you can offer some other suggestions? I think it would have to be unusually compelling to break from industry accepted convention.
Jan 07 2020
parent reply Max Samukha <maxsamukha gmail.com> writes:
On Tuesday, 7 January 2020 at 08:42:07 UTC, Manu wrote:

 And 'system' is more logical and self-explanatory? Perhaps you 
 can
 offer some other suggestions?
Nice piece of rhetoric. I didn't even say anything about "system". No, it is not more logical or self-explanatory (like most identifiers, it is only vaguely hints at the actual semantics). No, I am not going to suggest anything - system is ok with me. I don't feel too strong against "unsafe" either.
 I think it would have to be unusually compelling to break from
 industry accepted convention.
I don't think there is such thing as "industry accepted convention" with regard to "unsafe".
Jan 07 2020
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 7 January 2020 at 10:01:29 UTC, Max Samukha wrote:
 I don't think there is such thing as "industry accepted 
 convention" with regard to "unsafe".
It is standard terminology for program semantics going unchecked both statically and dynamically. "unsafe" does not say that the written code is doing anything wrong. "unsafe" means that the compiler isn't doing what is expected from a proper high level language in terms of catching illegal constructs. A language defines a set of text strings that is considered legal (valid) code. In a well specced language all legal code is safe. Most compilers fail to catch all illegal constructs and will emit code for programs that does not belong to the defined language. A decent (safe) language will then emit runtime checks that will catch such programs at runtime and stop them (e.g. indexes out of bounds). However, in an unsafe language, or unsafe language mode, or unsafe language constructs, the compiler and runtime will not detect and stop programs that don't belong to the defined language. That is the meaning of "unsafe".
Jan 07 2020
next sibling parent reply JN <666total wp.pl> writes:
On Tuesday, 7 January 2020 at 10:25:36 UTC, Ola Fosheim Grøstad 
wrote:
 "unsafe" does not say that the written code is doing anything 
 wrong. "unsafe" means that the compiler isn't doing what is 
 expected from a proper high level language in terms of catching 
 illegal constructs.
I actually like how "unsafe" sounds dangerous. It sounds like something to be avoided, and that's how unsafe should be used in a safe-aware code. You should avoid using it unless needed, and when used it should scream at you "this is dangerous". Kind of like UPPERCASE_DEFINE_MACROS in C.
Jan 07 2020
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 7 January 2020 at 11:10:03 UTC, JN wrote:
 I actually like how "unsafe" sounds dangerous. It sounds like 
 something to be avoided, and that's how unsafe should be used 
 in a safe-aware code.
Exactly, like walking on a line without a safety rope, biking without a helmet, using a chainsaw without protective gear... Unsafe = higher probability for failure. Analogy: I've never cut into my protective gear with a chain saw, but I've been close several times... You can work much faster with protective gear on as you can focus more on the work and keep the saw close (which makes the work more precise).
 You should avoid using it unless needed, and when used it 
 should scream at you "this is dangerous". Kind of like 
 UPPERCASE_DEFINE_MACROS in C.
An interesting point is that a language competing directly with C must be an unsafe language. A Turing complete language must emit runtime checks in order to finish static analysis in finite time (unless you put in fixed limits).
Jan 07 2020
prev sibling parent reply Max Samukha <maxsamukha gmail.com> writes:
On Tuesday, 7 January 2020 at 10:25:36 UTC, Ola Fosheim Grøstad 
wrote:

 However, in an unsafe language, or unsafe language mode, or 
 unsafe language constructs, the compiler and runtime will not 
 detect and stop programs that don't belong to the defined 
 language.

 That is the meaning of "unsafe".
Yeah, I know about that definition of "unsafe", thank you for a lecture on basic CS. I still cannot agree that the term "unsafe" is measurably more conventional than "unchecked" or "system".
Jan 07 2020
next sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 7 January 2020 at 13:32:32 UTC, Max Samukha wrote:
 I still cannot agree that the term "unsafe" is measurably more 
 conventional than "unchecked" or "system".
"unchecked" seems reasonable, but "system" could be interpreted as access to operating system specific features rather than fully portable features.
Jan 07 2020
prev sibling next sibling parent NaN <divide by.zero> writes:
On Tuesday, 7 January 2020 at 13:32:32 UTC, Max Samukha wrote:
 On Tuesday, 7 January 2020 at 10:25:36 UTC, Ola Fosheim Grøstad 
 wrote:

 However, in an unsafe language, or unsafe language mode, or 
 unsafe language constructs, the compiler and runtime will not 
 detect and stop programs that don't belong to the defined 
 language.

 That is the meaning of "unsafe".
Yeah, I know about that definition of "unsafe", thank you for a lecture on basic CS. I still cannot agree that the term "unsafe" is measurably more conventional than "unchecked" or "system".
How about "shrug" or "meh"? IE... "it might work ok but I couldn't be arsed to check."
Jan 07 2020
prev sibling parent Arine <arine123445128843 gmail.com> writes:
On Tuesday, 7 January 2020 at 13:32:32 UTC, Max Samukha wrote:
 On Tuesday, 7 January 2020 at 10:25:36 UTC, Ola Fosheim Grøstad 
 wrote:

 However, in an unsafe language, or unsafe language mode, or 
 unsafe language constructs, the compiler and runtime will not 
 detect and stop programs that don't belong to the defined 
 language.

 That is the meaning of "unsafe".
Yeah, I know about that definition of "unsafe", thank you for a lecture on basic CS. I still cannot agree that the term "unsafe" is measurably more conventional than "unchecked" or "system".
extern(System) safe void foo() { } I think system is over used as it is. And unsafe makes more sense than unchecked. Putting a ladder on a table is unsafe, it doesn't mean something bad is going to happen if you do. It just has more potential relatively to putting it on the ground.
Jan 07 2020
prev sibling parent Guillaume Piolat <first.last gmail.com> writes:
On Tuesday, 7 January 2020 at 06:24:11 UTC, Max Samukha wrote:
 On Monday, 6 January 2020 at 23:59:28 UTC, Manu wrote:

 Well all feedback I've received is that it fails at the rule 
 of least
 surprise.
admitted publicly that "unsafe" was a misnomer.
I like " system" as a name. I'll live almost entirely in system since pointers seems to perform well (not the least is that you are guaranteed no bounds check). system code isn't necessarily broken, and I don't necessarily want to read "unsafe" all day.
Jan 08 2020
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/6/2020 3:59 PM, Manu wrote:
 Well all feedback I've received is that it fails at the rule of least
 surprise. Definitely not intuitive what it means.
I'm frankly surprised at this. Yours is literally the first complaint about using `system` in 10 years that has come to my ears. Also, a safe/unsafe dichotomy can make sense. But a safe/trusted/unsafe makes less sense, like a 3 state boolean.
 I think it may be possible to see and consider the situation
 differently when looking from a safe-by-default perspective; today
 where 'system' is default, you wouldn't want to advertise the language
 as "unsafe by default"... but if safe is default, than 'unsafe' feels
 a lot more reasonable for the exceptions. I reckon the change in
 default may change your judgement that you describe above.
`static` in C makes no particular sense, but people are so used to it that they imagine it makes perfect sense :-) Nobody expects to be able to implement a storage allocator in code that is provably correct. Nobody expects the implementation of atomic shared operations to to be provably. People have historically called such underpinnings "system" code (long before there was a notion of "unsafe"), where the dirty but necessary work happens. Steamships had white-glove service to the passengers, and the greasy dirty work went on in the "system" under the decks to support it all. Whether "system" is intuitive or not is how you frame it. It's a perfect moniker. It is not "unsafe", it just means the compiler cannot prove it safe.
Jan 07 2020
next sibling parent Les De Ridder <les lesderid.net> writes:
On Wednesday, 8 January 2020 at 02:48:19 UTC, Walter Bright wrote:
 On 1/6/2020 3:59 PM, Manu wrote:
 Well all feedback I've received is that it fails at the rule 
 of least
 surprise. Definitely not intuitive what it means.
I'm frankly surprised at this. Yours is literally the first complaint about using `system` in 10 years that has come to my ears.
I was confused by the naming too at first.
Jan 07 2020
prev sibling next sibling parent reply Arine <arine123445128843 gmail.com> writes:
On Wednesday, 8 January 2020 at 02:48:19 UTC, Walter Bright wrote:
 On 1/6/2020 3:59 PM, Manu wrote:
 Well all feedback I've received is that it fails at the rule 
 of least
 surprise. Definitely not intuitive what it means.
I'm frankly surprised at this. Yours is literally the first complaint about using `system` in 10 years that has come to my ears. Also, a safe/unsafe dichotomy can make sense. But a safe/trusted/unsafe makes less sense, like a 3 state boolean.
trusted doesn't really make sense. It is pretty much system that safe can call. It's actually kind of bad as how easily it can be misused. trusted: comes to mind. You can have trusted destructors. So when you are reading safe code you can't easily tell where potentially unsafe code is located. As the trusted If we are going to make safe the default we don't really need safe keyword, or system or trusted. It's make sense to get rid of all 3 of them and just add unsafe. If you are going to do it, might as well do it right the first time. safe void potentialProblem() { A a; where(); is(); the(); potential(); problem(here ? maybe() : maybeNot()); } // safe by default // void potentialProblem() { A a; where(); is(); unsafe { the(); // easily identifiable } potential(); problem(here ? maybe() : maybeNot()); }
 I think it may be possible to see and consider the situation
 differently when looking from a safe-by-default perspective; 
 today
 where 'system' is default, you wouldn't want to advertise the 
 language
 as "unsafe by default"... but if safe is default, than 
 'unsafe' feels
 a lot more reasonable for the exceptions. I reckon the change 
 in
 default may change your judgement that you describe above.
`static` in C makes no particular sense, but people are so used to it that they imagine it makes perfect sense :-) Nobody expects to be able to implement a storage allocator in code that is provably correct. Nobody expects the implementation of atomic shared operations to to be provably. People have historically called such underpinnings "system" code (long before there was a notion of "unsafe"), where the dirty but necessary work happens. Steamships had white-glove service to the passengers, and the greasy dirty work went on in the "system" under the decks to support it all. Whether "system" is intuitive or not is how you frame it. It's a perfect moniker. It is not "unsafe", it just means the compiler cannot prove it safe.
If you can't prove it is safe, logic dictates it should then be identified as unsafe.
Jan 07 2020
next sibling parent Manu <turkeyman gmail.com> writes:
On Wed, Jan 8, 2020 at 5:15 PM Arine via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On Wednesday, 8 January 2020 at 02:48:19 UTC, Walter Bright wrote:
 On 1/6/2020 3:59 PM, Manu wrote:
 Well all feedback I've received is that it fails at the rule
 of least
 surprise. Definitely not intuitive what it means.
I'm frankly surprised at this. Yours is literally the first complaint about using `system` in 10 years that has come to my ears. Also, a safe/unsafe dichotomy can make sense. But a safe/trusted/unsafe makes less sense, like a 3 state boolean.
trusted doesn't really make sense. It is pretty much system that safe can call. It's actually kind of bad as how easily it can be misused. trusted: comes to mind. You can have trusted destructors. So when you are reading safe code you can't easily tell where potentially unsafe code is located. As the trusted If we are going to make safe the default we don't really need safe keyword, or system or trusted. It's make sense to get rid of all 3 of them and just add unsafe. If you are going to do it, might as well do it right the first time. safe void potentialProblem() { A a; where(); is(); the(); potential(); problem(here ? maybe() : maybeNot()); } // safe by default // void potentialProblem() { A a; where(); is(); unsafe { the(); // easily identifiable } potential(); problem(here ? maybe() : maybeNot()); }
Actually, this is a really good point! I've had this thought many times.
Jan 08 2020
prev sibling next sibling parent Mathias Lang <pro.mathias.lang gmail.com> writes:
On Wednesday, 8 January 2020 at 07:10:03 UTC, Arine wrote:
 If we are going to make  safe the default we don't really need 
  safe keyword, or  system or  trusted. It's make sense to get 
 rid of all 3 of them and just add  unsafe. If you are going to 
 do it, might as well do it right the first time.
Removing ` safe` as a keyword removes the ability to force templates to be ` safe`.
Jan 08 2020
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 08.01.20 08:10, Arine wrote:
 
  trusted doesn't really make sense. It is pretty much  system that  safe 
 can call. It's actually kind of bad as how easily it can be misused. 
  trusted: comes to mind. You can have  trusted destructors. So when you 
 are reading  safe code you can't easily tell where potentially  unsafe 
 code is located. As the  trusted is applied to the function, not at the 

 ...
This line of reasoning makes no sense. trusted void foo(T...)(T args){ ... } is like safe void foo(T...)(T args){ unsafe{ ... } } It's the same thing. The point is that the interface of foo is assumed to safe by all callers even though the implementation might not be.
 If we are going to make  safe the default we don't really need  safe 
 keyword, or  system or  trusted. It's make sense to get rid of all 3 of 
 them and just add  unsafe. If you are going to do it, might as well do 
 it right the first time.
I don't care all that much either way, but let's not pretend that what you propose is different to what we have in any important way other than how convenient certain things are to express. Adding trusted statement blocks and deprecating ` trusted:` annotations would have essentially the same effect.
Jan 08 2020
next sibling parent reply Manu <turkeyman gmail.com> writes:
On Thu, Jan 9, 2020 at 5:01 AM Timon Gehr via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On 08.01.20 08:10, Arine wrote:
  trusted doesn't really make sense. It is pretty much  system that  safe
 can call. It's actually kind of bad as how easily it can be misused.
  trusted: comes to mind. You can have  trusted destructors. So when you
 are reading  safe code you can't easily tell where potentially  unsafe
 code is located. As the  trusted is applied to the function, not at the

 ...
This line of reasoning makes no sense. trusted void foo(T...)(T args){ ... } is like safe void foo(T...)(T args){ unsafe{ ... } } It's the same thing. The point is that the interface of foo is assumed to safe by all callers even though the implementation might not be.
 If we are going to make  safe the default we don't really need  safe
 keyword, or  system or  trusted. It's make sense to get rid of all 3 of
 them and just add  unsafe. If you are going to do it, might as well do
 it right the first time.
I don't care all that much either way, but let's not pretend that what you propose is different to what we have in any important way other than how convenient certain things are to express. Adding trusted statement blocks and deprecating ` trusted:` annotations would have essentially the same effect.
unsafe blocks is distinctly preferable to me. Functions are usually >1 line, and I hate that we can only mark this at the function level. Unsafely statements are never at the function level, it's usually just one line among a larger function. An unsafe scope would be immensely preferable to me, because I can make it as narrow as the code i'm suspicious of, and the surrounding code doesn't lose its safe checking just by being a bystander.
Jan 08 2020
next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/8/2020 4:12 PM, Manu wrote:
 unsafe blocks is distinctly preferable to me. Functions are usually >1
 line, and I hate that we can only mark this at the function level.
 Unsafely statements are never at the function level, it's usually just
 one line among a larger function. An unsafe scope would be immensely
 preferable to me, because I can make it as narrow as the code i'm
 suspicious of, and the surrounding code doesn't lose its safe checking
 just by being a bystander.
This is routinely done in Phobos by making a tiny one line anonymous trusted lambda and immediately calling it. The compiler will inline it.
Jan 08 2020
parent reply Manu <turkeyman gmail.com> writes:
On Thu, Jan 9, 2020 at 3:30 PM Walter Bright via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On 1/8/2020 4:12 PM, Manu wrote:
 unsafe blocks is distinctly preferable to me. Functions are usually >1
 line, and I hate that we can only mark this at the function level.
 Unsafely statements are never at the function level, it's usually just
 one line among a larger function. An unsafe scope would be immensely
 preferable to me, because I can make it as narrow as the code i'm
 suspicious of, and the surrounding code doesn't lose its safe checking
 just by being a bystander.
This is routinely done in Phobos by making a tiny one line anonymous trusted lambda and immediately calling it. The compiler will inline it.
Unacceptable and embarrassing. The compiler does not inline it (appears to be subject to optimisation), and LDC/GDC implement different inlining rules where the compilers internal heuristics are undesirably perturbed by this 'pattern'.
Jan 08 2020
parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/8/2020 9:57 PM, Manu wrote:
 This is routinely done in Phobos by making a tiny one line anonymous  trusted
 lambda and immediately calling it. The compiler will inline it.
Unacceptable and embarrassing. The compiler does not inline it (appears to be subject to optimisation),
You have to use the -inline switch (for DMD), that's true.
 and LDC/GDC implement different inlining rules where
 the compilers internal heuristics are undesirably perturbed by this
 'pattern'.
It's a one-expression lambda. Why wouldn't it inline? I use one liner functions all the time, expecting them to inline. It's pervasive in D. Of course, I always use -inline for release builds.
Jan 15 2020
prev sibling parent reply Johannes Pfau <nospam example.com> writes:
Am Thu, 09 Jan 2020 10:12:23 +1000 schrieb Manu:

 
 unsafe blocks is distinctly preferable to me. Functions are usually >1
 line, and I hate that we can only mark this at the function level.
 Unsafely statements are never at the function level, it's usually just
 one line among a larger function. An unsafe scope would be immensely
 preferable to me, because I can make it as narrow as the code i'm
 suspicious of, and the surrounding code doesn't lose its safe checking
 just by being a bystander.
I agree that the lambda thing is an ugly hack and proper trusted blocks would be better. However, I wonder how languages with such blocks deal with problems such as these: safe void someFunction() { int[4] data; // Lot's of code trusted { data.ptr[3] = 42; } } Now someone changes data to int[2]: safe void someFunction() { int[2] data; // Lot's of code trusted { data.ptr[3] = 42; } } So by modifying safe code only, you introduced a memory safety issue. The interface of a trusted function however is more strictly defined: trusted function set(ref int[4] data) { data.ptr[3] = 42; } It's not possible to break the set function in safe code. You could probably argue that the trusted block in someFunction should have covered the int[2] data definition and that you can also write trusted functions which do not properly check / enforce their parameters and can be broken from safe code. But still, it seems like applying trusted/safe at function level provides stronger guarantees. I wonder how other languages deal with that? Not at all and just be extra careful when writing trusted blocks? -- Johannes
Jan 09 2020
next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/9/20 1:47 PM, Johannes Pfau wrote:

 So by modifying  safe code only, you introduced a memory safety issue.
Yes, this is why a function with ANY trusted blocks must be examined completely, and changes to the non-trusted parts must be checked to see if they cause problems with the trusted blocks. HOWEVER, it is still of tremendous value to have the rest of it mechanically checked. So I still prefer this usage to trusting the whole function.
 But still, it seems like applying trusted/safe at function level provides
 stronger guarantees. I wonder how other languages deal with that? Not at
 all and just be extra careful when writing trusted blocks?
 
Yes, this is exactly correct. Trust must happen at the function level, because that's where you can reason about the parameters and returns. Marking it safe is not really because the function is safe, it's because marking the WHOLE function trusted is to forgo all checking inside the function, which is not what you normally want. If we could design it again, probably you should have safe and system be what they are today, trusted would be safe, except where you put in unsafe blocks. This allows the code to pick which parts should be able to call system functions. But I think this is digressing from the DIP discussion quite a bit. Probably best to continue if necessary in a new thread. -Steve
Jan 09 2020
next sibling parent Arine <arine123445128843 gmail.com> writes:
On Thursday, 9 January 2020 at 19:00:27 UTC, Steven Schveighoffer 
wrote:
 But I think this is digressing from the DIP discussion quite a 
 bit. Probably best to continue if necessary in a new thread.

 -Steve
I don't agree. This is discussing a method to implement safe be default. If you are going to make a breaking change that causes almost all code to not compile, all tutorials and documentation to be invalidated. Every existing discussion to become obsolete. It makes sense to view all options. D's proposed safe by default use one keyword and unsafe blocks. Even though it lists Rust and detail about how D's implementation is fundamentally different on" safety, you can only turn it off with a keyword.
Jan 09 2020
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 09.01.20 20:00, Steven Schveighoffer wrote:
 On 1/9/20 1:47 PM, Johannes Pfau wrote:
 
 So by modifying  safe code only, you introduced a memory safety issue.
Yes, this is why a function with ANY trusted blocks must be examined completely, and changes to the non-trusted parts must be checked to see if they cause problems with the trusted blocks. HOWEVER, it is still of tremendous value to have the rest of it mechanically checked. So I still prefer this usage to trusting the whole function.
If your trusted code relies on safe code to maintain safety-critical invariants, your trusted code is broken. Any reasonable formalization of trusted would declare such an usage invalid, so lowering the scope of trusted to small blocks is not per se desirable. safe code can't be trusted. It may be edited by programmers who are not allowed to write trusted code.
Jan 09 2020
next sibling parent reply IGotD- <nise nise.com> writes:
On Thursday, 9 January 2020 at 19:22:28 UTC, Timon Gehr wrote:
 On 09.01.20 20:00, Steven Schveighoffer wrote:

 If your  trusted code relies on  safe code to maintain 
 safety-critical invariants, your  trusted code is broken. Any 
 reasonable formalization of  trusted would declare such an 
 usage invalid, so lowering the scope of  trusted to small 
 blocks is not per se desirable.

  safe code can't be trusted. It may be edited by programmers 
 who are not allowed to write  trusted code.
trusted is a completely unnecessary declaration and should be removed. This DIP should really already assume that trusted is removed. There are safe and unsafe (or system or whatever you call it). Safe code can call unsafe code a vice versa and it is the responsibility of the programmer to test the code and use the libraries the programmer think are stable enough. If you think about it there isn't a "middle", an almost safe, "I promise my trusted code is bug free".
Jan 09 2020
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 09.01.20 20:34, IGotD- wrote:
 On Thursday, 9 January 2020 at 19:22:28 UTC, Timon Gehr wrote:
 On 09.01.20 20:00, Steven Schveighoffer wrote:

 If your  trusted code relies on  safe code to maintain safety-critical 
 invariants, your  trusted code is broken. Any reasonable formalization 
 of  trusted would declare such an usage invalid, so lowering the scope 
 of  trusted to small blocks is not per se desirable.

  safe code can't be trusted. It may be edited by programmers who are 
 not allowed to write  trusted code.
trusted is a completely unnecessary declaration and should be removed. This DIP should really already assume that trusted is removed. There are safe and unsafe (or system or whatever you call it). Safe code can call unsafe code a vice versa and it is the responsibility of the programmer to test the code and use the libraries the programmer think are stable enough. If you think about it there isn't a "middle", an almost safe, "I promise my trusted code is bug free".
Sorry, but this is plain nonsense. Please read the documentation.
Jan 09 2020
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/9/20 2:22 PM, Timon Gehr wrote:
 On 09.01.20 20:00, Steven Schveighoffer wrote:
 On 1/9/20 1:47 PM, Johannes Pfau wrote:

 So by modifying  safe code only, you introduced a memory safety issue.
Yes, this is why a function with ANY trusted blocks must be examined completely, and changes to the non-trusted parts must be checked to see if they cause problems with the trusted blocks. HOWEVER, it is still of tremendous value to have the rest of it mechanically checked. So I still prefer this usage to trusting the whole function.
If your trusted code relies on safe code to maintain safety-critical invariants, your trusted code is broken. Any reasonable formalization of trusted would declare such an usage invalid, so lowering the scope of trusted to small blocks is not per se desirable. safe code can't be trusted. It may be edited by programmers who are not allowed to write trusted code.
I'm not saying it's safe. I'm saying I want the mechanical checking outside the trusted escape. e.g. I want the compiler to check these parts, but I know this one part needs trusting. D doesn't give a better way to express this other than safe code with trusted escapes. If I could mark the whole thing trusted, and turn on the mechanical checking for everything except line X, then I'd do that instead. -Steve
Jan 09 2020
next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Jan 09, 2020 at 02:35:36PM -0500, Steven Schveighoffer via
Digitalmars-d wrote:
 On 1/9/20 2:22 PM, Timon Gehr wrote:
[...]
  safe code can't be trusted. It may be edited by programmers who are
 not allowed to write  trusted code.
I'm not saying it's safe. I'm saying I want the mechanical checking outside the trusted escape. e.g. I want the compiler to check these parts, but I know this one part needs trusting. D doesn't give a better way to express this other than safe code with trusted escapes.
[...] Yeah, I also consider this to be valuable. Another way of doing the same thing is that trusted *doesn't* allow unsafe operations by default, it just marks that function as needing to be manually verified, but within that function you have to explicitly mark out which parts are to be trusted: auto myfunc(Args args) trusted { ... // only safe code allowed here system { ... // system code allowed here } ... // only safe code allowed here } The idea is that you want the compiler to statically check everything outside that nested system block so that no unsafe operations are permitted there, so that you can isolate block the code that requires temporary suspension of safe checks to a small, self-contained block. But the function as a whole cannot be marked safe because the system block within interacts with the surrounding code, so you cannot guarantee the resulting combination will actually be safe. The function still needs to be audited *as a whole* for safety, but with the benefit that the compiler is also helping with part of the auditing by prohibiting potentially unsafe operations outside explicitly-marked blocks. Inside a non- trusted function, system blocks would be completely verboten. ( system functions don't need such blocks because they're entirely system already.) T -- It always amuses me that Windows has a Safe Mode during bootup. Does that mean that Windows is normally unsafe?
Jan 09 2020
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 09.01.20 20:59, H. S. Teoh wrote:
 On Thu, Jan 09, 2020 at 02:35:36PM -0500, Steven Schveighoffer via
Digitalmars-d wrote:
 On 1/9/20 2:22 PM, Timon Gehr wrote:
[...]
  safe code can't be trusted. It may be edited by programmers who are
 not allowed to write  trusted code.
I'm not saying it's safe. I'm saying I want the mechanical checking outside the trusted escape. e.g. I want the compiler to check these parts, but I know this one part needs trusting. D doesn't give a better way to express this other than safe code with trusted escapes.
[...] Yeah, I also consider this to be valuable. Another way of doing the same thing is that trusted *doesn't* allow unsafe operations by default, it just marks that function as needing to be manually verified, but within that function you have to explicitly mark out which parts are to be trusted: ... T
I like this proposal (but there should be system _expressions_ too). It would also fix accidentally trusting your template alias parameters. Probably this is going a bit far off-topic now though.
Jan 09 2020
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/9/20 2:59 PM, H. S. Teoh wrote:

 Yeah, I also consider this to be valuable.  Another way of doing the
 same thing is that  trusted *doesn't* allow unsafe operations by
 default, it just marks that function as needing to be manually verified,
 but within that function you have to explicitly mark out which parts are
 to be trusted:
 
 	auto myfunc(Args args)  trusted {
 		... // only  safe code allowed here
 		 system {
 			... //  system code allowed here
 		}
 		... // only  safe code allowed here
 	}
Right, that's what I said 2 messages back ;)
 If we could design it again, probably you should have safe and system be what
they are today, trusted would be safe, except where you put in unsafe blocks.
This allows the code to pick which parts should be able to call system
functions.
-Steve
Jan 09 2020
prev sibling parent reply ag0aep6g <anonymous example.com> writes:
On Thursday, 9 January 2020 at 19:35:36 UTC, Steven Schveighoffer 
wrote:
 If I could mark the whole thing trusted, and turn on the 
 mechanical checking for everything except line X, then I'd do 
 that instead.
Well, you can do that: void foo() trusted { () safe { /* ... stuff ... */ } (); bar(1, 2, 3); /* line X */ () safe { /* ... stuff ... */ } (); } The problem is, of course, that you can't have `foo`'s safety inferred based on "stuff". Which is what we usually want. I have actually used that pattern once in Phobos: https://github.com/dlang/phobos/blob/master/std/range/package.d#L1550-L1581 I had to duplicate the code and use `__traits(compiles, ...)` to get inference. So the result isn't exactly pretty. But the use of trusted is watertight, as far as I can tell.
Jan 09 2020
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/9/20 3:08 PM, ag0aep6g wrote:
 On Thursday, 9 January 2020 at 19:35:36 UTC, Steven Schveighoffer wrote:
 If I could mark the whole thing trusted, and turn on the mechanical 
 checking for everything except line X, then I'd do that instead.
Well, you can do that:     void foo() trusted     {         () safe { /* ... stuff ... */ } ();         bar(1, 2, 3); /* line X */         () safe { /* ... stuff ... */ } ();     } The problem is, of course, that you can't have `foo`'s safety inferred based on "stuff". Which is what we usually want.
This turns on its head the lines you have to pay most attention to though :) Basically, your job of manually checking such a function is to 1. establish which parts are not mechanically checked, and 2. verify they are ALWAYS correct (unlikely) or that they are correct based on the mechanically checked parts of the function. In order to do that efficiently, I want to tag where the trouble spots may be. And these are likely to be MUCH fewer than the checked ones. Put it another way, a safe function with no trusted escapes needs no checking. A safe function with one trusted escape needs each safe line checked in reference to the trusted escape. With 2 escapes, you need to check each line against 2 blocks, etc. e.g. (to build on the previous example): safe void someFunction() { int[4] data; foo("argument"); bar(); trusted { data.ptr[3] = 42; } } Looking at line 2 and 3, I can verify that no parts touch anything that might be affected by the trusted block. I don't need to check foo to see if it's safe when called with "argument", nor do I need to investigate bar(), I just need to know, it doesn't use anything that is currently affected by the trusted block. It makes my job easier as a manual checker. I only need to investigate the declaration of `data`, and the trusted block.
 
 I have actually used that pattern once in Phobos:
 
 https://github.com/dlang/phobos/blob/master/std/range/package.d#L1550-L1581
 
 I had to duplicate the code and use `__traits(compiles, ...)` to get 
 inference. So the result isn't exactly pretty. But the use of  trusted 
 is watertight, as far as I can tell.
Hm... this is an odd thing for sure. I probably would have done it this way though: ref getR1() trusted { return r1; } ref getR2() trusted { return r2; } return r1Chosen ? ChooseResult(r1Chosen, getR1().save, getR2()) : ChooseResult(r1Chosen, getR1(), getR2().save); But actually, is that right? Even if it's safe, it's a bad idea to copy the non-tagged item, as its contents are the contents for the other item. Shouldn't it be: return r1Chosen ? ChooseResult(r1Chosen, getR1().save, R2.init) : ChooseResult(r1Chosen, R1.init, getR2().save); -Steve
Jan 09 2020
parent reply ag0aep6g <anonymous example.com> writes:
On Thursday, 9 January 2020 at 20:33:00 UTC, Steven Schveighoffer 
wrote:
  safe void someFunction()
 {
     int[4] data;
     foo("argument");
     bar();
      trusted
     {
         data.ptr[3] = 42;
     }
 }

 Looking at line 2 and 3, I can verify that no parts touch 
 anything that might be affected by the trusted block. I don't 
 need to check foo to see if it's safe when called with 
 "argument", nor do I need to investigate bar(), I just need to 
 know, it doesn't use anything that is currently affected by the 
 trusted block. It makes my job easier as a manual checker. I 
 only need to investigate the declaration of `data`, and the 
 trusted block.
Effectively, the trusted block taints the surrounding function without disabling the mechanical checks on most lines. For trusted blocks, I could get on board with that, as long as we limit the scope of the taint to the function. Then it's still fairly obvious what code needs special expertise. I.e., the rule for junior programmers changes from "you may only touch safe functions" to "you may only touch safe functions that don't contain trusted blocks". That's still reasonable. I don't think tainting should be allowed beyond function scope (e.g., tainting a whole module by accessing one of its globals), because then it becomes hard to identify the safety-critical parts. I also don't think we should use that pattern with the trusted function attribute we have at the moment. You're necessarily crossing the function border with that. So it's less clear what level of tainting is acceptable, and it would be harder to formalize. And we'd need to formalize this. Using trusted in a way that is clearly against the spec is just asking for trouble. For the given `someFunction`, making `data` an " system variable" [1] would also be a solution. Then you wouldn't even have to look at lines 2 and 3. I'd be in favor of pursuing that approach first. I can imagine that system variables would often make tainting functions unnecessary.
 I have actually used that pattern once in Phobos:
 
 https://github.com/dlang/phobos/blob/master/std/range/package.d#L1550-L1581
 
 I had to duplicate the code and use `__traits(compiles, ...)` 
 to get inference. So the result isn't exactly pretty. But the 
 use of  trusted is watertight, as far as I can tell.
Hm... this is an odd thing for sure. I probably would have done it this way though: ref getR1() trusted { return r1; } ref getR2() trusted { return r2; } return r1Chosen ? ChooseResult(r1Chosen, getR1().save, getR2()) : ChooseResult(r1Chosen, getR1(), getR2().save);
It's done that way in other parts of the code [2]. The problem is that `getR1` and `getR2` are not safe. So they're invalid if we take the spec seriously. Looking at my own code again, I'm not so sure anymore if it's really "watertight". What is stopping the hypothetical junior programmer from editing my safe helper functions to leak a reference to the union? It's safe code, so they're allowed to edit it. But it's safe code inside trusted code. Does that mean it's off limits again? Now my head's starting to spin.
 But actually, is that right? Even if it's safe, it's a bad idea 
 to copy the non-tagged item, as its contents are the contents 
 for the other item. Shouldn't it be:

 return r1Chosen ? ChooseResult(r1Chosen, getR1().save, R2.init) 
 : ChooseResult(r1Chosen, R1.init, getR2().save);
You're not wrong. It's not even safe. If the non-chosen range contains pointers, they're going to be garbage. If it has a copy constructor, those garbage pointers might be dereferenced. [1] https://github.com/dlang/DIPs/pull/179 [2] https://github.com/dlang/phobos/blob/f66da1f8c962fbb7ed440caad53d3a978c72ff88/std/range/package.d#L1468-L1481
Jan 09 2020
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/9/20 6:26 PM, ag0aep6g wrote:
 It's done that way in other parts of the code [2]. The problem is that 
 `getR1` and `getR2` are not safe. So they're invalid if we take the spec 
 seriously.
I'm not sure what you mean by this. They are not safe, nor are they intended to be, they are trusted escapes. But they only live inside the function that uses them, and only called when they are safe. Your reference is even better, the function is only defined within the context where it is valid. In any case, I'll look at making a PR in a bit. No need to keep discussing in this thread. -Steve
Jan 09 2020
prev sibling next sibling parent reply Arine <arine123445128843 gmail.com> writes:
On Thursday, 9 January 2020 at 18:47:23 UTC, Johannes Pfau wrote:
 Now someone changes data to int[2]:

  safe void someFunction()
 {
     int[2] data;
     // Lot's of code
      trusted
     {
         data.ptr[3] = 42;
     }
 }

 So by modifying  safe code only, you introduced a memory safety 
 issue. The interface of a  trusted function however is more 
 strictly defined:

  trusted function set(ref int[4] data)
 {
     data.ptr[3] = 42;
 }
That's a pretty contrived example. safe void someFunction() { int[2] data; // Lot's of code unsafe { static assert( data.length > 3 ); data.ptr[3] = 42; } } There you get the same safety and you don't have to create a separate function that passes in a ref to a int array of a static size, that'll probably literally never be used anywhere else. If it's a dynamic array, then they are both equally unsafe and it's up to you to ensure it is safe. If you have that unsafe block in the function, it's going to be a lot easier to see where that potential problem is. Otherwise it'll look like any other safe function.
Jan 09 2020
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 09.01.20 20:09, Arine wrote:
 
  safe void someFunction()
 {
      int[2] data;
      // Lot's of code
       unsafe
      {
          static assert( data.length > 3 );
          data.ptr[3] = 42;
      }
 }
safe void someFunction(){ static struct Nope{ int[2] payload; alias payload this; enum length=1337; } Nope data; // ... unsafe{ static assert(data.length>3); data.ptr[3] = 42; } }
Jan 09 2020
prev sibling next sibling parent ag0aep6g <anonymous example.com> writes:
On Thursday, 9 January 2020 at 18:47:23 UTC, Johannes Pfau wrote:
  safe void someFunction()
 {
     int[4] data;
     // Lot's of code
      trusted
     {
         data.ptr[3] = 42;
     }
 }

 Now someone changes data to int[2]:

  safe void someFunction()
 {
     int[2] data;
     // Lot's of code
      trusted
     {
         data.ptr[3] = 42;
     }
 }

 So by modifying  safe code only, you introduced a memory safety 
 issue. The interface of a  trusted function however is more 
 strictly defined:

  trusted function set(ref int[4] data)
 {
     data.ptr[3] = 42;
 }
Unfortunately, that kind of trusted misuse is pretty common. system variables is a feature that can help in such cases. There's a DIP in the making: https://github.com/dlang/DIPs/pull/179 You could then write someFunction as: safe void someFunction() { system int[4] data; // Lot's of code trusted { data.ptr[3] = 42; } } Now you're guaranteed that "lot's of code" can't touch `data`, and you can rely on that in the trusted section.
Jan 09 2020
prev sibling next sibling parent Paolo Invernizzi <paolo.invernizzi gmail.com> writes:
On Thursday, 9 January 2020 at 18:47:23 UTC, Johannes Pfau wrote:
 Am Thu, 09 Jan 2020 10:12:23 +1000 schrieb Manu:

 
 unsafe blocks is distinctly preferable to me. Functions are 
 usually >1 line, and I hate that we can only mark this at the 
 function level. Unsafely statements are never at the function 
 level, it's usually just one line among a larger function. An 
 unsafe scope would be immensely preferable to me, because I 
 can make it as narrow as the code i'm suspicious of, and the 
 surrounding code doesn't lose its safe checking just by being 
 a bystander.
I agree that the lambda thing is an ugly hack and proper trusted blocks would be better. However, I wonder how languages with such blocks deal with problems such as these: safe void someFunction() { int[4] data; // Lot's of code trusted { data.ptr[3] = 42; } } Now someone changes data to int[2]: safe void someFunction() { int[2] data; // Lot's of code trusted { data.ptr[3] = 42; } } So by modifying safe code only, you introduced a memory safety issue. The interface of a trusted function however is more strictly defined: trusted function set(ref int[4] data) { data.ptr[3] = 42; } It's not possible to break the set function in safe code. You could probably argue that the trusted block in someFunction should have covered the int[2] data definition and that you can also write trusted functions which do not properly check / enforce their parameters and can be broken from safe code. But still, it seems like applying trusted/safe at function level provides stronger guarantees. I wonder how other languages deal with that? Not at all and just be extra careful when writing trusted blocks?
Exactly! Function level seems to be the proper place to granularly expose assumptions and promises in a clean way: put on the stage contracts, documentation and the possibility to easily unittest it ... I'm -1 on trusted blocks
Jan 09 2020
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/9/2020 10:47 AM, Johannes Pfau wrote:
 I agree that the lambda thing is an ugly hack and proper trusted blocks
 would be better.
It's intended to be that way. Bad language design is where the simple, straightforward code is considered bad form, for example, in C++: void foo(int array[]) // bad, boo hiss #include <vector> void foo(std::vector<int> array); // good, you get a gold star Besides, most of the ugliness I've seen comes from excessively trying to reduce the number of characters. Making it a regular nested function with a name makes it nice.
 However, I wonder how languages with such blocks deal
 with problems such as these:
 
  safe void someFunction()
 {
      int[4] data;
      // Lot's of code
       trusted
      {
          data.ptr[3] = 42;
      }
 }
 
 Now someone changes data to int[2]:
 
  safe void someFunction()
 {
      int[2] data;
      // Lot's of code
       trusted
      {
          data.ptr[3] = 42;
      }
 }
 
 So by modifying  safe code only, you introduced a memory safety issue.
 The interface of a  trusted function however is more strictly defined:
 
  trusted function set(ref int[4] data)
 {
      data.ptr[3] = 42;
 }
 
 It's not possible to break the set function in  safe code. You could
 probably argue that the trusted block in someFunction should have covered
 the int[2] data definition and that you can also write  trusted functions
 which do not properly check / enforce their parameters and can be broken
 from  safe code.
Exactly right. Let's make it look nicer: safe void someFunction() { int[4] data; // Lot's of code trusted void set() { data.ptr[3] = 42; } set(); }
 But still, it seems like applying trusted/safe at function level provides
 stronger guarantees.
It also makes it easier for both the compiler and user to reason about. The user doesn't need to bother wondering/worrying if the compiler will detect breaking the trusted code by changing the safe code.
Jan 15 2020
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 15.01.20 19:08, Walter Bright wrote:
 On 1/9/2020 10:47 AM, Johannes Pfau wrote:
 I agree that the lambda thing is an ugly hack and proper trusted blocks
 would be better.
It's intended to be that way. Bad language design is where the simple, straightforward code is considered bad form, for example, in C++:     void foo(int array[])  // bad, boo hiss     #include <vector>     void foo(std::vector<int> array);  // good, you get a gold star ...
Or perhaps #include <vector> void foo(std::vector<int> const &array);
 Besides, most of the ugliness I've seen comes from excessively trying to 
 reduce the number of characters. Making it a regular nested function 
 with a name makes it nice.
 ...
Maybe it looks nice. A trusted nested function that depends on enclosing safe code to ensure memory safety is however still not valid.
 ...
 
 Let's make it look nicer:
 
     safe void someFunction()
    {
       int[4] data;
       // Lot's of code
 
        trusted void set() { data.ptr[3] = 42; }
 
       set();
    }
 
 
 But still, it seems like applying trusted/safe at function level provides
 stronger guarantees.
It also makes it easier for both the compiler and user to reason about. The user doesn't need to bother wondering/worrying if the compiler will detect breaking the trusted code by changing the safe code.
It will not. The "nice" version is bad.
Jan 15 2020
parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/15/2020 10:46 AM, Timon Gehr wrote:
 It will not. The "nice" version is bad.
Yeah, I realized after I posted it that it should be `static` and pass `data` by ref.
Jan 15 2020
prev sibling next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Jan 09, 2020 at 10:12:23AM +1000, Manu via Digitalmars-d wrote:
[...]
 unsafe blocks is distinctly preferable to me. Functions are usually >1
 line, and I hate that we can only mark this at the function level.
 Unsafely statements are never at the function level, it's usually just
 one line among a larger function. An unsafe scope would be immensely
 preferable to me, because I can make it as narrow as the code i'm
 suspicious of, and the surrounding code doesn't lose its safe checking
 just by being a bystander.
There is this current idiom that essentially serves as a trusted block: auto myFunc() safe { ... // mundane stuff () trusted { // dangerous stuff goes here }(); ... // more mundane stuff } But it's quite the eyesore, I'll admit. OTOH, that may be its redeeming quality: it looks so ugly, and is so icky to write, that it discourages people from overusing it. You're inclined to do it only when you absolutely have to. T -- There's light at the end of the tunnel. It's the oncoming train.
Jan 08 2020
next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/8/2020 4:49 PM, H. S. Teoh wrote:
 OTOH, that may be its redeeming quality: it looks so ugly, and is so
 icky to write, that it discourages people from overusing it. You're
 inclined to do it only when you absolutely have to.
Bingo!
Jan 08 2020
prev sibling parent Arine <arine123445128843 gmail.com> writes:
On Thursday, 9 January 2020 at 00:49:29 UTC, H. S. Teoh wrote:
 On Thu, Jan 09, 2020 at 10:12:23AM +1000, Manu via 
 Digitalmars-d wrote: [...]
 unsafe blocks is distinctly preferable to me. Functions are 
 usually >1 line, and I hate that we can only mark this at the 
 function level. Unsafely statements are never at the function 
 level, it's usually just one line among a larger function. An 
 unsafe scope would be immensely preferable to me, because I 
 can make it as narrow as the code i'm suspicious of, and the 
 surrounding code doesn't lose its safe checking just by being 
 a bystander.
There is this current idiom that essentially serves as a trusted block: auto myFunc() safe { ... // mundane stuff () trusted { // dangerous stuff goes here }(); ... // more mundane stuff } But it's quite the eyesore, I'll admit. OTOH, that may be its redeeming quality: it looks so ugly, and is so icky to write, that it discourages people from overusing it. You're inclined to do it only when you absolutely have to.
This isn't something you'd want people to not write. It's how you obviously). It makes it easier to read because you see in the safe function what is unsafe. Creating a separate function that you probably don't need, and labeling it as trusted just makes the code harder to read and understand what might be unsafe. You have to go through the entire function, call by call and determine which functions are unsafe.
Jan 08 2020
prev sibling next sibling parent Manu <turkeyman gmail.com> writes:
On Thu, Jan 9, 2020 at 10:49 AM H. S. Teoh via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On Thu, Jan 09, 2020 at 10:12:23AM +1000, Manu via Digitalmars-d wrote:
 [...]
 unsafe blocks is distinctly preferable to me. Functions are usually >1
 line, and I hate that we can only mark this at the function level.
 Unsafely statements are never at the function level, it's usually just
 one line among a larger function. An unsafe scope would be immensely
 preferable to me, because I can make it as narrow as the code i'm
 suspicious of, and the surrounding code doesn't lose its safe checking
 just by being a bystander.
There is this current idiom that essentially serves as a trusted block: auto myFunc() safe { ... // mundane stuff () trusted { // dangerous stuff goes here }(); ... // more mundane stuff } But it's quite the eyesore, I'll admit. OTOH, that may be its redeeming quality: it looks so ugly, and is so icky to write, that it discourages people from overusing it. You're inclined to do it only when you absolutely have to.
Lambdas are usually suggested, but it's a completely unacceptable hack. * additional function call overhead * influences the inliner heuristics unfavourably * may allocate a closure if you're not careful * additional callstack pollutes stack trace with redundant frames with stupid names, which is particularly annoying while debugging! This is a tired and unacceptable suggestion.
Jan 08 2020
prev sibling next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Jan 09, 2020 at 12:01:39PM +1000, Manu via Digitalmars-d wrote:
 On Thu, Jan 9, 2020 at 10:49 AM H. S. Teoh via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
[...]
         auto myFunc()  safe {
                 ... // mundane stuff
                 ()  trusted {
                         // dangerous stuff goes here
                 }();
                 ... // more mundane stuff
         }

 But it's quite the eyesore, I'll admit.
[...]
 Lambdas are usually suggested, but it's a completely unacceptable hack.
  * additional function call overhead
  * influences the inliner heuristics unfavourably
  * may allocate a closure if you're not careful
[...] Oh? Didn't somebody post a PR to inline these lambdas when they appear in such contexts? Was that never merged, or is it only active with -inline? Did you check the output asm to see what it actually does? T -- The irony is that Bill Gates claims to be making a stable operating system and Linus Torvalds claims to be trying to take over the world. -- Anonymous
Jan 08 2020
parent Basile B. <b2.temp gmx.com> writes:
On Thursday, 9 January 2020 at 02:34:37 UTC, H. S. Teoh wrote:
 On Thu, Jan 09, 2020 at 12:01:39PM +1000, Manu via 
 Digitalmars-d wrote:
 On Thu, Jan 9, 2020 at 10:49 AM H. S. Teoh via Digitalmars-d 
 <digitalmars-d puremagic.com> wrote:
[...]
         auto myFunc()  safe {
                 ... // mundane stuff
                 ()  trusted {
                         // dangerous stuff goes here
                 }();
                 ... // more mundane stuff
         }

 But it's quite the eyesore, I'll admit.
[...]
 Lambdas are usually suggested, but it's a completely 
 unacceptable hack.
  * additional function call overhead
  * influences the inliner heuristics unfavourably
  * may allocate a closure if you're not careful
[...] Oh? Didn't somebody post a PR to inline these lambdas when they appear in such contexts? Was that never merged, or is it only active with -inline? Did you check the output asm to see what it actually does? T
I have a feature branch with a POC [1] of trusted block statements. I remember that while it worked this was not so nicely done because safety is something that works at the function level so the semantic part consists of a cheat. [1]: https://c.gmx.com/ 558129942915716568/BZ_xc2wjRgWzo3XVZXjVVg
Jan 08 2020
prev sibling next sibling parent Manu <turkeyman gmail.com> writes:
On Thu, Jan 9, 2020 at 12:34 PM H. S. Teoh via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On Thu, Jan 09, 2020 at 12:01:39PM +1000, Manu via Digitalmars-d wrote:
 On Thu, Jan 9, 2020 at 10:49 AM H. S. Teoh via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
[...]
         auto myFunc()  safe {
                 ... // mundane stuff
                 ()  trusted {
                         // dangerous stuff goes here
                 }();
                 ... // more mundane stuff
         }

 But it's quite the eyesore, I'll admit.
[...]
 Lambdas are usually suggested, but it's a completely unacceptable hack.
  * additional function call overhead
  * influences the inliner heuristics unfavourably
  * may allocate a closure if you're not careful
[...] Oh? Didn't somebody post a PR to inline these lambdas when they appear in such contexts? Was that never merged, or is it only active with -inline? Did you check the output asm to see what it actually does?
That has never been behaviour I've observed. And GDC/LDC don't have `-inline`; they defer to their own optimiser. LDC with -O2 doesn't inline this. I'm sure you can tickle the things and make this inline, but this will still affect the compilers heuristics unfavourably leading to poor optimisation choices regardless. https://godbolt.org/z/oVdRP9 Abusing a lambda is not a 'feature', it's a terrible hack that materially changes functionality and has never been a valid suggestion. I've argued this so many times before. We should have attributed scopes in the language, this has been a feature request forever.
Jan 08 2020
prev sibling parent reply Arine <arine123445128843 gmail.com> writes:
On Wednesday, 8 January 2020 at 18:59:38 UTC, Timon Gehr wrote:
 On 08.01.20 08:10, Arine wrote:
 
  trusted doesn't really make sense. It is pretty much  system 
 that  safe can call. It's actually kind of bad as how easily 
 it can be misused.  trusted: comes to mind. You can have 
  trusted destructors. So when you are reading  safe code you 
 can't easily tell where potentially  unsafe code is located. 
 As the  trusted is applied to the function, not at the call 

 ...
This line of reasoning makes no sense. trusted void foo(T...)(T args){ ... } is like safe void foo(T...)(T args){ unsafe{ ... } } It's the same thing. The point is that the interface of foo is assumed to safe by all callers even though the implementation might not be.
That'd be a code smell. If you have to put the entire body of a function in unsafe, that function should just be defined as unsafe. You've just given the perfect illustration of why trusted is terrible.
 If we are going to make  safe the default we don't really need 
  safe keyword, or  system or  trusted. It's make sense to get 
 rid of all 3 of them and just add  unsafe. If you are going to 
 do it, might as well do it right the first time.
I don't care all that much either way, but let's not pretend that what you propose is different to what we have in any important way other than how convenient certain things are to express. Adding trusted statement blocks and deprecating ` trusted:` annotations would have essentially the same effect.
Did you miss the example?
Jan 08 2020
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 09.01.20 07:19, Arine wrote:
 On Wednesday, 8 January 2020 at 18:59:38 UTC, Timon Gehr wrote:
 On 08.01.20 08:10, Arine wrote:
  trusted doesn't really make sense. It is pretty much  system that 
  safe can call. It's actually kind of bad as how easily it can be 
 misused.  trusted: comes to mind. You can have  trusted destructors. 
 So when you are reading  safe code you can't easily tell where 
 potentially  unsafe code is located. As the  trusted is applied to 

 ...
This line of reasoning makes no sense. trusted void foo(T...)(T args){ ... } is like safe void foo(T...)(T args){ unsafe{ ... } } It's the same thing. The point is that the interface of foo is assumed to safe by all callers even though the implementation might not be.
That'd be a code smell. If you have to put the entire body of a function in unsafe, that function should just be defined as unsafe.
Nonsense. If a function provides a safe interface, safe code should be able to call it freely. Forcing client code to unnecessarily sprinkle unsafe blocks everywhere is a bad idea.
 You've just given the perfect illustration of why  trusted is terrible.
 ...
Not really, but it appears you might not properly understand either safe/ trusted/ system or safe/ unsafe or modular software verification. The main drawback of unsafe is that its meaning on blocks is dual to its meaning on functions. Unsafe blocks are like trusted (trust me, what's in this block is fine) and unsafe functions are like system (be careful, the compiler will not check all preconditions required to call this function safely). The only benefit of safe/ unsafe is that you need fewer keywords. It's actually more confusing.
 If we are going to make  safe the default we don't really need  safe 
 keyword, or  system or  trusted. It's make sense to get rid of all 3 
 of them and just add  unsafe. If you are going to do it, might as 
 well do it right the first time.
I don't care all that much either way, but let's not pretend that what you propose is different to what we have in any important way other than how convenient certain things are to express. Adding trusted statement blocks and deprecating ` trusted:` annotations would have essentially the same effect.
Did you miss the example?
Of course not. Your example is either terrible or covered by trusted statement blocks. Not sure which.
Jan 09 2020
prev sibling next sibling parent Dominikus Dittes Scherkl <dominikus scherkl.de> writes:
On Wednesday, 8 January 2020 at 02:48:19 UTC, Walter Bright wrote:
 Also, a safe/unsafe dichotomy can make sense. But a 
 safe/trusted/unsafe makes less sense, like a 3 state boolean.
Which it defacto is. we should get rid of trusted (at function level) and replace it by trusted expressions. But whether the remaining system is kept or renamed to unsafe really doesn't matter, I think.
Jan 08 2020
prev sibling parent reply Manu <turkeyman gmail.com> writes:
On Wed, Jan 8, 2020 at 12:50 PM Walter Bright via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On 1/6/2020 3:59 PM, Manu wrote:
 Well all feedback I've received is that it fails at the rule of least
 surprise. Definitely not intuitive what it means.
I'm frankly surprised at this. Yours is literally the first complaint about using `system` in 10 years that has come to my ears.
It's the kind of thing that people wouldn't bother complaining about, because it has no material affect on their ability to get their job done, it's just weird. I mean, I've thought this the whole time, and I've never said it here. The only reason that I feel it was worth raising the topic, is because this is the one single moment that it would be possible to make this change... so it seems worth the thought.
 Also, a safe/unsafe dichotomy can make sense. But a safe/trusted/unsafe makes
 less sense, like a 3 state boolean.
I don't think it makes any less sense. It seems reasonable that safe code can't call unsafe code, unless we `trust` it.
 I think it may be possible to see and consider the situation
 differently when looking from a safe-by-default perspective; today
 where 'system' is default, you wouldn't want to advertise the language
 as "unsafe by default"... but if safe is default, than 'unsafe' feels
 a lot more reasonable for the exceptions. I reckon the change in
 default may change your judgement that you describe above.
`static` in C makes no particular sense, but people are so used to it that they imagine it makes perfect sense :-)
We're not asking people to get on board with nonsense decisions that C made 50 years ago, we're asking new users to feel that D is natural and desirable. My experience is this (with no exceptions): there is a finite number of 'weird shit' experiences that a new user can digest before they stop and lose interest, and there are lots of ways we burn through that budget. At some point, we blow the threshold and they go away. Every single person I've introduced to D has followed this pattern, sadly. Every... single... one. This is indeed a very minor one, but these sorts of weird perceptions still consume some of that balance. In this case, I see no reason for anything other than a completely intuitive and expected language, and they would be comfortable, accept that D makes perfect sense on this matter, and the budget remains for other more important stuff which certainly exists.
 Nobody expects to be able to implement a storage allocator in code that is
 provably correct. Nobody expects the implementation of atomic shared operations
 to to be provably. People have historically called such underpinnings "system"
 code (long before there was a notion of "unsafe"), where the dirty but
necessary
 work happens. Steamships had white-glove service to the passengers, and the
 greasy dirty work went on in the "system" under the decks to support it all.

 Whether "system" is intuitive or not is how you frame it. It's a perfect
 moniker. It is not "unsafe", it just means the compiler cannot prove it safe.
Whatever you reckon. I was just offering that there's an opportunity here.
Jan 08 2020
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/8/2020 3:42 AM, Manu wrote:
 Whatever you reckon. I was just offering that there's an opportunity here.
I understand. But too much of this shuffling names around is just bouncing the bricks and wasting everyone's time changing their code, correcting their books, redoing websites, updating tutorials, etc., and just makes us look like dithering fools. We've had many of these in the past. The only one that really paid off was renaming `invariant` to `immutable`, but we did that one very early before people got very far with the former.
Jan 08 2020
parent Arine <arine123445128843 gmail.com> writes:
On Thursday, 9 January 2020 at 05:37:18 UTC, Walter Bright wrote:
 On 1/8/2020 3:42 AM, Manu wrote:
 Whatever you reckon. I was just offering that there's an 
 opportunity here.
I understand. But too much of this shuffling names around is just bouncing the bricks and wasting everyone's time changing their code, correcting their books, redoing websites, updating tutorials, etc., and just makes us look like dithering fools.
Isn't that exactly what's happening right now with changing the default to be safe... ?
Jan 08 2020
prev sibling next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/2/20 4:47 AM, Mike Parker wrote:
 This is the feedback thread for the first round of Community Review for 
 DIP 1028, "Make  safe the Default":
 
 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688
54b/DIPs/DIP1028.md 
 
 
 All review-related feedback on and discussion of the DIP should occur in 
 this thread. The review period will end at 11:59 PM ET on January 16, or 
 when I make a post declaring it complete.
 
 At the end of Round 1, if further review is deemed necessary, the DIP 
 will be scheduled for another round of Community Review. Otherwise, it 
 will be queued for the Final Review and Formal Assessment.
 
 Anyone intending to post feedback in this thread is expected to be 
 familiar with the reviewer guidelines:
 
 https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md
 
 *Please stay on topic!*
 
 Thanks in advance to all who participate.
Some sticky points: 1. Currenty the compiler can "give up" on attribute inference, and therefore leaves functions as system. What happens when safe is the default? I would recommend that they should be inferred safe, but this might be a code-breaking in some cases. 2. I'll echo here what other have said, because it's REALLY important: do NOT recommend slapping trusted on anything. It's a very very bad idea, and destroys the whole concept of safe. Rather, put system on functions that have to be system. -Steve
Jan 03 2020
parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/3/2020 7:23 AM, Steven Schveighoffer wrote:
 Some sticky points:
 
 1. Currenty the compiler can "give up" on attribute inference, and therefore 
 leaves functions as  system. What happens when  safe is the default? I would 
 recommend that they should be inferred  safe, but this might be a
code-breaking 
 in some cases.
They'll be inferred safe.
 2. I'll echo here what other have said, because it's REALLY important: do NOT 
 recommend slapping  trusted on anything. It's a very very bad idea, and
destroys 
 the whole concept of  safe. Rather, put  system on functions that have to be 
  system.
Yeah, that's a good idea.
Jan 03 2020
prev sibling next sibling parent Meta <jared771 gmail.com> writes:
I'm glad we're finally opening this can of worms. IMO, it's worth 
whatever breakage it causes, or to turn that around, no price is 
too high to have  safe be the default. It's also a great PR point 
for D to be memory safe by default.
Jan 03 2020
prev sibling next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/2/20 4:47 AM, Mike Parker wrote:
 This is the feedback thread for the first round of Community Review for 
 DIP 1028, "Make  safe the Default":
 
 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688
54b/DIPs/DIP1028.md 
 
 
 All review-related feedback on and discussion of the DIP should occur in 
 this thread. The review period will end at 11:59 PM ET on January 16, or 
 when I make a post declaring it complete.
 
 At the end of Round 1, if further review is deemed necessary, the DIP 
 will be scheduled for another round of Community Review. Otherwise, it 
 will be queued for the Final Review and Formal Assessment.
 
 Anyone intending to post feedback in this thread is expected to be 
 familiar with the reviewer guidelines:
 
 https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md
 
 *Please stay on topic!*
 
 Thanks in advance to all who participate.
Add to rationale: The vast majority of non-template code written is safe, but not marked as such. This means many projects cannot enable safe because their dependencies were not marked that way. This will correct that for all those dependencies. e.g.: I made most of diet-ng safe so I could enable runtime diet templates (see PR here: https://github.com/rejectedsoftware/diet-ng/pull/70). Many of my changes were to enable safe at runtime (most things were not marked safe because CTFE doesn't require safe, and most of diet is using CTFE). For the safety changes, most of what I did was simply to slap safe: at the top, or inside types which were not templates. The one exception was object.opEquals, which I had to write a trusted wrapper for. But in any case, it's a good rationale. I write non-template code ALL the time that is safe, but don't think to mark it. Same can be said about pure and nothrow. -Steve
Jan 03 2020
next sibling parent reply monkyyy <crazymonkyyy gmail.com> writes:
I strongly oppose such a move.

I am in all likelyhood going to mark every line of code with 
 trusted which is a bold face lie, as I appear to be the tiny 
minority of people who actually likes C and uses pointers as the 
most reliable tool in my tool box.

You will be increasing verbosity, and promoting lying code; 
because this is just how I will behave, because I didn't and will 
not ever be going to looking towards rust as the C replacement. 
Yet C needs to be replaced and there isn't exactly a slew of 
options. So why are you taking pages from rust?

I'm here because you offer compile time abstractions on simple 
structs that are not the modern c++ mess, as modern cpus break 
more and more assumptions C made, those abstracts will be nessery 
with pointer math, casting and other "discouraged" code to get 
the most speed. And people looking for the exact same thing I'm 
looking for with that same style will lie to the compiler in the 
exact same way.

Theres needs a non-verbose, non-lying way to opt-out, and 
probably shouldn't be opt-in in the first place.

I would suggest module scope default behaviors.
Jan 03 2020
next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/3/2020 2:37 PM, monkyyy wrote:
 I strongly oppose such a move.
Just add: system: to the top of your modules and you should be good to go for most cases.
Jan 03 2020
parent reply matheus <matheus gmail.com> writes:
On Saturday, 4 January 2020 at 06:43:16 UTC, Walter Bright wrote:
 On 1/3/2020 2:37 PM, monkyyy wrote:
 I strongly oppose such a move.
Just add: system: to the top of your modules and you should be good to go for most cases.
I see this pattern is this topic: "just add system and everything will be fine". So isn't this will create a trend where when developer is bothered by the compiler then they will just do this and in the end "safety" will never be achieve? Matheus.
Jan 04 2020
parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/4/2020 2:45 AM, matheus wrote:
 So isn't this will create a trend where when developer is bothered by the 
 compiler then they will just do this and in the end "safety" will never be
achieve?
D has lots of ways to avoid compiler checks. It's up to you to use them or not.
Jan 05 2020
prev sibling parent Dominikus Dittes Scherkl <dominikus scherkl.de> writes:
On Friday, 3 January 2020 at 22:37:24 UTC, monkyyy wrote:
 I strongly oppose such a move.

 I am in all likelyhood going to mark every line of code with 
  trusted
What a crappy idea. Why should that be necessary?
 You will be increasing verbosity, and promoting lying code;
No. You just need to add system, and that only if you really did use unsafe features in your code. Which in fact is not that often, even in very low level code.
 Theres needs a non-verbose, non-lying way to opt-out, and 
 probably shouldn't be opt-in in the first place.
There will be a compiler-option to opt out (after the years where there is a compiler-option to opt-in). So no need to get upset (yet). And after those years I'm pretty sure you will have a new view on that - when you're the only one still needing system on more than a hand full of functions
 I would suggest module scope default behaviors.
I personally don't like that, but it is there. I just hope this will vanish over the time as I think it's crappy style.
Jan 04 2020
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/3/2020 10:41 AM, Steven Schveighoffer wrote:
 Add to rationale:
 
 The vast majority of non-template code written is  safe, but not marked as
such. 
 This means many projects cannot enable safe because their dependencies were
not 
 marked that way. This will correct that for all those dependencies.
Sounds good.
 Same can be said about pure and nothrow.
Unfortunately, not much code tends to be pure without expending much effort. Pure would be a poor default. Nothrow is likely to become the default in the future. Please, start a new thread for discussion of that.
Jan 03 2020
prev sibling next sibling parent reply Guillaume Piolat <first.last gmail.com> writes:
On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1028, "Make  safe the Default":

 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688554b/DIPs/DIP1028.md

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

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

 Anyone intending to post feedback in this thread is expected to 
 be familiar with the reviewer guidelines:

 https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md

 *Please stay on topic!*

 Thanks in advance to all who participate.
I'm still against: - it break everything for everyone, so we'll lose working packages on code.dlang.org who happen to have no maintainer but have worked for years - it doesn't seem like Community input is wanted in any way, it's all "there is no choice" - ...but doing it just move the default. It's not an enabler for "safe reference counting" or things like that, since it's just a default. - benefits are overstated since D has always had a lot less memory corruption than C++ (thanks to slices, GC, bounds-checks, and default initialization!). And C++ has less corruption than C thanks to encapsulation. CVE are often due to C which has the maximum number of corruptions. If one's software is an attack vector, then people that care could use the safe subset instead of making the life of every beginner worse.
Jan 03 2020
next sibling parent reply mipri <mipri minimaltype.com> writes:
On Friday, 3 January 2020 at 20:59:45 UTC, Guillaume Piolat wrote:
 I'm still against:
 - it break everything for everyone, so we'll lose working 
 packages on code.dlang.org who happen to have no maintainer but 
 have worked for years
This is technical problem with solutions like this one: https://forum.dlang.org/post/vcubtfjpwzbsleayexwy forum.dlang.org
 - ...but doing it just move the default. It's not an enabler 
 for "safe reference counting" or things like that, since it's 
 just a default.
 - benefits are overstated
Defaults are enormously important though. Putting aside the rate of bugs, when you *do* have one in front of you, defaults matter more than anything else in terms of how readily you can find the problem. When safe is the default, if you have a memory error, you can grep your code base for the nonsafe bits and catalogue them and start there. Another result: people will try something, get an error, and then ask: "should I mark this trusted so I can do what I wanted, or use a safer construct and not have to do that?" Just the question is helpful, but it's also likely that there will be a greater incidence of people going with the safer construct and then avoiding problems altogether. Another result: instead of the status quo of "mark something safe -> get explosion of errors because so much code is system unnecessarily -> realize what a chore it would be to make trusted interfaces to this code -> remove safe", you're more likely to not have problems at all because the code you call is already safe because that's the default. Another result: just by having the compiler option and a deprecation cycle started, people will start actually reporting problems with safe, like they are in this thread right now, instead of running into those problems and grumbling "eh I guess this is half baked, I'll just not use it".
Jan 03 2020
next sibling parent reply Guillaume Piolat <first.last gmail.com> writes:
On Friday, 3 January 2020 at 21:24:03 UTC, mipri wrote:
 Another result: instead of the status quo of "mark something
  safe -> get explosion of errors because so much code is
  system unnecessarily -> realize what a chore it would be to
 make  trusted interfaces to this code -> remove  safe", you're
 more likely to not have problems at all because the code you
 call is already  safe because that's the default.
Which is another way to say you will loose productivity all the time, before you know if that software has any business being good in the first place. Companies write lots of small tools, many of which can (and should) be pretty crappy! Else it's just bad focus. Like I said on Rust context: if you write a hello world, no one cares who owns the string "hello world".
 Another result: just by having the compiler option and a
 deprecation cycle started, people will start actually reporting
 problems with  safe, like they are in this thread right now,
 instead of running into those problems and grumbling "eh I
 guess this is half baked, I'll just not use it".
A less charitable view on this is that people don't use safe because it brings them too little value. "let's make this attribute mandatory because the opt-in version isn't successful" is not really Community input.
Jan 03 2020
parent mipri <mipri minimaltype.com> writes:
On Friday, 3 January 2020 at 21:53:29 UTC, Guillaume Piolat wrote:
 On Friday, 3 January 2020 at 21:24:03 UTC, mipri wrote:
 Another result: instead of the status quo of "mark something
  safe -> get explosion of errors because so much code is
  system unnecessarily -> realize what a chore it would be to
 make  trusted interfaces to this code -> remove  safe", you're
 more likely to not have problems at all because the code you
 call is already  safe because that's the default.
Which is another way to say you will loose productivity all the time, before you know if that software has any business being good in the first place. Companies write lots of small tools, many of which can (and should) be pretty crappy! Else it's just bad focus.
But isn't this kind of code even more likely than most code to be safe? This isn't nogc. It's just these restrictions: https://dlang.org/spec/function.html#safe-functions The big one is "no calling system functions" and this DIP will do a lot to alleviate the pain of that restriction. The other stuff, you run into when you're trying to be clever or improve code. Swap out the unnecessary copies of this idup by casting stuff to immutable, e.g.
Jan 03 2020
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/3/2020 1:24 PM, mipri wrote:
 [...]
I was going to write a reply, then read yours. Mine would be redundant.
Jan 03 2020
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/3/20 3:59 PM, Guillaume Piolat wrote:
 On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community Review 
 for DIP 1028, "Make  safe the Default":

 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688
54b/DIPs/DIP1028.md 


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

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

 Anyone intending to post feedback in this thread is expected to be 
 familiar with the reviewer guidelines:

 https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md

 *Please stay on topic!*

 Thanks in advance to all who participate.
I'm still against: - it break everything for everyone, so we'll lose working packages on code.dlang.org who happen to have no maintainer but have worked for years
Can we auto-check this? It should be as easy as checking out each package and doing dub build with an altered compiler, along with the current one. If the current compiler builds but the altered one does not, then you have found an issue to be reported/analyzed. Such use cases would be instrumental for finding a reason NOT to do this DIP, or alternatively, show how little breakage would be. I tend to think that the breakages will be both minor and few.
 - it doesn't seem like Community input is wanted in any way, it's all 
 "there is no choice"
There is no choice in that D must support safety. But I'm certain that if there were a very compelling reason not to make it the default, this would not be accepted. This IS the community feedback.
 - ...but doing it just move the default. It's not an enabler for "safe 
 reference counting" or things like that, since it's just a default.
It's very much an enabler because people tend to write safe code all the time without marking it. For example, I'm sure iopipe (with the exception of the calls into c-libraries such as memchr and zlib) can be marked safe. But I didn't, because I haven't bothered to worry about it. But absolutely it should be safe. I'd probably have to adjust a few things, and then it will build. The benefit is huge, because then someone doesn't have to choose between memory safety and iopipe speed. If the compiler complained about this when I was developing it, I'd fix the problems as they happened.
 - benefits are overstated since D has always had a lot less memory 
 corruption than C++ (thanks to slices, GC, bounds-checks, and default 
 initialization!). And C++ has less corruption than C thanks to 
 encapsulation. CVE are often due to C which has the maximum number of 
 corruptions.
The difference will be huge. I don't know if this can be overstated. I'd say 99% of code written is ALREADY safe. But we are missing out on the benefits of that because we don't bother marking (lazy idiots that we are). Then you have an ecosystem that is safe-unfriendly, and it begets more code that is safe unfriendly. Once any dependency didn't pay attention to safe, you have to deal with it with trusted at the higher levels, and it's turtles all the way down. This is very similar to the const problem. Take for example, mysql-native. Nothing in there is really safe friendly, yet. So if I want to use mysql, I have to make MY code safe-unfriendly, or just insert trusted escapes for everything, hoping that mysql-native is really actually safe (it pretty much is). One step further, vibe.d now complains all over the place that your handlers are not safe, especially for REST routes. If I want to use mysql-native and vibe.d, everything either has to be trusted, or I have to use some other library. When the compiler complains about the 1% of your code that isn't mechanically checkable as safe, you will spend the 1% of your time to fix it, and move on. It will just feel like another syntax error "oh yeah, I forgot a semicolon". I don't complain about semicolon requirements, I just fix them and move on.
 If one's software is an attack vector, then people that care could use 
 the  safe subset instead of making the life of every beginner worse.
How does this make beginner life worse? Does the beginner start off doing pointer math, or using void *? The advantage here is that D eschews such things for more safe features, so D code is usually safe anyway! void main() { import std.stdio; writeln("Hello, world!"); } will still work. -Steve
Jan 03 2020
next sibling parent reply Guillaume Piolat <first.last gmail.com> writes:
On Friday, 3 January 2020 at 22:13:28 UTC, Steven Schveighoffer 
wrote:
 I'd probably have to adjust a few things, and then it will 
 build. The benefit is huge, because then someone doesn't have 
 to choose between memory safety and iopipe speed. If the 
 compiler complained about this when I was developing it, I'd 
 fix the problems as they happened.
Can anyone produce ONE example of a memory corruption code they write that was found with use of marking something safe?
Jan 03 2020
next sibling parent reply Alex <sascha.orlov gmail.com> writes:
On Friday, 3 January 2020 at 22:23:41 UTC, Guillaume Piolat wrote:
 On Friday, 3 January 2020 at 22:13:28 UTC, Steven Schveighoffer 
 wrote:
 I'd probably have to adjust a few things, and then it will 
 build. The benefit is huge, because then someone doesn't have 
 to choose between memory safety and iopipe speed. If the 
 compiler complained about this when I was developing it, I'd 
 fix the problems as they happened.
Can anyone produce ONE example of a memory corruption code they write that was found with use of marking something safe?
Not sure, if this fits here. But if I add ´´´ safe:´´´ at the beginning of the module, the library https://code.dlang.org/packages/vebtree does not compile any more.
Jan 03 2020
parent reply WebFreak001 <d.forum webfreak.org> writes:
On Friday, 3 January 2020 at 22:36:17 UTC, Alex wrote:
 [...]
 Not sure, if this fits here. But if I add ´´´ safe:´´´ at the 
 beginning of the module, the library 
 https://code.dlang.org/packages/vebtree does not compile any 
 more.
you can't just slap ` safe:` on because all the libraries and stuff you depend on which wasn't marked safe is still gonna stay system and thus disallow your calls. Instead you need to use the compiler with the safe by default PR. I have done this for all dub packages now so everyone can review what this change actually does to their packages: https://i.webfreak.org/safe-test/index.html It seems that your vebtree package compiles fine, however that is not to say for the rest of dub. Currently a lot of issues are caused by phobos' std.bitmanip.bitfields. So a lot of these errors are certainly fixable, but currently it doesn't look good in terms of support. (Tested using phobos v2.089.1-198-gbb8ba28bf)
Jan 04 2020
next sibling parent Atila Neves <atila.neves gmail.com> writes:
On Saturday, 4 January 2020 at 10:22:34 UTC, WebFreak001 wrote:
 On Friday, 3 January 2020 at 22:36:17 UTC, Alex wrote:
 I have done this for all dub packages now so everyone can 
 review what this change actually does to their packages:

 https://i.webfreak.org/safe-test/index.html
Thank you!
Jan 04 2020
prev sibling next sibling parent Alex <sascha.orlov gmail.com> writes:
On Saturday, 4 January 2020 at 10:22:34 UTC, WebFreak001 wrote:
 On Friday, 3 January 2020 at 22:36:17 UTC, Alex wrote:
 [...]
 Not sure, if this fits here. But if I add ´´´ safe:´´´ at the 
 beginning of the module, the library 
 https://code.dlang.org/packages/vebtree does not compile any 
 more.
you can't just slap ` safe:` on because all the libraries and stuff you depend on which wasn't marked safe is still gonna stay system and thus disallow your calls. Instead you need to use the compiler with the safe by default PR. I have done this for all dub packages now so everyone can review what this change actually does to their packages: https://i.webfreak.org/safe-test/index.html It seems that your vebtree package compiles fine, however that is not to say for the rest of dub. Currently a lot of issues are caused by phobos' std.bitmanip.bitfields. So a lot of these errors are certainly fixable, but currently it doesn't look good in terms of support. (Tested using phobos v2.089.1-198-gbb8ba28bf)
Thank you very much!
Jan 04 2020
prev sibling next sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/4/20 5:22 AM, WebFreak001 wrote:
 On Friday, 3 January 2020 at 22:36:17 UTC, Alex wrote:
 [...]
 Not sure, if this fits here. But if I add ´´´ safe:´´´ at the 
 beginning of the module, the library 
 https://code.dlang.org/packages/vebtree does not compile any more.
you can't just slap ` safe:` on because all the libraries and stuff you depend on which wasn't marked safe is still gonna stay system and thus disallow your calls. Instead you need to use the compiler with the safe by default PR. I have done this for all dub packages now so everyone can review what this change actually does to their packages: https://i.webfreak.org/safe-test/index.html It seems that your vebtree package compiles fine, however that is not to say for the rest of dub. Currently a lot of issues are caused by phobos' std.bitmanip.bitfields. So a lot of these errors are certainly fixable, but currently it doesn't look good in terms of support. (Tested using phobos v2.089.1-198-gbb8ba28bf)
Awesome! I'll look into the bitmanip problems. Can you do us a favor and sort by package name? -Steve
Jan 04 2020
prev sibling next sibling parent reply Gregor =?UTF-8?B?TcO8Y2ts?= <gregormueckl gmx.de> writes:
On Saturday, 4 January 2020 at 10:22:34 UTC, WebFreak001 wrote:
 I have done this for all dub packages now so everyone can 
 review what this change actually does to their packages:

 https://i.webfreak.org/safe-test/index.html
I unfortunately have to question some of the results in that list. I have a single, simple package called "sml" in dub and it actually compiles (without safe by default). This contradicts what your list is stating.
Jan 04 2020
parent Mike Parker <aldacron gmail.com> writes:
On Saturday, 4 January 2020 at 14:46:40 UTC, Gregor Mückl wrote:
 On Saturday, 4 January 2020 at 10:22:34 UTC, WebFreak001 wrote:
 I have done this for all dub packages now so everyone can 
 review what this change actually does to their packages:

 https://i.webfreak.org/safe-test/index.html
I unfortunately have to question some of the results in that list. I have a single, simple package called "sml" in dub and it actually compiles (without safe by default). This contradicts what your list is stating.
Please everyone, take this discussion to a new thread and keep this one focused on review of DIP 1028. Thanks!
Jan 04 2020
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/4/2020 2:22 AM, WebFreak001 wrote:
 Currently a lot of issues are caused by phobos' std.bitmanip.bitfields.
Please add all issues to Bugzilla.
Jan 04 2020
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/4/20 4:17 PM, Walter Bright wrote:
 On 1/4/2020 2:22 AM, WebFreak001 wrote:
 Currently a lot of issues are caused by phobos' std.bitmanip.bitfields.
Please add all issues to Bugzilla.
This isn't an issue, because the DIP is not part of the language yet. The problem is that a function used by CTFE in there is not marked, and does an array cast (so safe by default rejects it). I've already submitted a change, and it's already helped with WebFreak's tests: https://github.com/dlang/phobos/pull/7343. Should be merged shortly. -Steve
Jan 04 2020
parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/4/2020 6:44 PM, Steven Schveighoffer wrote:
 The problem is that a function used by CTFE in there is not marked, and does
an 
 array cast (so safe by default rejects it). I've already submitted a change,
and 
 it's already helped with WebFreak's tests: 
 https://github.com/dlang/phobos/pull/7343.
 
 Should be merged shortly.
Good!
Jan 04 2020
prev sibling next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/4/2020 2:22 AM, WebFreak001 wrote:
 I have done this for all dub packages now so everyone can review what this 
 change actually does to their packages:
 
 https://i.webfreak.org/safe-test/index.html
This is good work. Thanks!
Jan 04 2020
prev sibling parent reply Mathias Lang <pro.mathias.lang gmail.com> writes:
On Saturday, 4 January 2020 at 10:22:34 UTC, WebFreak001 wrote:
 On Friday, 3 January 2020 at 22:36:17 UTC, Alex wrote:
 [...]
 Not sure, if this fits here. But if I add ´´´ safe:´´´ at the 
 beginning of the module, the library 
 https://code.dlang.org/packages/vebtree does not compile any 
 more.
you can't just slap ` safe:` on because all the libraries and stuff you depend on which wasn't marked safe is still gonna stay system and thus disallow your calls. Instead you need to use the compiler with the safe by default PR. I have done this for all dub packages now so everyone can review what this change actually does to their packages: https://i.webfreak.org/safe-test/index.html It seems that your vebtree package compiles fine, however that is not to say for the rest of dub. Currently a lot of issues are caused by phobos' std.bitmanip.bitfields. So a lot of these errors are certainly fixable, but currently it doesn't look good in terms of support. (Tested using phobos v2.089.1-198-gbb8ba28bf)
When providing results, it is best to provide your methodology alongside them so people can reproduce. So is there somewhere public I can find your build scripts ? I myself gave a try to the switch, but I didn't expect *anything* to work, as I was sure druntime/Phobos would not compile with '-preview=safedefault', and as I mentioned already, we'll hit linker error if we don't compile them with '-preview=safedefault'. The results I got were as I expected (https://github.com/dlang/dmd/pull/10709#issuecomment-571899986), which seems to be at odds with what you're seeing.
Jan 07 2020
parent WebFreak001 <d.forum webfreak.org> writes:
On Wednesday, 8 January 2020 at 05:47:15 UTC, Mathias Lang wrote:
 On Saturday, 4 January 2020 at 10:22:34 UTC, WebFreak001 wrote:
 [...]
When providing results, it is best to provide your methodology alongside them so people can reproduce. So is there somewhere public I can find your build scripts ? I myself gave a try to the switch, but I didn't expect *anything* to work, as I was sure druntime/Phobos would not compile with '-preview=safedefault', and as I mentioned already, we'll hit linker error if we don't compile them with '-preview=safedefault'. The results I got were as I expected (https://github.com/dlang/dmd/pull/10709#issuecomment-571899986), which seems to be at odds with what you're seeing.
I didn't compile druntime or phobos with the -preview=safedefault flag, only the dub packages. The command for building the dub packages is at the very top. dmd-safe-wrapper is a simple .sh file like this: /opt/dmd-safe/dmd/generated/linux/release/64/dmd -preview=safedefault "$ " see the other thread in general for replies pls
Jan 08 2020
prev sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Jan 03, 2020 at 10:23:41PM +0000, Guillaume Piolat via Digitalmars-d
wrote:
 On Friday, 3 January 2020 at 22:13:28 UTC, Steven Schveighoffer wrote:
 
 I'd probably have to adjust a few things, and then it will build.
 The benefit is huge, because then someone doesn't have to choose
 between memory safety and iopipe speed. If the compiler complained
 about this when I was developing it, I'd fix the problems as they
 happened.
 
Can anyone produce ONE example of a memory corruption code they write that was found with use of marking something safe?
Ran into this a long time ago: struct ResourceA { /* ... */ } struct ResourceB { /* ... */ } // ... ResourceA getResourceA() safe { return ResourceA(); } ResourceB getResourceB() safe { return ResourceB(); } void freeResourceA(ResourceA*) safe { /* ... */ } void freeResourceB(ResourceB*) safe { /* ... */ } struct Container { ResourceA resA; ResourceB resB; // ... void delegate()[] dtors; this(int blah) /* safe*/ { resA = getResourceA(); dtors ~= { freeResourceA(&resA); }; resB = getResourceB(); dtors ~= { freeResourceA(&resA); }; // ... } ~this() { // Cleanup resources foreach (dtor; dtors) dtor(); } } The idea is that each allocated resource must be cleaned up when the container goes out of scope. To prevent cleanup code from going out of sync with allocation code, it's appended to a list of dtors immediately after allocation (sorta like a manual version of scope(exit) that works over an object's lifetime). Exercise for the reader: spot the bug. So, with safe commented out in Container.this() as shown above, this compiles fine with 'dmd -dip1000', even though DIP1000 ostensibly is supposed to prevent precisely this sort of memory corruption. Uncomment the safe, and recompile, the compiler identifies the problem: test.d(17): Error: reference to local this assigned to non-scope this.dtors in safe code test.d(20): Error: reference to local this assigned to non-scope this.dtors in safe code The reason is that DIP1000 only performs these checks in safe code (and for good reasons -- in system code presumably you know what you're doing, and should be able to do apparently unsafe things, the assumption being that you've taken measures to prevent problems that the compiler cannot mechanically verify). T -- What's a "hot crossed bun"? An angry rabbit.
Jan 03 2020
parent Guillaume Piolat <first.last gmail.com> writes:
On Friday, 3 January 2020 at 22:47:05 UTC, H. S. Teoh wrote:
 On Fri, Jan 03, 2020 at 10:23:41PM +0000, Guillaume Piolat via 
 Digitalmars-d wrote:
 On Friday, 3 January 2020 at 22:13:28 UTC, Steven 
 Schveighoffer wrote:
 
 I'd probably have to adjust a few things, and then it will 
 build. The benefit is huge, because then someone doesn't 
 have to choose between memory safety and iopipe speed. If 
 the compiler complained about this when I was developing it, 
 I'd fix the problems as they happened.
 
Can anyone produce ONE example of a memory corruption code they write that was found with use of marking something safe?
Ran into this a long time ago: struct ResourceA { /* ... */ } struct ResourceB { /* ... */ } // ... ResourceA getResourceA() safe { return ResourceA(); } ResourceB getResourceB() safe { return ResourceB(); } void freeResourceA(ResourceA*) safe { /* ... */ } void freeResourceB(ResourceB*) safe { /* ... */ } struct Container { ResourceA resA; ResourceB resB; // ... void delegate()[] dtors; this(int blah) /* safe*/ { resA = getResourceA(); dtors ~= { freeResourceA(&resA); }; resB = getResourceB(); dtors ~= { freeResourceA(&resA); }; // ... } ~this() { // Cleanup resources foreach (dtor; dtors) dtor(); } } The idea is that each allocated resource must be cleaned up when the container goes out of scope. To prevent cleanup code from going out of sync with allocation code, it's appended to a list of dtors immediately after allocation (sorta like a manual version of scope(exit) that works over an object's lifetime).
(I catched your bug while reading (&resA is dupe), but would make similar bugs of course) Just a note that people have sent me 3 such bugs they had and that safe indeed catch (sometimes in association with -dip1000) ------- sample 2 --------- import std.stdio; void main() { int[3] q; oh(cast(int[4]*)(cast(void*)q)); } void oh(int[4]* ar) { writeln(*ar); } ------- sample 3 ---------- import std; struct User { string username; ubyte[] password; } ubyte[20] hashPassword(const(char)[] password) { import std.digest.sha; return sha1Of(password); } User admin; void registerAdmin() { auto hash = hashPassword("hello"); admin.username = "bob"; admin.password = hash; } void printAdmin() { writeln(admin); } void main() { registerAdmin(); printAdmin(); } So we can get an idea of the kind of things it will catch.
Jan 03 2020
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/3/2020 2:13 PM, Steven Schveighoffer wrote:
 - it doesn't seem like Community input is wanted in any way, it's all "there 
 is no choice"
There is no choice in that D must support safety. But I'm certain that if there were a very compelling reason not to make it the default, this would not be accepted. This IS the community feedback.
I've gotten a fair amount of feedback over the years "why isn't safe the default" and having it not be the default implies D isn't serious about memory safety. I'm worn out suggesting that annotating with safe is not a problem. Delaying making safe the default any longer is a serious strategic mistake.
Jan 03 2020
prev sibling next sibling parent Per =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1028, "Make  safe the Default":

 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688554b/DIPs/DIP1028.md
Yes, please! All the way. Thanks, Walter
Jan 04 2020
prev sibling next sibling parent reply Atila Neves <atila.neves gmail.com> writes:
On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:

[snip]

 https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md

 *Please stay on topic!*

 Thanks in advance to all who participate.
I get the impression that most of the negative feedback here falls into the following categories: 1) This will break too much code 2) Crappy code is ok, don't burden users to make their code safe 3) It's too much effort to convert existing code to safe Having basically *only* written safe code for years now (although sometimes misusing trusted), here are my opinions on the categories I came up with: 1) As with every other recent DIP, the change will be gated with `-preview` so initially it will be opt-in. No breakages will happen overnight. Also as with every other recent DIP, after that initial period it will become opt-out with `-revert`. At most, and only sometime in the future, breakages can be easily avoided by adding one flag to the compiler invocation command. I wish it weren't true, but I suspect that this particular revert flag will last for quite a while. 2) and 3) Most D code is safe. Nearly all of it is. Unless you're taking addresses of locals (which can be made safe by using DIP1000 and scope), doing pointer arithmetic, or slicing pointers, nearly all instances of system code left will be casts. I would be very surprised if many changes have to be made, *especially* if the default becomes safe since most of the problems I face are in dependencies. This is why changing the default is important: most code is safe anyway but we're not getting the benefits because it's more effort to annotate than not, so most people don't bother. "But we're already safer than C++" is analogous to "but we already compile faster than C++". They're both low bars to set, and the compiler can never be "too fast". Eliminating more bugs at compile-time is one of our goals. This DIP helps us get closer to the ideal.
Jan 04 2020
next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 04/01/2020 11:42 PM, Atila Neves wrote:
 
 I get the impression that most of the negative feedback here falls into 
 the following categories:
 
 1) This will break too much code
 2) Crappy code is ok, don't burden users to make their code  safe
 3) It's too much effort to convert existing code to  safe
There is a solution to all three of the categories that you have described that would be of major benefit to D over all. And it has not been posted on this thread yet. We defer this going live till D3. This way we can do a big push for all the changes that have the potential for changing workflows and limitations of existing code while ensuring a massive announcement when we have got everything ready to be used. There would still be the preview switch, but it won't be made the default by itself. It would be grouped into a new switch ``-preview=d3`` and when we are ready we can turn that on by default instead. Lets tell a story about how to do memory safety, that gives us headlines. Lets not do stuff that causes people pain that they are not fully on board with.
Jan 04 2020
next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/4/2020 3:23 AM, rikki cattermole wrote:
 We defer this going live till D3.
D's future will be in incremental improvements, not creating a new language.
Jan 04 2020
parent rikki cattermole <rikki cattermole.co.nz> writes:
On 05/01/2020 10:25 AM, Walter Bright wrote:
 On 1/4/2020 3:23 AM, rikki cattermole wrote:
 We defer this going live till D3.
D's future will be in incremental improvements, not creating a new language.
I did not suggest a new language. I have said this for many years, D3 will be from philosophical changes, not technical and safe by default is a perfect candidate for that.
Jan 04 2020
prev sibling parent Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
On Saturday, 4 January 2020 at 11:23:24 UTC, rikki cattermole 
wrote:
 There is a solution to all three of the categories that you 
 have described that would be of major benefit to D over all. 
 And it has not been posted on this thread yet.
Actually it has been. But creating a plan to manage these large changes does not appear to be valued and instead everyone is focused on complaining. This thread is supposed to be direction on improving the DIP not the management of a larger vision. Big https://forum.dlang.org/post/tlpwfwwakfmowpnwrvcg forum.dlang.org
Jan 04 2020
prev sibling next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/4/2020 2:42 AM, Atila Neves wrote:
 Most D code is  safe. Nearly all of it is. Unless you're taking addresses of 
 locals (which can be made  safe by using DIP1000 and scope),
When passing the address of a local to a function, nearly all of that can be easily and safely fixed by changing the function parameter from `T*` to `ref T`.
Jan 04 2020
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/4/2020 2:42 AM, Atila Neves wrote:
 most code is  safe anyway
And most of the rest can be trivially made safe. Which brings up something interesting: With safe as the default, far fewer annotations will be needed for functions! Since nobody likes annotations, including me, this is good.
Jan 04 2020
prev sibling next sibling parent reply Gregor =?UTF-8?B?TcO8Y2ts?= <gregormueckl gmx.de> writes:
On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1028, "Make  safe the Default":

 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688554b/DIPs/DIP1028.md

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

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

 Anyone intending to post feedback in this thread is expected to 
 be familiar with the reviewer guidelines:

 https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md

 *Please stay on topic!*

 Thanks in advance to all who participate.
My concern is about forcing such a transition onto the D ecosystem at all. Making this change the default in the D compiler will create a split in the ecosystem. I don't really know a single programming language ecosystem of notable size that went smoothly through a transition that altered the syntax and/or semantics of previously written code. If someone could name a positive example, I'd be grateful. The obvious counterexample here is the Python 2 to Python 3 transition. Python 3.0 was released in December 2008 and we're at the end of the decade long deprecation period of Python 2. There's still a lot of software that hasn't made the transition. Most of the changes were small, but they required people to touch existing code. Even automated tools like 2to3 didn't make a lot of impact. I'm running a variant of Arch Linux here, that made Python 3 the default fairly early. Just running a "grep python2 /usr/bin/*" still finds a couple of scripts that need Python 2. D already had a schism in the past with Tango vs. Phobos in the D 1.0 days. It held the development of the ecosystem back. D 2.0 has matured in recent years and it has enjoyed a period of relative stability that I believe increased its appeal. Any language change that forces large scale alteration of existing code a will undermine all this again. This may put the language on the sidelines as a "toy", "research" or "unstable" language in the perception of many. Walter admits that this drive to create a type safe version of D is marketing driven. The assertion is that languages need to have this property to be successful in the future. Is that reward worth the risk of alienating existing users? I would propose a more gradual transition, if that is feasibly in any way. A rough sketch might be: - Phase 1: Introduce module level pragmas that enable safe-by-default or alternatively perhaps an explicit opt out at module level. Recommend that modules start with this declaration, but don't enforce it. - Phase 2: When enough modules in dub packages contain these pragmas, enable a compiler warning if the compiler sees a module without such a pragma. - Phase 3: If sufficent packages in dub have been annotated accordingly (say, >90% in dub), the global switch can be thrown. This plan would put an effort on educating and convincing the community to make the change. Progression should be milestone based, not deadline based. It is important to send the message that the change is being made gradually and carefully. Even with this gradual transition, D can still claim to be a safe language. Projects that want to be safe by default can easily check that all modules have the corresponding pragma at the top. That's not worse than other static checks that are performed on source code in CI/CD environments.
Jan 04 2020
parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/4/2020 10:51 AM, Gregor Mückl wrote:
 [...]
The transition plan of starting with -preview=feature and eventually changing it to -revert=feature has so far been satisfactory. It gives people plenty of warning and an ability to transition at their own pace.
Jan 04 2020
prev sibling next sibling parent reply Sebastiaan Koppe <mail skoppe.eu> writes:
On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1028, "Make  safe the Default":
I expected this to take at least another year or two. I am very glad it is happening now. Because of dip1000 I have been using safe for a while and having it be the default is the only thing that makes sense. Mainly because of the fact that of all d code out there, only a small part is system (and it should decline relatively going forward), which means that annotating the system parts is easier than annotating the safe parts. Especially when you have the compiler complain something isn't safe versus pretending everything is system. To abuse a Chinese proverb: the best time for safe as default was 20 years ago, the second best time is now. With the preview and revert flags there is plenty time to develop tools to automate the transition, as others have mentioned here as well.
Jan 04 2020
parent reply jxel <jxel gmall.com> writes:
On Saturday, 4 January 2020 at 19:27:25 UTC, Sebastiaan Koppe 
wrote:
 On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1028, "Make  safe the Default":
I expected this to take at least another year or two. I am very glad it is happening now. Because of dip1000 I have been using safe for a while and having it be the default is the only thing that makes sense. Mainly because of the fact that of all d code out there, only a small part is system (and it should decline relatively going forward), which means that annotating the system parts is easier than annotating the safe parts. Especially when you have the compiler complain something isn't safe versus pretending everything is system.
To use an argument that is being used against why this shouldn't happen. You can just do: safe: Its nice and easy and does what you want, then you can annotate everything else that needs to with system.
Jan 04 2020
parent reply Sebastiaan Koppe <mail skoppe.eu> writes:
On Saturday, 4 January 2020 at 19:37:43 UTC, jxel wrote:
 To use an argument that is being used against why this 
 shouldn't happen. You can just do:

  safe:

 Its nice and easy and does what you want, then you can annotate 
 everything else that needs to with  system.
That makes no sense to me. Instead of sane defaults I am expected to prepend every file with some customary intro? And even if I do that, probably no dependency I use does. Just like hardly any dub package is bothered to do safe right now. Besides, it doesn't work for everything, I have tried.
Jan 04 2020
next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Saturday, 4 January 2020 at 20:19:09 UTC, Sebastiaan Koppe 
wrote:
 Besides, it doesn't work for everything, I have tried.
This should be fixed regardless of defaults. We'll want it either way.
Jan 04 2020
prev sibling next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/4/2020 12:19 PM, Sebastiaan Koppe wrote:
 That makes no sense to me. Instead of sane defaults I am expected to prepend 
 every file with some customary intro? And even if I do that, probably no 
 dependency I use does. Just like hardly any dub package is bothered to do
 safe 
 right now.
With D, I have repeatedly learned the lesson of the value of having the right thing by default, so no action is required by the user. It's surprisingly enormous. Regrettably I did not push for safe by default many years ago.
Jan 04 2020
prev sibling parent reply jxel <jxel gmall.com> writes:
On Saturday, 4 January 2020 at 20:19:09 UTC, Sebastiaan Koppe 
wrote:
 On Saturday, 4 January 2020 at 19:37:43 UTC, jxel wrote:
 To use an argument that is being used against why this 
 shouldn't happen. You can just do:

  safe:

 Its nice and easy and does what you want, then you can 
 annotate everything else that needs to with  system.
That makes no sense to me. Instead of sane defaults I am expected to prepend every file with some customary intro? And even if I do that, probably no dependency I use does. Just like hardly any dub package is bothered to do safe right now.
I looked at a few of the dub packages that work with the safe transition, some of them just had trusted: at the top. A lot of thr ones that did work were small or entirely templated. Dub honestly isnt the best place to look at good code anyways. Is that your goal, you want to force safe on people so that their code works with your code? You want sane defaults at the cost of breaking almost every piece of code out there. As well as any tutorials, examples, and documentation. That's the definition of insanity. What is a good default depends on what the person uses for D. Anyone that uses system will make the same argument as you, why should they preface every file with system:. Such anecdotal rationale isnt good enough.
 Besides, it doesn't work for everything, I have tried.
Exactly the point, people are trying to push system: as some easy alternative solution. Its not.
Jan 04 2020
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Sat, Jan 04, 2020 at 10:35:19PM +0000, jxel via Digitalmars-d wrote:
[...]
 I looked at a few of the dub packages that work with the safe
 transition, some of them just had  trusted: at the top.
[...] Yikes. Which packages are those? Blanket trusted at the top of a file is a huge anti-pattern, and a big red flag that the code is *not* to be trusted. Proper use of trusted dictates that it should be as small and as contained as possible, and that it should only be applied to functions that export a safe API. I.e., this: void trustedMemset(void* buf, size_t sz, ubyte data) trusted is flat-out wrong code, because there is no way to ensure that the parameters received by the function are actually safe. The correct signature is: void trustedMemset(void[] buf, ubyte data) trusted because the slice ensures that the length will always be consistent with the actual buffer size when passed from safe code. (Of course, all bets are off if the caller is system.) There is no way you can check an entire module this way *and* ensure it continues to obey this rule over time in the face of ongoing code changes. (And that's not to mention the respective function bodies, all of which must be vetted before it can be trusted.) I absolutely do not trust any module that has trusted: at the top. T -- Spaghetti code may be tangly, but lasagna code is just cheesy.
Jan 04 2020
parent reply jxel <jxel gmall.com> writes:
On Sunday, 5 January 2020 at 04:07:52 UTC, H. S. Teoh wrote:
 On Sat, Jan 04, 2020 at 10:35:19PM +0000, jxel via 
 Digitalmars-d wrote: [...]
 I looked at a few of the dub packages that work with the safe 
 transition, some of them just had  trusted: at the top.
[...] Yikes. Which packages are those? Blanket trusted at the top of a file is a huge anti-pattern, and a big red flag that the code is *not* to be trusted. Proper use of trusted dictates that it should be as small and as contained as possible, and that it should only be applied to functions that export a safe API. I.e., this: void trustedMemset(void* buf, size_t sz, ubyte data) trusted is flat-out wrong code, because there is no way to ensure that the parameters received by the function are actually safe. The correct signature is: void trustedMemset(void[] buf, ubyte data) trusted because the slice ensures that the length will always be consistent with the actual buffer size when passed from safe code. (Of course, all bets are off if the caller is system.) There is no way you can check an entire module this way *and* ensure it continues to obey this rule over time in the face of ongoing code changes. (And that's not to mention the respective function bodies, all of which must be vetted before it can be trusted.) I absolutely do not trust any module that has trusted: at the top. T
Well you can call safe code from system, so you can't really guarantee the value is correct in safe. Kind of the same situation with an uninitialized bool that evaluates differently because of the code gen. The only way to guarantee it is valid is if you created the variable in safe and wasn't passed as a parameter. Anyways, realistically people are just going to use trusted: more instead of system: because trusted: is an actual solution and doesn't require fixing templates and any other anomalies that show up. So yes more code will work with safe but it won't actually make it safer.
Jan 05 2020
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Sun, Jan 05, 2020 at 04:43:55PM +0000, jxel via Digitalmars-d wrote:
[...]
 Well you can call  safe code from  system, so you can't really
 guarantee the value is correct in  safe.
The guarantees of safe is conditioned upon being called from other safe code. As long as somewhere at the top of the call chain there's a system function, then all bets are off. This is why this DIP is so important: until main() can become safe, there's always a possibility that somewhere along the line you screwed up and negated the guarantees of safe. This is unavoidable; for example a system main() could have trashed the entire RAM before calling a safe function, and it's already in UB land when the safe function runs, so there's no way for the safe function to guarantee anything. Our current situation is that we have system on top of the call chain (because not everything is safe yet) and maybe some safe bits lower down or at the bottom. Where we want to get to is safe at the top, and small bits of system at the bottom gated by properly-audited trusted entry points. This DIP is an important step in this direction.
 Kind of the same situation with an uninitialized bool that evaluates
 differently because of the code gen. The only way to guarantee it is
 valid is if you created the variable in  safe and wasn't passed as a
 parameter.
D always initializes all locals. Writing `bool b = void;' is system, so again, once your caller is system, all bets are off further down the call chain.
 Anyways, realistically people are just going to use  trusted: more
 instead of  system: because  trusted: is an actual solution and
 doesn't require fixing templates and any other anomalies that show up.
 So yes more code will work with  safe but it won't actually make it
 safer.
If I had my way, I'd outright outlaw " trusted:" and only allow it on smaller constructs. If you really wanted to trust an entire module that's essentially system, just write main() system and be done with it. Why lie to yourself for no benefit whatsoever? T -- Life is complex. It consists of real and imaginary parts. -- YHL
Jan 05 2020
next sibling parent reply jxel <jxel gmall.com> writes:
On Sunday, 5 January 2020 at 17:57:18 UTC, H. S. Teoh wrote:
 On Sun, Jan 05, 2020 at 04:43:55PM +0000, jxel via 
 Digitalmars-d wrote: [...]
 Well you can call  safe code from  system, so you can't really 
 guarantee the value is correct in  safe.
The guarantees of safe is conditioned upon being called from other safe code. As long as somewhere at the top of the call chain there's a system function, then all bets are off. This is why this DIP is so important: until main() can become safe, there's always a possibility that somewhere along the line you screwed up and negated the guarantees of safe. This is unavoidable; for example a system main() could have trashed the entire RAM before calling a safe function, and it's already in UB land when the safe function runs, so there's no way for the safe function to guarantee anything. Our current situation is that we have system on top of the call chain (because not everything is safe yet) and maybe some safe bits lower down or at the bottom. Where we want to get to is safe at the top, and small bits of system at the bottom gated by properly-audited trusted entry points. This DIP is an important step in this direction.
What if you have a safe library that gets called from another program that is system. You can't guarantee anything. If safety matters to you then use it. Its not going to stop bad code. If someone gets an error and inserting trusted gets it to compile, or they can spend 2-4 hours restructuring code, they are going to use the option that doesn't waste their time.
 Kind of the same situation with an uninitialized bool that 
 evaluates differently because of the code gen. The only way to 
 guarantee it is valid is if you created the variable in  safe 
 and wasn't passed as a parameter.
D always initializes all locals. Writing `bool b = void;' is system, so again, once your caller is system, all bets are off further down the call chain.
Bzz, wrong. You can void initialize in safe.
 Anyways, realistically people are just going to use  trusted: 
 more instead of  system: because  trusted: is an actual 
 solution and doesn't require fixing templates and any other 
 anomalies that show up. So yes more code will work with  safe 
 but it won't actually make it safer.
If I had my way, I'd outright outlaw " trusted:" and only allow it on smaller constructs. If you really wanted to trust an entire module that's essentially system, just write main() system and be done with it. Why lie to yourself for no benefit whatsoever? T
If its safe by default, throwing system: at the top won't work for everything. It'll stop template auto inferring, so trusted is the only real simple solution. If you are using system, it doesn't matter to you cause you don't get that safety anyways. Its a matter of getting your code to compile again, trusted is going to be the quickest easiest solution.
Jan 05 2020
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/5/2020 12:13 PM, jxel wrote:
 inserting  trusted gets 
 it to compile, or they can spend 2-4 hours restructuring code, they are going
to 
 use the option that doesn't waste their time.
This misses the point. D provides plenty of escapes from writing safe code. The point is not to stop all those escapes, but to: 1. make it clear where those escapes are 2. make it auditable, i.e. the QA dept can grep for ` trusted` and then decide whether to have a company standard about that or not. In the absence of such, the code is not auditable. For example, in C: void foo() { int* p; } // initialized to garbage This is not auditable. Whereas in D: system void foo() { int* p = void; } // initialized to garbage *is* auditable and is intentional and requires extra effort, it is not the default.
Jan 05 2020
parent jxel <jxel gmall.com> writes:
On Monday, 6 January 2020 at 02:17:42 UTC, Walter Bright wrote:
 On 1/5/2020 12:13 PM, jxel wrote:
 inserting  trusted gets it to compile, or they can spend 2-4 
 hours restructuring code, they are going to use the option 
 that doesn't waste their time.
This misses the point. D provides plenty of escapes from writing safe code. The point is not to stop all those escapes, but to: 1. make it clear where those escapes are 2. make it auditable, i.e. the QA dept can grep for ` trusted` and then decide whether to have a company standard about that or not. In the absence of such, the code is not auditable. For example, in C: void foo() { int* p; } // initialized to garbage This is not auditable. Whereas in D: system void foo() { int* p = void; } // initialized to garbage *is* auditable and is intentional and requires extra effort, it is not the default.
There seems to be a disconnect of Practicality Vs. Ideology here. I had a similar argument with someone who was distained with std::map<> for being implemented as an ordered map instead of as a hash map. That the basic map should be a hash map as in the general case you don't need it to be sorted and you pay for the performance impact. That its intuitive and what people expect of the basic map type to be implemented as a hash map. This isn't practical to do. I agree with your ideology, it is sound. The price you have to pay for it though, is too high. In my opinion. If you don't think it is, no one can stop you.
Jan 05 2020
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 05.01.20 18:57, H. S. Teoh wrote:
 Writing `bool b = void;' is  system
I wish. https://issues.dlang.org/show_bug.cgi?id=19968 https://github.com/dlang/dlang.org/pull/2260 https://issues.dlang.org/show_bug.cgi?id=20148
Jan 05 2020
parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/5/2020 3:48 PM, Timon Gehr wrote:
 On 05.01.20 18:57, H. S. Teoh wrote:
 Writing `bool b = void;' is  system
I wish. https://issues.dlang.org/show_bug.cgi?id=19968 https://github.com/dlang/dlang.org/pull/2260 https://issues.dlang.org/show_bug.cgi?id=20148
I'm glad there's a bugzilla for it marked with the `safe` keyword so I don't have to harangue anyone :-)
Jan 05 2020
prev sibling next sibling parent reply NaN <divide by.zero> writes:
On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 Anyone intending to post feedback in this thread is expected to 
 be familiar with the reviewer guidelines:

 https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md

 *Please stay on topic!*

 Thanks in advance to all who participate.
Has anybody looked at performance considerations since safe mandates bounds checking is left on in release mode?
Jan 04 2020
parent reply James Blachly <james.blachly gmail.com> writes:
On 1/4/20 8:43 PM, NaN wrote:
 On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 
 Has anybody looked at performance considerations since  safe mandates 
 bounds checking is left on in release mode?
Great question. Presumably we can compile with nobounds for performance sensitive code. IMO this is a reasonable trade-off. Rust leaves bounds checking on always, apparently.
Jan 06 2020
parent Paulo Pinto <pjmlp progtools.org> writes:
On Monday, 6 January 2020 at 13:18:01 UTC, James Blachly wrote:
 On 1/4/20 8:43 PM, NaN wrote:
 On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 
 Has anybody looked at performance considerations since  safe 
 mandates bounds checking is left on in release mode?
Great question. Presumably we can compile with nobounds for performance sensitive code. IMO this is a reasonable trade-off. Rust leaves bounds checking on always, apparently.
Rust, just like most safe systems programming languages provides an escape hatch (which requires unsafe), and also does bounds checking elision via dataflow analysis.
Jan 06 2020
prev sibling next sibling parent reply Jon Degenhardt <jond noreply.com> writes:
On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1028, "Make  safe the Default":

 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688554b/DIPs/DIP1028.md
From the discussions it appears the amount and nature of breakage will depend on whether DIP1000 is enabled. Assuming this is true, it make sense to discuss DIP1000 in DIP1028. For example: * Is implementation of DIP1028 dependent on making DIP1000 or something similar the default? * If DIP1000 is not the default when '-preview=safedefault' becomes available, will '-preview=safedefault' have the effect of turning on the '-preview=dip1000'? * Discussion of the types of breakage that will be avoided by having DIP1000 enabled. --Jon
Jan 04 2020
parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/4/2020 7:59 PM, Jon Degenhardt wrote:
  From the discussions it appears the amount and nature of breakage will depend 
 on whether DIP1000 is enabled. Assuming this is true, it make sense to discuss 
 DIP1000 in DIP1028. For example:
 * Is implementation of DIP1028 dependent on making DIP1000 or something
similar 
 the default?
 * If DIP1000 is not the default when '-preview=safedefault' becomes available, 
 will '-preview=safedefault' have the effect of turning on the
'-preview=dip1000'?
 * Discussion of the types of breakage that will be avoided by having DIP1000 
 enabled.
DIP1000 and DIP1028 will remain independent effects.
Jan 04 2020
prev sibling next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/2/20 4:47 AM, Mike Parker wrote:
 This is the feedback thread for the first round of Community Review for 
 DIP 1028, "Make  safe the Default":
 
 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688
54b/DIPs/DIP1028.md 
 
 
 All review-related feedback on and discussion of the DIP should occur in 
 this thread. The review period will end at 11:59 PM ET on January 16, or 
 when I make a post declaring it complete.
 
 At the end of Round 1, if further review is deemed necessary, the DIP 
 will be scheduled for another round of Community Review. Otherwise, it 
 will be queued for the Final Review and Formal Assessment.
 
 Anyone intending to post feedback in this thread is expected to be 
 familiar with the reviewer guidelines:
 
 https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md
 
 *Please stay on topic!*
 
 Thanks in advance to all who participate.
A consideration I didn't think of before. What happens here? extern(C) void free(void *ptr); Is this considered safe now by default? We should not have that be the case. -Steve
Jan 08 2020
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/8/20 9:14 PM, Steven Schveighoffer wrote:
 On 1/2/20 4:47 AM, Mike Parker wrote:
 This is the feedback thread for the first round of Community Review 
 for DIP 1028, "Make  safe the Default":

 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688
54b/DIPs/DIP1028.md 


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

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

 Anyone intending to post feedback in this thread is expected to be 
 familiar with the reviewer guidelines:

 https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md

 *Please stay on topic!*

 Thanks in advance to all who participate.
A consideration I didn't think of before. What happens here? extern(C) void free(void *ptr); Is this considered safe now by default? We should not have that be the case.
extern(C++) prototypes also. Basically, any function where ` safe` does not factor into the function mangled name, and no implementation is present should be assumed to be system. -Steve
Jan 08 2020
prev sibling next sibling parent reply berni44 <dlang d-ecke.de> writes:
On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1028, "Make  safe the Default":
Not sure, if this has allready been mentioned, I didn't read all posts, so forgive me my laziness... With safe being the default, a typical hello-world-program would need system. I don't like this. So I thought, why couldn't (as a default) the compiler deduce safe/ system automatically, like he does for templates? One still could write safe if this is important, so the compiler will complain, if it isn't safe. Or, at least, writeln and co should be trusted... (IMHO, there should be a real good reason, whenever a Phobos function does not work in safe-code...)
Jan 12 2020
parent Ogi <ogion.art gmail.com> writes:
On Sunday, 12 January 2020 at 12:28:23 UTC, berni44 wrote:
 With  safe being the default, a typical hello-world-program 
 would need  system. I don't like this.
writeln is safe as long as you use it with safe arguments. import std.stdio; safe: void main() { writeln("Hello, world!"); } Compiles without errors.
Jan 12 2020
prev sibling next sibling parent reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1028, "Make  safe the Default":

 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688554b/DIPs/DIP1028.md
First, Walter, thanks for writing this, and Mike, thanks for taking care of the review process :-) Since I'm co-author of some key bits of the current reviewer guidelines, I'll try to follow the questions there fairly precisely and see if it makes for some nice structure in my feedback. (1) Is the proposal acceptable as a language change in principle? Clearly yes: safe-by-default fits within an observable trend of languages getting more and more concerned with provable memory safety, and with a related trend of requiring the user to write provably safe code. Rust in particular has significantly raised the bar in this space, and proven that such constraints are often welcomed by developers. The should we/shouldn't we questions around this are likely to come down to practicalities. However, this does seem like a fairly major philosophical shift in the language design. Up until now D has (possibly only implicitly) followed what amounts to a "permissive by default" design philosophy where (apart from really obvious stupidities) the default setting is that one can do what one likes, and stronger design constraints (including memory safety but also e.g. constness and immutability, purity, nogc, nothrow, final methods, ...) are readily available but all opt-in. The existence of a parallel DIP for nothrow-by-default seems to confirm this push for a more restrictive-by-default language. The two DIPs should be considered on their own merits, so I won't try to couple them, beyond noticing the design trend they both contribute to. However, the impact of that trend should be considered in terms of the impact on the D development experience. Some thoughts on pros and cons will be covered below. As a separate issue, it's probably a good idea to take discussion of keyword choices off the table for the purposes of this DIP. safe, trusted and system have (2) Is the proposal workable in practice? -- "Is the proposed feature specified in sufficient detail?" -- There is sufficient spec to make the change happen, per se. What is missing is a sufficiently detailed overview of the practical problems that will arise from the migration, and explicit proposals for how to deal with them. This brings us to ... -- "Are edge cases, flaws, and risks identified and addressed?" -- The identified breaking changes and risks are discussed only at a high level. The proposed solutions (explicit annotation of all non-templated functions) are correct per se but don't really capture the complexity of the likely reality. Some examples: * system-by-default means that if a safe attribute is overlooked, that bug can be fixed without breaking change: by contrast, with safe-by-default, an overlooked system attribute can't be fixed without breaking change to the API concerned. (Yes, I can hear you now saying that if the function isn't safe then the compiler will object and force the user to add system, so this oversight won't happen. But this is about intent: the function might be safe in practice, as initially implemented, but with no intention to preserve that guarantee. One advantage of opt-in constraints is that generally one can be sure that the developer means them to be there.) * As noted already in others' feedback, the use of ` system:` to tag multiple functions has an asymmetric impact compared to ` safe:`. In the latter case one likely _wants_ that attribute to apply to all subsequent functions, including templated ones. However, we probably do not want catch-all ` system:` to override the inferred safety of templated function instantiations. This edge case should be discussed, with suggestions for how to address it. * The DIP contains no advice or impact assessment for the case of 3rd-party libraries that are no longer actively maintained, and the consequent risks for obsoleting a large amount of existing D code. Ideally the DIP should contain a robust estimate of the numbers of projects this might impact, and some discussion of the pros and cons of that impact, and mitigation strategies. The migration plan should include clear steps for how to regularly remeasure the expected impact on 3rd-party library usability over time (e.g. as more and more libraries are adapted to support the new feature). There should also be explicit criteria for deciding on what level of impact is (un)acceptable in order to transition from `--preview=safedefault` to the feature being on by default. * Issues related to taking the address of local variables (mentioned several times in this discussion thread) should be discussed, with reference to other DIPs that address that concern. It should be made clear whether finalization of those other features is needed (or strongly desirable) to finalize safe-by-default. * The impact of safe-by-default on `extern` APIs should be discussed. We have no reasonable grounds to assume these functions are safe by default: the DIP should address how to deal with this (which should ideally not rely on developer virtue). * The impact of safe-by-default on the ability to write ` nogc` code should be covered by the DIP, including appropriate references to other relevant DIPs. * The advice in the current draft of the DIP to "annotate functions that aren't safe with ` trusted` or ` system` should include clear guidance as to _when_ to use ` trusted` and when to use ` system`. We don't want to "fix" migration problems by blindly slapping ` trusted` onto code that hasn't been properly validated. We have already had cases of people trying to do that just to get stuff to compile with ` safe` <https://github.com/msoucy/dproto/pull/79> so we should try to avoid the risk of spreading that kind of code around. (Rust has to deal with similar concerns, of too many devs just adding `unsafe` blocks willy-nilly to get the compiler off their backs, and I've seen similarly problematic uses of trusted in even some quite prominent D libraries.) * It seems likely that safe-by-default will increase the number of occasions that developers have to use trusted. The DIP should try to make some estimate of the amount of impact, and should address whether it is necessary (or at least very desirable) to add support for trusted code blocks as well as functions (cf. what Rust allows with `unsafe`, and feedback by Manu and others on the problems of needing to define local lambdas to apply the trusted attribute to). These last few examples touch on another missing risk: there is no assessment of the expected impact on developer experience. Arguably a very nice productivity feature of D is the ability to hack readily and only worry about introducing strict constraints when one actively wants them. This is part of what makes D so readily usable for everything from small casual scripts to large-scale libraries and applications. Those of us who tend to apply ` safe` willingly and regularly may underestimate the impact on users who prefer fast iteration over strictly enforced constraints. I'm particularly concerned that it may get too many developers into the habit of unthinkingly slapping down ` trusted` on code that doesn't deserve it, rather as some Rust developers just `unsafe` lots of things without really thinking it through. It's easy to dismiss those people as architects of their own pain, but the problem is how such users can spread bad habits by example. We should perhaps not underestimate the importance of consent in submitting to constraints ... :-) OTOH the positive flipside of imposing constraints by default is that it means that the combination of different constraints gets much better battle tested: there is a much lower barrier to discovering (and hopefully fixing) tricky edge cases. -- "Are there any platform or architecture pitfalls to be aware of?" -- None that I can think of. -- "Is there an implementation that proves the proposed feature works in practice?" -- The basic implementation is likely trivial. Questions of proof need to apply more to the migration path (see below). -- "Does the DIP consider prior work from other languages?" -- Yes, but the consideration is merely of their existence. It would be good to have a more detailed comparison, discussing how they achieve those outcomes, and what the resulting constraints and developer experiences are. -- "If the proposed feature is a breaking change, is there a well-defined migration path?" -- This is the crux of the matter. There are many small finnicky impacts that this change will have. The basic migration path of using `--preview=safedefault` and ironing out kinks is sound. However, what needs to be established (which is currently missing) is a clear statement of the criteria that will be used to determine when (and if!) it is appropriate to transition from the `--preview` feature to having safe-by-default ... by default. In short, acceptance of moving to the `--preview=safedefault` stage should NOT be taken as acceptance of the safe-by-default transition in its entirety. The DIP should define the definite blockers to that transition, and should outline a robust review process for the decision to finalize (or abandon) the change. The core code migration step (adding ` system` to non-templated functions without an existing ` safe`, ` trusted` or ` system` attribute) ought to be possible to automate: the DIP might mandate the creation of such a tool as a requirement before the transition can be finalized. (3) Summary The proposed feature is a significant breaking change. If we are lucky, the practical impact may be much smaller than one might anticipate, but that needs to be robustly established before approval can be given to the DIP (or at least, to transitioning away from `--preview=safedefault`). The DIP needs to provide much more detail on the anticipated impacts, the migration paths, and the risks for the existing and future D ecosystem (with particular attention to how many existing codebases may be obsoleted). It should also clarify if any other DIPs or experimental features need to be finalized before this DIP can be. The anticipated impact on both developer and maintainer experience should be carefully outlined, with clearly written mitigation strategies for the worst pain points. In short: since nothing stops anyone who cares from having a ` safe` codebase right now through the existing opt-in features, show us in detail how the pain of transitioning to opt-out is really worth it ;-)
Jan 13 2020
next sibling parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On Monday, 13 January 2020 at 15:57:38 UTC, Joseph Rushton 
Wakeling wrote:
 As a separate issue, it's probably a good idea to take 
 discussion of keyword choices off the table for the purposes of 
 this DIP.   safe,  trusted and  system have
Whoops, I forgot to complete my train of thought there :-) The paragraph should read: safe, trusted and system have well-defined meanings which are entirely compatible with the transition to safe-by-default. We should keep our focus on the stuff that needs to change, not the stuff that doesn't.
Jan 13 2020
prev sibling parent reply Arine <arine123445128843 gmail.com> writes:
On Monday, 13 January 2020 at 15:57:38 UTC, Joseph Rushton 
Wakeling wrote:
 Clearly yes:  safe-by-default fits within an observable trend 
 of languages getting more and more concerned with provable 
 memory safety, and with a related trend of requiring the user 
 to write provably safe code.  Rust in particular has 
 significantly raised the bar in this space, and proven that 
 such constraints are often welcomed by developers.
Rust doesn't just provide safety. It also provides a lot more other guarantees than just safety. It is low level and achieves memory safety *without* a GC. It provides guarantees for multi threading, that reduces data races and other difficult to diagnose problems. This is a world where single thread performance isn't getting significantly faster. But we are now getting CPUs with 64 cores and 128 threads. You can't just look at one aspect for Rust, without looking at every aspect. Java provides memory safety, but there's a reason why people using Rust don't use Java.
 As a separate issue, it's probably a good idea to take 
 discussion of keyword choices off the table for the purposes of 
 this DIP.   safe,  trusted and  system have well-defined 
 meanings which are entirely compatible with the transition to 
  safe-by-default.  We should keep our focus on the stuff that 
 needs to change, not the stuff that doesn't.
It's not just keyword choices. It's fundamentally how discover-able unsafe code is while reading safe code. This DIP is a big breaking change that is going to break basically all code out there. All documentation, all discussions, all example code, ~everything~. This is probably the only time to discuss something like this. It wouldn't make sense to accept this DIP, then have another DIP that causes a similar amount of breakage regarding a similar aspect of the language.
 In short: since nothing stops anyone who cares from having a 
 ` safe` codebase right now through the existing opt-in 
 features, show us in detail how the pain of transitioning to 
 opt-out is really worth it ;-)
I agree with this. People that want to write safe code write safe code. Those that don't want to, don't. Making safe by default won't make people write safe code that is actually safe, it'll just make them misuse trusted more.
Jan 13 2020
next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/13/20 12:13 PM, Arine wrote:
 This DIP is a big breaking change that is going to break basically all 
 code out there
Can someone explain this point of view to me? It seems extreme. I've also seen a lot of assertions that all documentation and tutorials (ALL) will be broken. -Steve
Jan 13 2020
next sibling parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On Monday, 13 January 2020 at 17:33:12 UTC, Steven Schveighoffer 
wrote:
 On 1/13/20 12:13 PM, Arine wrote:
 This DIP is a big breaking change that is going to break 
 basically all code out there
Can someone explain this point of view to me? It seems extreme. I've also seen a lot of assertions that all documentation and tutorials (ALL) will be broken.
Yea. This is something where both sides of the argument are better off avoiding rhetoric and providing clear empirical evidence. Obviously the onus is more strongly on the DIP proponents, but it's not helpful for anyone to offer unsubstantiated opinion rather than facts. Without demonstrable facts on hand, perhaps it's better to provide feedback on what facts need to be obtained rather than just unsubstantiated opinion?
Jan 13 2020
prev sibling parent reply bachmeier <no spam.net> writes:
On Monday, 13 January 2020 at 17:33:12 UTC, Steven Schveighoffer 
wrote:

 I've also seen a lot of assertions that all documentation and 
 tutorials (ALL) will be broken.
That was probably me. I don't recall ever saying all documentation and tutorials will be broken, but it will certainly cause problems for a lot of the material out in the wild, and it's the kind of breakage that will make folks run away. It's not just what's written in the documentation/tutorial either. You change one thing in a working example and all of a sudden it no longer compiles. Seriously, who changes to safe by default in a regular release? Ultimately it's up to the DIP author to make the case that this type of breakage won't happen. The author of this DIP did not do that, and anyone else making such a proposal would have it shot down immediately for exactly that reason.
Jan 13 2020
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/13/20 1:38 PM, bachmeier wrote:
 On Monday, 13 January 2020 at 17:33:12 UTC, Steven Schveighoffer wrote:
 
 I've also seen a lot of assertions that all documentation and 
 tutorials (ALL) will be broken.
That was probably me. I don't recall ever saying all documentation and tutorials will be broken, but it will certainly cause problems for a lot of the material out in the wild, and it's the kind of breakage that will make folks run away. It's not just what's written in the documentation/tutorial either. You change one thing in a working example and all of a sudden it no longer compiles. Seriously, who changes to safe by default in a regular release?
I feel this is a bit blown out of proportion. I see all the time on stackoverflow answers updated for e.g. newer versions of Swift. There's no reason to think the same thing wouldn't happen for D. But I also think it's going to be a very small part of the tutorials/docs that are incorrect. Looking at tour.dlang.org, I see the following pages that won't work with the DIP defaults: https://tour.dlang.org/tour/en/basics/memory (basically talks about safe D anyway, so it would need an update for sure) https://tour.dlang.org/tour/en/basics/type-qualifiers (runs fine with dip1000, so maybe we need to look at the order in which we turn on the various DIP defaults) https://tour.dlang.org/tour/en/basics/associative-arrays (object.keys is not safe, this would need to be fixed before implementation of the DIP) https://tour.dlang.org/tour/en/basics/exceptions (writeln(e.info) has issues with safety, that might not be a problem with the real DIP)
 
 Ultimately it's up to the DIP author to make the case that this type of 
 breakage won't happen. The author of this DIP did not do that, and 
 anyone else making such a proposal would have it shot down immediately 
 for exactly that reason.
You will have lots of time to get your code ready for the DIP to be the default. -Steve
Jan 13 2020
parent reply bachmeier <no spam.net> writes:
On Monday, 13 January 2020 at 20:32:32 UTC, Steven Schveighoffer 
wrote:
 On 1/13/20 1:38 PM, bachmeier wrote:
 On Monday, 13 January 2020 at 17:33:12 UTC, Steven 
 Schveighoffer wrote:
 
 I've also seen a lot of assertions that all documentation and 
 tutorials (ALL) will be broken.
That was probably me. I don't recall ever saying all documentation and tutorials will be broken, but it will certainly cause problems for a lot of the material out in the wild, and it's the kind of breakage that will make folks run away. It's not just what's written in the documentation/tutorial either. You change one thing in a working example and all of a sudden it no longer compiles. Seriously, who changes to safe by default in a regular release?
I feel this is a bit blown out of proportion. I see all the time on stackoverflow answers updated for e.g. newer versions of Swift. There's no reason to think the same thing wouldn't happen for D. But I also think it's going to be a very small part of the tutorials/docs that are incorrect. Looking at tour.dlang.org, I see the following pages that won't work with the DIP defaults:
If you only work with idiomatic D code, this DIP won't have much of an impact. If you're like me, and almost everything you've ever done with D has taken advantage of D's interoperability with C (one of its big selling points), it's a serious PITA, and every bit of documentation, tutorial, and blog post you've ever written for others will break. All of a sudden you have to tell others to litter their code with ugly trusted or system. All of this because adding a -safe switch isn't sufficient for those that want safe by default.
Jan 13 2020
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Monday, 13 January 2020 at 21:43:24 UTC, bachmeier wrote:
 All of this because adding a -safe switch isn't sufficient for 
 those that want safe by default.
Or better yet, let's make ` safe:` work well so we can do this on a per-module level. See: http://dpldocs.info/this-week-in-d/Blog.Posted_2020_01_13.html#my-attribute-proposal---no-changes-to-defaults
Jan 13 2020
next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 14/01/2020 10:46 AM, Adam D. Ruppe wrote:
 On Monday, 13 January 2020 at 21:43:24 UTC, bachmeier wrote:
 All of this because adding a -safe switch isn't sufficient for those 
 that want safe by default.
Or better yet, let's make ` safe:` work well so we can do this on a per-module level. See: http://dpldocs.info/this-week-in-d/Blog.Posted_2020_01_13.html#my-attribute-proposal---no changes-to-defaults
I'm not sure I like the idea that attributes are going down scopes like you have suggested. It should be explicit that you want that. Otherwise I'm on board.
Jan 13 2020
parent Adam D. Ruppe <destructionator gmail.com> writes:
On Tuesday, 14 January 2020 at 01:03:37 UTC, rikki cattermole 
wrote:
 I'm not sure I like the idea that attributes are going down 
 scopes like you have suggested. It should be explicit that you 
 want that.
In as much as like a " safe class" (or struct/interface/etc) makes sense, it would surely make the most sense that a safe class is one where all methods are safe. Ditto on nothrow and pure. So the descending into scopes is a consequence of that. Though you could argue that a nogc class is a class that cannot live on the GC heap instead... (i was so happy with disable operator new until that got deprecated). But still, the same idea can apply there too. We just need to define it as such. But that's the formal reason why these specific attributes would descend into scopes.
Jan 13 2020
prev sibling next sibling parent jmh530 <john.michael.hall gmail.com> writes:
On Monday, 13 January 2020 at 21:46:46 UTC, Adam D. Ruppe wrote:
 [snip]

 Or better yet, let's make ` safe:` work well so we can do this 
 on a per-module level. See:

 http://dpldocs.info/this-week-in-d/Blog.Posted_2020_01_13.html#my-attribute-proposal---no-changes-to-defaults
I like this approach. Looks like DIP 1029 is moving in that direction.
Jan 14 2020
prev sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 13.01.20 22:46, Adam D. Ruppe wrote:
 On Monday, 13 January 2020 at 21:43:24 UTC, bachmeier wrote:
 All of this because adding a -safe switch isn't sufficient for those 
 that want safe by default.
Or better yet, let's make ` safe:` work well so we can do this on a per-module level. See: http://dpldocs.info/this-week-in-d/Blog.Posted_2020_01_13.html#my-attribute-proposal---no changes-to-defaults
It does not mention nested functions and auto return functions. They should be treated like template functions (as they also have attributes inferred by default).
Jan 14 2020
prev sibling parent reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On Monday, 13 January 2020 at 17:13:36 UTC, Arine wrote:
 Rust doesn't just provide safety. It also provides a lot more 
 other guarantees than just safety. It is low level and achieves 
 memory safety *without* a GC. It provides guarantees for multi 
 threading, that reduces data races and other difficult to 
 diagnose problems. This is a world where single thread 
 performance isn't getting significantly faster. But we are now 
 getting CPUs with 64 cores and 128 threads.
Yes, indeed. That's kind of the point -- Rust has established a set of viable techniques for proving memory safety in a systems programming context. That in turn establishes that there is lot of scope for D to improve its memory-safety guarantees (in particular, being able to prove memory safety criteria in GC-free code). D has been learning and adapting from that -- and can continue to do so. But in terms of considering the basic viability of this DIP, the important point of consideration is whether it is desirable to have provable memory safety by default in a systems programming language. Rust gives us a clear example that it can be both desirable and achievable. The move to ever-more-parallel development gives us the extra motivation for why this will matter more and more in future. All the other stuff comes down to implementation details. The question is which of those implementation details matter when it comes to making safe-by-default viable in practice, and whether that is achievable with minimal transition problems. Note that all this is saying is that it is valid to make the proposal. It doesn't say that the proposal should be accepted (either on principled or on practical grounds). You may notice plenty of practical critique in the feedback I offered.
 You can't just look at one aspect for Rust, without looking at 
 every aspect. Java provides memory safety, but there's a reason 
 why people using Rust don't use Java.
Genuine question, as I'm not a Java dev: does Java genuinely provide _provable_ memory safety? Or is it just that in practice things will be memory safe because of the GC, and it doesn't allow you access to features that escape that safety blanket?
 It's not just keyword choices. It's fundamentally how 
 discover-able  unsafe code is while reading  safe code.
Isn't that the same as it's ever been -- search for trusted blocks? I don't see how that would change.
Jan 13 2020
parent reply Arine <arine123445128843 gmail.com> writes:
On Monday, 13 January 2020 at 17:34:48 UTC, Joseph Rushton 
Wakeling wrote:
 On Monday, 13 January 2020 at 17:13:36 UTC, Arine wrote:
 Rust doesn't just provide safety. It also provides a lot more 
 other guarantees than just safety. It is low level and 
 achieves memory safety *without* a GC. It provides guarantees 
 for multi threading, that reduces data races and other 
 difficult to diagnose problems. This is a world where single 
 thread performance isn't getting significantly faster. But we 
 are now getting CPUs with 64 cores and 128 threads.
Yes, indeed. That's kind of the point -- Rust has established a set of viable techniques for proving memory safety in a systems programming context. That in turn establishes that there is lot of scope for D to improve its memory-safety guarantees (in particular, being able to prove memory safety criteria in GC-free code).
That's the thing, D has a GC. If you are now trying to push Rust-like features into safe to allow safe non-gc memory, you are going to be adding restricting code that would otherwise not have to be to be safe with a GC. So the language becomes more restrictive like Rust, all while losing the benefit of having a GC and not needing to worry about those restrictions. The DIP that tried to disable dynamic array resizing is proof of that.
 You can't just look at one aspect for Rust, without looking at 
 every aspect. Java provides memory safety, but there's a 
 reason why people using Rust don't use Java.
Genuine question, as I'm not a Java dev: does Java genuinely provide _provable_ memory safety? Or is it just that in practice things will be memory safe because of the GC, and it doesn't allow you access to features that escape that safety blanket?
Depends what you mean by provable. If you mean using potentially unsafe features and the compiler being able to prove they are being used safely, no I don't think any compiler does that. If you mean it's provable to be safe because it doesn't allow unsafe features like basically what D does, then yes. It'd be more safe than D in that regard as it simply doesn't allow pointers. If you also take into consideration, in it's current state, D isn't provable to be safe as it has features that a provably *unsafe*. At least one person here even thought you couldn't use the feature in safe code (see: void initializers).
 It's not just keyword choices. It's fundamentally how 
 discover-able  unsafe code is while reading  safe code.
Isn't that the same as it's ever been -- search for trusted blocks? I don't see how that would change.
If your in a safe function trying to figure out where unsafe calls are, how would you search for trusted? The function you are searching for could be in one of the thousands of different files. Are you going to go look at each and every one? There's an example a few pages back that illustrates this.
Jan 13 2020
parent reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On Tuesday, 14 January 2020 at 05:23:10 UTC, Arine wrote:
 That's the thing, D has a GC. If you are now trying to push 
 Rust-like features into  safe to allow  safe non-gc memory, you 
 are going to be adding restricting code that would otherwise 
 not have to be to be  safe with a GC. So the language becomes 
 more restrictive like Rust, all while losing the benefit of 
 having a GC and not needing to worry about those restrictions. 
 The DIP that tried to disable dynamic array resizing is proof 
 of that.
It's not about what _I'm_ doing. There are already DIPs and experimental features that extend the reach of what safe can verify, allowing validation of memory safety for various GC-free (or rather, GC-agnostic) scenarios. That doesn't impose Rust-style restrictions on anyone who doesn't want them -- you can GC away to your heart's content -- but it makes it more possible for people who want to work _without_ the GC to validate the memory safety of their programs. And that provides a context where safe-by-default might start to look less intrusive. BTW, note that Rust, having dropped built-in GC early on in its design, is now looking at ways to support it as a developer opt-in: https://docs.rs/gc/0.3.3/gc/ So, these things are not either-or. Whether a developer wants to use GC or not (or a hybrid of GC- and non-GC-backed memory allocation), there's a common interest in being able to validate at compile time that the overall result is memory safe.
 It's not just keyword choices. It's fundamentally how 
 discover-able  unsafe code is while reading  safe code.
Isn't that the same as it's ever been -- search for trusted blocks? I don't see how that would change.
If your in a safe function trying to figure out where unsafe calls are, how would you search for trusted? The function you are searching for could be in one of the thousands of different files. Are you going to go look at each and every one? There's an example a few pages back that illustrates this.
I'm sorry, but I can't find the example you are referring to. Can you provide a link to the post? As for the rest of your remarks: I understand (and sympathize) with the wish for better ways to track down those parts of a codebase that need manual validation. But that problem is the same problem whether we have safe as an opt-in or as the default. From what you've written elsewhere, do I understand correctly that what you're arguing for is an alternative way of marking those pieces of code, and that you believe this would make it easier to search out those problematic parts of a codebase? On that note I disagree with your earlier remark:
 If we are going to make  safe the default we don't really need
  safe keyword, or  system or  trusted. It's make sense to get
 rid of all 3 of them and just add  unsafe. If you are going to
 do it, might as well do it right the first time.
I agree that trusted can be abused, but limiting us to just unsafe (à la Rust) seems to me to be unacceptable. One of the horrible things about Rust is that you can put an `unsafe { ... }` block around any single arbitrary line inside a function, and the compiler stops complaining -- despite the fact that the validity of that unsafe call may be contingent on stuff in the other lines of the function. And yet the function signature offers no clue to the user that there might be anything risky going on underneath. trusted allows us to clearly annotate those function signatures such that the user is always clear which functions are in need of overall validation. FWIW I agree with Steven Schveighoffer that it would be useful to update the behaviour of trusted such that the developer must mark up the explicitly unsafe lines: https://forum.dlang.org/post/qv7t8b$2h2t$1 digitalmars.com However, I'm not sure that this needs to be coupled with the current DIP. It's a complementary and helpful change to a safe-by-default switchover, but not a _necessary_ one.
Jan 14 2020
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 14.01.20 15:56, Joseph Rushton Wakeling wrote:
 On Tuesday, 14 January 2020 at 05:23:10 UTC, Arine wrote:
 That's the thing, D has a GC. If you are now trying to push Rust-like 
 features into  safe to allow  safe non-gc memory, you are going to be 
 adding restricting code that would otherwise not have to be to be 
  safe with a GC. So the language becomes more restrictive like Rust, 
 all while losing the benefit of having a GC and not needing to worry 
 about those restrictions. The DIP that tried to disable dynamic array 
 resizing is proof of that.
It's not about what _I'm_ doing.  There are already DIPs and experimental features that extend the reach of what safe can verify, allowing validation of memory safety for various GC-free (or rather, GC-agnostic) scenarios.
Which features and DIPs are those?
Jan 14 2020
parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On Wednesday, 15 January 2020 at 02:08:18 UTC, Timon Gehr wrote:
 It's not about what _I'm_ doing.  There are already DIPs and 
 experimental features that extend the reach of what  safe can 
 verify, allowing validation of memory safety for various 
 GC-free (or rather, GC-agnostic) scenarios.
Which features and DIPs are those?
DIP1000 for example. (Yes, I know that this didn't formally get accepted but stuff has moved forward derived from this.) Obviously this is not as comprehensive as e.g. Rust's borrow checker, but the direction of travel here seems pretty clear.
Jan 15 2020
prev sibling next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/2/20 4:47 AM, Mike Parker wrote:
 This is the feedback thread for the first round of Community Review for 
 DIP 1028, "Make  safe the Default":
 
 https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688
54b/DIPs/DIP1028.md 
 
 
 All review-related feedback on and discussion of the DIP should occur in 
 this thread. The review period will end at 11:59 PM ET on January 16, or 
 when I make a post declaring it complete.
 
 At the end of Round 1, if further review is deemed necessary, the DIP 
 will be scheduled for another round of Community Review. Otherwise, it 
 will be queued for the Final Review and Formal Assessment.
 
 Anyone intending to post feedback in this thread is expected to be 
 familiar with the reviewer guidelines:
 
 https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md
 
 *Please stay on topic!*
 
 Thanks in advance to all who participate.
How does the DIP affect interfaces and class virtual functions? Especially interfaces without marking will be a potential problem as there will be no errors on a system interface stub which now is tagged with safe but has no implementation to complain about. But an implementing class would fail to compile potentially (and might be in a separate project). This is a fundamental API difference that's not easy to account for. The DIP should address that process. I noticed that even templated class member functions are currently system unless tagged safe (for good reason). So there's going to be a lot of code out there like this. -Steve
Jan 13 2020
next sibling parent reply Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
On Monday, 13 January 2020 at 20:37:33 UTC, Steven Schveighoffer 
wrote:
 How does the DIP affect interfaces and class virtual functions? 
 Especially interfaces without marking will be a potential 
 problem as there will be no errors on a  system interface stub 
 which now is tagged with  safe but has no implementation to 
 complain about. But an implementing class would fail to compile 
 potentially (and might be in a separate project). This is a 
 fundamental API difference that's not easy to account for. The 
 DIP should address that process.
I agree and I think my request for a depreciation plan would request that unspecified interface methods be deprecated. https://forum.dlang.org/post/bojmstnsnfydfaggslzj forum.dlang.org
Jan 13 2020
parent reply MoonlightSentinel <moonlightsentinel disroot.org> writes:
On Tuesday, 14 January 2020 at 06:12:35 UTC, Jesse Phillips wrote:
 I agree and I think my request for a depreciation plan would 
 request that unspecified interface methods be deprecated.

 https://forum.dlang.org/post/bojmstnsnfydfaggslzj forum.dlang.org
I don't think deprecating would be a good idea since it make more attributes mandatory which isn't helpful for quick scripts and disrupts existing builds using -de. Another approach could be to highlight problematic functions (which are really system but not annotated as such). Hence I implemented -transition=safe to list these functions as a less intrusive message, see https://github.com/dlang/dmd/pull/10715
Jan 14 2020
parent Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
On Tuesday, 14 January 2020 at 10:21:21 UTC, MoonlightSentinel 
wrote:
 On Tuesday, 14 January 2020 at 06:12:35 UTC, Jesse Phillips 
 wrote:
 I agree and I think my request for a depreciation plan would 
 request that unspecified interface methods be deprecated.

 https://forum.dlang.org/post/bojmstnsnfydfaggslzj forum.dlang.org
I don't think deprecating would be a good idea since it make more attributes mandatory which isn't helpful for quick scripts and disrupts existing builds using -de. Another approach could be to highlight problematic functions (which are really system but not annotated as such). Hence I implemented -transition=safe to list these functions as a less intrusive message, see https://github.com/dlang/dmd/pull/10715
For interfaces I could understand, the depreciation I suggested for regular methods would mandate only needed attributes but it also requires a different compiler logic. Your solution may effectively be the same. I think a depreciation is important to guide the transition and shouldn't be done right away but as one of the release steps. Those using de are looking to nudge themselves on the release plan.
Jan 14 2020
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/13/2020 12:37 PM, Steven Schveighoffer wrote:
 How does the DIP affect interfaces and class virtual functions? Especially 
 interfaces without marking will be a potential problem as there will be no 
 errors on a  system interface stub which now is tagged with  safe but has no 
 implementation to complain about. But an implementing class would fail to 
 compile potentially (and might be in a separate project). This is a
fundamental 
 API difference that's not easy to account for. The DIP should address that
process.
Unmarked introducing functions (such as the ones in Object) will have to be marked as system. Later on we can mark them safe as a separate transition issue.
 I noticed that even templated class member functions are currently  system 
 unless tagged  safe (for good reason). So there's going to be a lot of code
out 
 there like this.
Templated functions get their safety inferred if not explicitly marked.
Jan 15 2020
next sibling parent reply jmh530 <john.michael.hall gmail.com> writes:
On Wednesday, 15 January 2020 at 18:26:31 UTC, Walter Bright 
wrote:
 [snip]
 I noticed that even templated class member functions are 
 currently  system unless tagged  safe (for good reason). So 
 there's going to be a lot of code out there like this.
Templated functions get their safety inferred if not explicitly marked.
Even for templated member functions? Running the code below causes an error. The way safe flows through to nested scopes seems to override it. import std; safe pure: struct Foo { void foo(T)() { int x; int* y = &x; } void bar() { } } void main() { debug { writeln(isSafe!(Foo.foo!int)); writeln(hasFunctionAttributes!(Foo.foo!int, "pure")); writeln(isSafe!(Foo.bar)); writeln(hasFunctionAttributes!(Foo.bar, "pure")); } }
Jan 15 2020
parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/15/2020 11:13 AM, jmh530 wrote:
 Templated functions get their safety inferred if not explicitly marked.
Even for templated member functions?
Hmm, I think you're right.
Jan 15 2020
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/15/20 1:26 PM, Walter Bright wrote:
 On 1/13/2020 12:37 PM, Steven Schveighoffer wrote:
 How does the DIP affect interfaces and class virtual functions? 
 Especially interfaces without marking will be a potential problem as 
 there will be no errors on a  system interface stub which now is 
 tagged with  safe but has no implementation to complain about. But an 
 implementing class would fail to compile potentially (and might be in 
 a separate project). This is a fundamental API difference that's not 
 easy to account for. The DIP should address that process.
Unmarked introducing functions (such as the ones in Object) will have to be marked as system. Later on we can mark them safe as a separate transition issue.
This needs at the very least a section of the DIP. I would recommend some kind of deprecation period where people are told to mark their abstract and interface functions system or safe (and might even be worth making it an error for a short time to nudge them even further). Otherwise, you will have projects that compile just fine, but silently change their API when the DIP becomes the default.
 I noticed that even templated class member functions are currently 
  system unless tagged  safe (for good reason). So there's going to be 
 a lot of code out there like this.
Templated functions get their safety inferred if not explicitly marked.
Sorry, I could have worded this better. Member functions of templated classes (i.e. virtual functions) are not inferred like they are for structs: class C(T) { T foo() { return T.init; } } struct S(T) { T foo() { return T.init; } } void main() safe { S!int s; assert(s.foo == 0); // OK, S.foo inferred safe auto c = new C!int; assert(c.foo == 0); // error, cannot call system function C.foo } -Steve
Jan 16 2020
prev sibling parent Mike Parker <aldacron gmail.com> writes:
On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:

 All review-related feedback on and discussion of the DIP should 
 occur in this thread. The review period will end at 11:59 PM ET 
 on January 16, or when I make a post declaring it complete.
This round of review is now closed. Thanks to everyone who participated.
Jan 17 2020