digitalmars.D - DIP 1028---Make safe the Default---Community Review Round 1
- Mike Parker (15/15) Jan 02 2020 This is the feedback thread for the first round of Community
- Mike Parker (2/4) Jan 02 2020 And to make it searchable: #DIP1028
- WebFreak001 (27/42) Jan 02 2020 This is a simple but really powerful change. I think most issues
- Basile B. (18/33) Jan 02 2020 While I don't disapprove I suggest a very long deprecation phase,
- Basile B. (4/46) Jan 02 2020 actually dont take in account the final note. It would obviously
- bachmeier (20/35) Jan 02 2020 "This will likely break most code that has not already been
- bachmeier (8/51) Jan 02 2020 I want to make this comment in a new reply since it's separate
- ag0aep6g (9/16) Jan 02 2020 Yes, you shouldn't blindly slap @trusted on your non-@safe functions.
- bachmeier (4/10) Jan 02 2020 What compiler do you use? I always get error messages when I try
- ag0aep6g (16/22) Jan 02 2020 Why would you suddenly be calling @system functions from @safe code?
- Dominikus Dittes Scherkl (10/19) Jan 02 2020 Yes! I fully support this DIP.
- ag0aep6g (26/30) Jan 02 2020 One step at a time. As it is, the DIP may be disruptive but it's simple....
- Dominikus Dittes Scherkl (17/36) Jan 02 2020 But it is also simple (you just don't need the two pairs of
- jmh530 (11/15) Jan 02 2020 Nothing prevents you from going function by function to verify if
- jmh530 (5/7) Jan 02 2020 I believe this DIP should be not be accepted until 1) it is
- bachmeier (4/12) Jan 02 2020 If a function is not annotated, why should it default to @system?
- jmh530 (6/15) Jan 02 2020 I'm thinking about the transition. (non-template) Functions are
- Dominikus Dittes Scherkl (6/14) Jan 02 2020 Yes, yes!
- jmh530 (27/33) Jan 02 2020 You should probably also check that the unittests still pass
- Dominikus Dittes Scherkl (5/39) Jan 02 2020 No, this should not be necessary. baz() compiles with @safe as
- jmh530 (9/14) Jan 02 2020 Under current behavior, baz is @system by default, but that will
- Dominikus Dittes Scherkl (8/24) Jan 02 2020 No, I argue the program was originally buggy: is got the false
- Dominikus Dittes Scherkl (4/12) Jan 02 2020 Woah, writing fast is not my thing :-/
- mipri (20/22) Jan 02 2020 So, +1 migration task:
- jmh530 (7/10) Jan 02 2020 The et al should probably include at least
- Walter Bright (6/8) Jan 02 2020 Issues that don't get put in bugzilla don't get fixed. Please tag all is...
- jmh530 (26/34) Jan 03 2020 You made the argument further down that we shouldn't need to act
- Steven Schveighoffer (34/44) Jan 03 2020 So I spent about 3 days to try and bring a large project into the realm
- Les De Ridder (2/5) Jan 02 2020 The rationale seems a bit lacking.
- ag0aep6g (13/17) Jan 02 2020 There's this paragraph in the DIP: "This will likely break most code
- 12345swordy (8/23) Jan 02 2020 This dip, doesn't describe how to make the destroy function for
- Guillaume Piolat (38/44) Jan 02 2020 This is a serious concern (destruction and attributes), for
- JN (14/16) Jan 02 2020 Personally, I don't care for memory safety either, I don't write
- Adam D. Ruppe (13/16) Jan 02 2020 or just open the debugger and it tells you exactly where it
- H. S. Teoh (28/33) Jan 02 2020 [...]
- Mathias Lang (4/6) Jan 02 2020 You can actually use DIP1000 to allow this. That's why it would
- Walter Bright (18/23) Jan 03 2020 In my experience, the fix for such things is to use `ref T` instead of `...
- Walter Bright (2/3) Jan 03 2020 Oh, if only that were true. (I have decades of experience with this.)
- Adam D. Ruppe (21/23) Jan 03 2020 I've had a few times when things got outright corrupted in D and
- Atila Neves (12/26) Jan 03 2020 This is also my prediction.
- Walter Bright (7/13) Jan 03 2020 Buffer overflows (memory unsafety) are consistently at the top of the li...
- Guillaume Piolat (7/16) Jan 03 2020 I think what will be useful is accepting the change as -preview,
- Atila Neves (3/13) Jan 03 2020 This has been how every other DIP has been introduced, I don't
- Walter Bright (4/10) Jan 03 2020 Yes. Although it will break a lot of code, the fix (annotate with @syste...
- Adam D. Ruppe (11/13) Jan 03 2020 You should try this new programming language I like a lot. It has
- Walter Bright (4/5) Jan 02 2020 Issues that don't get put in bugzilla don't get fixed. Please tag all is...
- 12345swordy (3/9) Jan 02 2020 Done,
- Walter Bright (2/4) Jan 03 2020 Thank you.
- Walter Bright (3/5) Jan 02 2020 Issues with @safe that are not about making @safe the default (i.e. not ...
- 12345swordy (8/15) Jan 02 2020 What about bugs for @safe that require an DIP to fix then? Your
- Walter Bright (6/13) Jan 03 2020 Because this DIP is about making @safe the default, not changing the beh...
- bachmeier (21/26) Jan 03 2020 That a lot of working code will no longer compile without wasting
- Walter Bright (12/24) Jan 03 2020 No refactoring, changing data structures, anything like that, will be re...
- Arine (18/20) Jan 02 2020 If you could annotate the module with @system to use the old
- H. S. Teoh (11/22) Jan 02 2020 You can already do this today:
- Steven Schveighoffer (8/30) Jan 03 2020 This is erroneous. It marks all templates @system, which would otherwise...
- Eugene Wissner (11/14) Jan 03 2020 I think it applies only to other attributes.
- Steven Schveighoffer (5/25) Jan 03 2020 It seems you are right! But I could have sworn I had to mark member
- Walter Bright (6/29) Jan 02 2020 We already have that in starting a module with:
- Timon Gehr (3/16) Jan 02 2020 This will not result in the old behavior. It will disable inference of
- Walter Bright (2/19) Jan 03 2020 Ah, you're right for template code.
- Arine (6/9) Jan 02 2020 If issues with @safe aren't going to be considered with this DIP,
- Walter Bright (8/18) Jan 03 2020 Issues not in bugzilla do not get fixed. Please put all issues with @saf...
- Arine (14/31) Jan 03 2020 Then this would be better served as an opt in feature. This is
- Walter Bright (12/26) Jan 03 2020 It will be opt-in for a time, that's why it will be enabled with
- Johan (21/33) Jan 03 2020 I expect the change of default to be a _lot_ of work to deal with
- Walter Bright (8/22) Jan 03 2020 Templates without an explicit @safe/@trusted/@system will still get thei...
- Arine (33/62) Jan 04 2020 No one is going to really use that, they'll just wait til it's
- Arine (10/16) Jan 04 2020 An expression comes to mind, "death by a thousand cuts". If you
- IGotD- (13/31) Jan 04 2020 We need to have a separate discussion about the strategy for
- IGotD- (8/23) Jan 02 2020 Since this breaks virtually all code out there I suggest that
- Walter Bright (3/7) Jan 02 2020 Implementation:
- Jesse Phillips (4/7) Jan 02 2020 I think the DIP should specify the depreciation plan. Currently
- Jesse Phillips (14/23) Jan 03 2020 I think this could even be as simple as, "a new DIP will be
- Jesse Phillips (8/17) Jan 03 2020 Another thought to depreciation, the compiler could deprecated
- Jesse Phillips (13/31) Jan 08 2020 With the above rule in place and taking precedence, the next
- Jesse Phillips (8/11) Jan 02 2020 I would part of the rational would be: A large portion of
- Walter Bright (3/10) Jan 03 2020 There's another DIP coming that will make nothrow the default. Please, a...
- Mathias Lang (36/38) Jan 02 2020 On paper, this sounds like a great idea. Make '@safe' the default
- Walter Bright (24/54) Jan 03 2020 Modules can be labeled as @system by beginning them with:
- Steven Schveighoffer (13/22) Jan 03 2020 This does not work for member functions (also a valid criticism of the
- Walter Bright (3/4) Jan 03 2020 Sure, but if you want to do as little work as possible, blanket marking ...
- Mathias Lang (35/83) Jan 07 2020 As mentioned countless times already, this has a widely different
- Walter Bright (10/20) Jan 07 2020 Defaulting to @safe will ironically mitigate these types of issues.
- Jacob Carlborg (9/13) Jan 03 2020 With a DIP causing this large breakage I expect the DIP to be
- Walter Bright (2/10) Jan 03 2020 Such a tool would indeed be welcome. Please write it! (Perhaps modify df...
- Dennis (51/65) Jan 03 2020 The rationale is short and makes claims without any motivation,
- Manu (9/24) Jan 03 2020 FWIW, I'm not emotional about this, but it seems like a really good
- David Gileadi (2/9) Jan 03 2020 +1
- Dennis Cote (14/16) Jan 03 2020 I was going to give this a +1, but upon further reflection, I
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (14/20) Jan 03 2020 "unsafe" is the defacto terminology for code that isn't type
- Walter Bright (3/10) Jan 03 2020 Andrei and I talked about this for a while before coming up with 'system...
- Manu (11/21) Jan 06 2020 Okay.
- Max Samukha (4/7) Jan 06 2020 The feedback is incomplete. I have disliked "unsafe" since C# and
- Paulo Pinto (11/18) Jan 06 2020 The very first systems programming language that introduced the
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (11/14) Jan 06 2020 Thanks for sharing, some fun stuff (Wikipedia):
- Paulo Pinto (5/19) Jan 07 2020 It is also one of the oldest OS still being developed, nowadays
- Max Samukha (5/15) Jan 07 2020 Interesting. However, I didn't say that C# was the first to
- Paulo Pinto (7/25) Jan 07 2020 If we count the amount of safe system programming languages that
- Manu (6/13) Jan 07 2020 And 'system' is more logical and self-explanatory? Perhaps you can
- Max Samukha (8/13) Jan 07 2020 Nice piece of rhetoric. I didn't even say anything about
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (19/21) Jan 07 2020 It is standard terminology for program semantics going unchecked
- JN (7/11) Jan 07 2020 I actually like how "unsafe" sounds dangerous. It sounds like
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (12/18) Jan 07 2020 Exactly, like walking on a line without a safety rope, biking
- Max Samukha (5/10) Jan 07 2020 Yeah, I know about that definition of "unsafe", thank you for a
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (4/6) Jan 07 2020 "unchecked" seems reasonable, but "system" could be interpreted
- NaN (3/15) Jan 07 2020 How about "shrug" or "meh"?
- Arine (8/20) Jan 07 2020 extern(System) @safe void foo()
- Guillaume Piolat (7/14) Jan 08 2020 I like "@system" as a name.
- Walter Bright (15/23) Jan 07 2020 I'm frankly surprised at this. Yours is literally the first complaint ab...
- Les De Ridder (2/9) Jan 07 2020 I was confused by the naming too at first.
- Arine (32/64) Jan 07 2020 @trusted doesn't really make sense. It is pretty much @system
- Manu (3/44) Jan 08 2020 Actually, this is a really good point! I've had this thought many times.
- Mathias Lang (3/7) Jan 08 2020 Removing `@safe` as a keyword removes the ability to force
- Timon Gehr (12/24) Jan 08 2020 This line of reasoning makes no sense.
- Manu (9/33) Jan 08 2020 unsafe blocks is distinctly preferable to me. Functions are usually >1
- Walter Bright (3/10) Jan 08 2020 This is routinely done in Phobos by making a tiny one line anonymous @tr...
- Manu (7/17) Jan 08 2020 Unacceptable and embarrassing.
- Walter Bright (5/13) Jan 15 2020 It's a one-expression lambda. Why wouldn't it inline? I use one liner fu...
- Johannes Pfau (39/47) Jan 09 2020 I agree that the lambda thing is an ugly hack and proper trusted blocks
- Steven Schveighoffer (19/24) Jan 09 2020 Yes, this is why a function with ANY trusted blocks must be examined
- Arine (13/16) Jan 09 2020 I don't agree. This is discussing a method to implement safe be
- Timon Gehr (7/18) Jan 09 2020 If your @trusted code relies on @safe code to maintain safety-critical
- IGotD- (10/18) Jan 09 2020 @trusted is a completely unnecessary declaration and should be
- Timon Gehr (2/21) Jan 09 2020 Sorry, but this is plain nonsense. Please read the documentation.
- Steven Schveighoffer (8/28) Jan 09 2020 I'm not saying it's safe. I'm saying I want the mechanical checking
- H. S. Teoh (32/40) Jan 09 2020 [...]
- Timon Gehr (4/25) Jan 09 2020 I like this proposal (but there should be @system _expressions_ too). It...
- Steven Schveighoffer (3/17) Jan 09 2020 -Steve
- ag0aep6g (16/19) Jan 09 2020 Well, you can do that:
- Steven Schveighoffer (42/65) Jan 09 2020 This turns on its head the lines you have to pay most attention to thoug...
- ag0aep6g (40/76) Jan 09 2020 Effectively, the @trusted block taints the surrounding function
- Steven Schveighoffer (9/12) Jan 09 2020 I'm not sure what you mean by this. They are not safe, nor are they
- Arine (20/37) Jan 09 2020 That's a pretty contrived example.
- Timon Gehr (14/25) Jan 09 2020 @safe void someFunction(){
- ag0aep6g (17/43) Jan 09 2020 Unfortunately, that kind of @trusted misuse is pretty common.
- Paolo Invernizzi (7/55) Jan 09 2020 Exactly!
- Walter Bright (21/63) Jan 15 2020 It's intended to be that way. Bad language design is where the simple,
- Timon Gehr (7/44) Jan 15 2020 Or perhaps
- Walter Bright (3/4) Jan 15 2020 Yeah, I realized after I posted it that it should be `static` and pass `...
- H. S. Teoh (17/24) Jan 08 2020 There is this current idiom that essentially serves as a @trusted block:
- Walter Bright (2/5) Jan 08 2020 Bingo!
- Arine (9/32) Jan 08 2020 This isn't something you'd want people to not write. It's how you
- Manu (9/30) Jan 08 2020 Lambdas are usually suggested, but it's a completely unacceptable hack.
- H. S. Teoh (10/25) Jan 08 2020 [...]
- Basile B. (6/32) Jan 08 2020 I have a feature branch with a POC [1] of @trusted block
- Manu (14/36) Jan 08 2020 That has never been behaviour I've observed. And GDC/LDC don't have
- Arine (6/32) Jan 08 2020 That'd be a code smell. If you have to put the entire body of a
- Timon Gehr (14/52) Jan 09 2020 Nonsense. If a function provides a safe interface, @safe code should be
- Dominikus Dittes Scherkl (5/7) Jan 08 2020 Which it defacto is. we should get rid of @trusted (at function
- Manu (28/51) Jan 08 2020 It's the kind of thing that people wouldn't bother complaining about,
- Walter Bright (8/9) Jan 08 2020 I understand. But too much of this shuffling names around is just bounci...
- Arine (3/10) Jan 08 2020 Isn't that exactly what's happening right now with changing the
- Steven Schveighoffer (11/33) Jan 03 2020 Some sticky points:
- Walter Bright (3/13) Jan 03 2020 Yeah, that's a good idea.
- Meta (4/4) Jan 03 2020 I'm glad we're finally opening this can of worms. IMO, it's worth
- Steven Schveighoffer (18/40) Jan 03 2020 Add to rationale:
- monkyyy (20/20) Jan 03 2020 I strongly oppose such a move.
- Walter Bright (4/5) Jan 03 2020 Just add:
- matheus (7/13) Jan 04 2020 I see this pattern is this topic: "just add @system and
- Walter Bright (2/4) Jan 05 2020 D has lots of ways to avoid compiler checks. It's up to you to use them ...
- Dominikus Dittes Scherkl (15/22) Jan 04 2020 What a crappy idea.
- Walter Bright (6/12) Jan 03 2020 Unfortunately, not much code tends to be pure without expending much eff...
- Guillaume Piolat (18/33) Jan 03 2020 I'm still against:
- mipri (26/34) Jan 03 2020 This is technical problem with solutions like this one:
- Guillaume Piolat (12/23) Jan 03 2020 Which is another way to say you will loose productivity all the
- mipri (9/21) Jan 03 2020 But isn't this kind of code even more likely than most code to
- Walter Bright (2/3) Jan 03 2020 I was going to write a reply, then read yours. Mine would be redundant.
- Steven Schveighoffer (52/90) Jan 03 2020 Can we auto-check this? It should be as easy as checking out each
- Guillaume Piolat (4/9) Jan 03 2020 Can anyone produce ONE example of a memory corruption code they
- Alex (4/15) Jan 03 2020 Not sure, if this fits here. But if I add ´´´@safe:´´´ at the
- WebFreak001 (13/18) Jan 04 2020 you can't just slap `@safe:` on because all the libraries and
- Atila Neves (2/6) Jan 04 2020 Thank you!
- Alex (2/21) Jan 04 2020 Thank you very much!
- Steven Schveighoffer (4/25) Jan 04 2020 Awesome! I'll look into the bitmanip problems.
- Gregor =?UTF-8?B?TcO8Y2ts?= (5/8) Jan 04 2020 I unfortunately have to question some of the results in that
- Mike Parker (4/14) Jan 04 2020 Please everyone, take this discussion to a new thread and keep
- Walter Bright (2/3) Jan 04 2020 Please add all issues to Bugzilla.
- Steven Schveighoffer (8/12) Jan 04 2020 This isn't an issue, because the DIP is not part of the language yet.
- Walter Bright (2/8) Jan 04 2020 Good!
- Walter Bright (2/6) Jan 04 2020 This is good work. Thanks!
- Mathias Lang (11/30) Jan 07 2020 When providing results, it is best to provide your methodology
- WebFreak001 (8/20) Jan 08 2020 I didn't compile druntime or phobos with the -preview=safedefault
- H. S. Teoh (47/58) Jan 03 2020 Ran into this a long time ago:
- Guillaume Piolat (41/86) Jan 03 2020 (I catched your bug while reading (&resA is dupe), but would make
- Walter Bright (5/11) Jan 03 2020 I've gotten a fair amount of feedback over the years "why isn't @safe th...
- Per =?UTF-8?B?Tm9yZGzDtnc=?= (3/6) Jan 04 2020 Yes, please! All the way.
- Atila Neves (36/39) Jan 04 2020 I get the impression that most of the negative feedback here
- rikki cattermole (15/22) Jan 04 2020 There is a solution to all three of the categories that you have
- Walter Bright (2/3) Jan 04 2020 D's future will be in incremental improvements, not creating a new langu...
- rikki cattermole (4/9) Jan 04 2020 I did not suggest a new language.
- Jesse Phillips (8/11) Jan 04 2020 Actually it has been. But creating a plan to manage these large
- Walter Bright (3/5) Jan 04 2020 When passing the address of a local to a function, nearly all of that ca...
- Walter Bright (5/6) Jan 04 2020 And most of the rest can be trivially made @safe.
- Gregor =?UTF-8?B?TcO8Y2ts?= (49/64) Jan 04 2020 My concern is about forcing such a transition onto the D
- Walter Bright (4/5) Jan 04 2020 The transition plan of starting with -preview=feature and eventually cha...
- Sebastiaan Koppe (16/18) Jan 04 2020 I expected this to take at least another year or two. I am very
- jxel (7/20) Jan 04 2020 To use an argument that is being used against why this shouldn't
- Sebastiaan Koppe (6/11) Jan 04 2020 That makes no sense to me. Instead of sane defaults I am expected
- Adam D. Ruppe (4/5) Jan 04 2020 This should be fixed regardless of defaults. We'll want it either
- Walter Bright (4/8) Jan 04 2020 With D, I have repeatedly learned the lesson of the value of having the ...
- jxel (17/30) Jan 04 2020 I looked at a few of the dub packages that work with the safe
- H. S. Teoh (25/27) Jan 04 2020 [...]
- jxel (12/38) Jan 05 2020 Well you can call @safe code from @system, so you can't really
- H. S. Teoh (26/37) Jan 05 2020 The guarantees of @safe is conditioned upon being called from other
- jxel (14/52) Jan 05 2020 What if you have a @safe library that gets called from another
- Walter Bright (12/15) Jan 05 2020 This misses the point. D provides plenty of escapes from writing safe co...
- jxel (12/30) Jan 05 2020 There seems to be a disconnect of Practicality Vs. Ideology here.
- Timon Gehr (5/6) Jan 05 2020 I wish.
- Walter Bright (3/11) Jan 05 2020 I'm glad there's a bugzilla for it marked with the `safe` keyword so I d...
- NaN (3/8) Jan 04 2020 Has anybody looked at performance considerations since @safe
- James Blachly (5/9) Jan 06 2020 Great question. Presumably we can compile with nobounds for performance
- Paulo Pinto (4/13) Jan 06 2020 Rust, just like most safe systems programming languages provides
- Jon Degenhardt (12/15) Jan 04 2020 From the discussions it appears the amount and nature of breakage
- Walter Bright (2/11) Jan 04 2020 DIP1000 and DIP1028 will remain independent effects.
- Steven Schveighoffer (5/27) Jan 08 2020 A consideration I didn't think of before. What happens here?
- Steven Schveighoffer (5/35) Jan 08 2020 extern(C++) prototypes also. Basically, any function where `@safe` does
- berni44 (12/14) Jan 12 2020 Not sure, if this has allready been mentioned, I didn't read all
- Ogi (8/10) Jan 12 2020 writeln is @safe as long as you use it with safe arguments.
- Joseph Rushton Wakeling (226/229) Jan 13 2020 First, @Walter, thanks for writing this, and @Mike, thanks for
- Joseph Rushton Wakeling (8/11) Jan 13 2020 Whoops, I forgot to complete my train of thought there :-) The
- Arine (24/40) Jan 13 2020 Rust doesn't just provide safety. It also provides a lot more
- Steven Schveighoffer (5/7) Jan 13 2020 Can someone explain this point of view to me? It seems extreme.
- Joseph Rushton Wakeling (11/17) Jan 13 2020 Yea. This is something where both sides of the argument are
- bachmeier (14/16) Jan 13 2020 That was probably me. I don't recall ever saying all
- Steven Schveighoffer (20/37) Jan 13 2020 I feel this is a bit blown out of proportion.
- bachmeier (11/34) Jan 13 2020 If you only work with idiomatic D code, this DIP won't have much
- Adam D. Ruppe (4/6) Jan 13 2020 Or better yet, let's make `@safe:` work well so we can do this on
- rikki cattermole (4/13) Jan 13 2020 I'm not sure I like the idea that attributes are going down scopes like
- Adam D. Ruppe (13/16) Jan 13 2020 In as much as like a "@safe class" (or struct/interface/etc)
- jmh530 (3/7) Jan 14 2020 I like this approach. Looks like DIP 1029 is moving in that
- Timon Gehr (4/13) Jan 14 2020 It does not mention nested functions and auto return functions. They
- Joseph Rushton Wakeling (29/41) Jan 13 2020 Yes, indeed. That's kind of the point -- Rust has established a
- Arine (24/50) Jan 13 2020 That's the thing, D has a GC. If you are now trying to push
- Joseph Rushton Wakeling (48/70) Jan 14 2020 It's not about what _I'm_ doing. There are already DIPs and
- Timon Gehr (2/15) Jan 14 2020 Which features and DIPs are those?
- Joseph Rushton Wakeling (5/10) Jan 15 2020 DIP1000 for example. (Yes, I know that this didn't formally get
- Steven Schveighoffer (12/34) Jan 13 2020 How does the DIP affect interfaces and class virtual functions?
- Jesse Phillips (5/13) Jan 13 2020 I agree and I think my request for a depreciation plan would
- MoonlightSentinel (8/11) Jan 14 2020 I don't think deprecating would be a good idea since it make more
- Jesse Phillips (10/23) Jan 14 2020 For interfaces I could understand, the depreciation I suggested
- Walter Bright (4/13) Jan 15 2020 Unmarked introducing functions (such as the ones in Object) will have to...
- jmh530 (23/29) Jan 15 2020 Even for templated member functions? Running the code below
- Walter Bright (2/5) Jan 15 2020 Hmm, I think you're right.
- Steven Schveighoffer (25/42) Jan 16 2020 This needs at the very least a section of the DIP. I would recommend
- Mike Parker (3/6) Jan 17 2020 This round of review is now closed. Thanks to everyone who
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
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
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
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
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: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.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
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
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: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.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
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
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
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.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.And legacy code should be treated as system, not as trusted.Perfectly working legacy code should by default stop compiling?
Jan 02 2020
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
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
On Thursday, 2 January 2020 at 14:43:50 UTC, ag0aep6g wrote:On 02.01.20 14:47, Dominikus Dittes Scherkl wrote: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.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 incorrectlyThat 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
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
On Thursday, 2 January 2020 at 13:49:43 UTC, jmh530 wrote:On Thursday, 2 January 2020 at 12:34:05 UTC, bachmeier wrote: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.[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
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
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
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
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: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.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
On Thursday, 2 January 2020 at 11:31:59 UTC, bachmeier wrote:[snip]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.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
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: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!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).
Jan 02 2020
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
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: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.[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
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
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: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)-[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
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
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
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
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
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
On 1/2/20 6:19 AM, jmh530 wrote:On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote: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/175This 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 03 2020
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.mdThe rationale seems a bit lacking.
Jan 02 2020
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.mdThere'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
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
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
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
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
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
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
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
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
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
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
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 dayArguably 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
On Friday, 3 January 2020 at 11:29:47 UTC, Walter Bright wrote:On 1/2/2020 9:06 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.- 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.Absolutely.- I'll just slap trusted everywhere and call is a dayArguably better to slap system everywhere.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
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:This has been how every other DIP has been introduced, I don't expect this one to be any different.On 1/2/2020 9:06 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.- 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.
Jan 03 2020
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!Yes. Although it will break a lot of code, the fix (annotate with system where the compiler indicates) is straightforward.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
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
On 1/2/2020 6:39 AM, 12345swordy wrote:This issue is major blocking pointIssues 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
On Friday, 3 January 2020 at 01:23:01 UTC, Walter Bright wrote:On 1/2/2020 6:39 AM, 12345swordy wrote:Done, https://issues.dlang.org/show_bug.cgi?id=15246This issue is major blocking pointIssues 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
On 1/2/2020 6:00 PM, 12345swordy wrote:Done, https://issues.dlang.org/show_bug.cgi?id=15246Thank you.
Jan 03 2020
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
On Friday, 3 January 2020 at 01:24:17 UTC, Walter Bright wrote:On 1/2/2020 6:39 AM, 12345swordy wrote: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?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
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
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
On 1/3/2020 12:02 PM, bachmeier wrote: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 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 compilerThis 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
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
On Thu, Jan 02, 2020 at 05:27:22PM +0000, Arine via Digitalmars-d wrote: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.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
Jan 02 2020
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: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. -SteveYou 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.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
Jan 03 2020
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
On 1/3/20 10:48 AM, Eugene Wissner wrote:On Friday, 3 January 2020 at 15:38:02 UTC, Steven Schveighoffer wrote: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. -SteveThis 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
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 similarWe 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
On 03.01.20 02:31, Walter Bright wrote:On 1/2/2020 9:27 AM, Arine wrote:This will not result in the old behavior. It will disable inference of safe in that module.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 similarWe already have that in starting a module with: system:
Jan 02 2020
On 1/2/2020 6:11 PM, Timon Gehr wrote:On 03.01.20 02:31, Walter Bright wrote:Ah, you're right for template code.On 1/2/2020 9:27 AM, Arine wrote:This will not result in the old behavior. It will disable inference of safe in that module.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 similarWe already have that in starting a module with: system:
Jan 03 2020
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
On 1/2/2020 9:20 PM, Arine wrote:On Friday, 3 January 2020 at 01:31:26 UTC, Walter Bright wrote:No. We don't have time to do all development serially.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.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
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: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.On Friday, 3 January 2020 at 01:31:26 UTC, Walter Bright wrote:No. We don't have time to do all development seriallyThis 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.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
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=safedefaultThis 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 issuesThis 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
On Friday, 3 January 2020 at 22:59:53 UTC, Walter Bright wrote:On 1/3/2020 5:57 AM, Arine wrote:Yes please.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=safedefaultI 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). -JohanEspecially 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.
Jan 03 2020
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
On Friday, 3 January 2020 at 22:59:53 UTC, Walter Bright wrote:On 1/3/2020 5:57 AM, Arine wrote: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.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=safedefaultIt'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.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.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.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 issuesThis 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 04 2020
On Friday, 3 January 2020 at 22:59:53 UTC, Walter Bright wrote: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.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.
Jan 04 2020
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: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.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.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.
Jan 04 2020
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
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.mdImplementation: https://github.com/dlang/dmd/pull/10709
Jan 02 2020
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.mdI 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
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: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.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.mdI 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 03 2020
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: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.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.mdI 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 03 2020
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: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.On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote: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.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.mdI 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 08 2020
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.mdI 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
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
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
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
On 1/3/20 6:06 AM, Walter Bright wrote:On 1/2/2020 10:31 PM, Mathias Lang wrote: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. -SteveOn 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:
Jan 03 2020
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
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.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".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.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.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 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.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.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.Because `scope` is ignored for mangling. ` safe` cannot be ignored, so the same solution cannot be used.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.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.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.There's a trove of issues in bugzilla to pick from. But put in simpler terms: Where is ` safe` reference counting ?actually finish what we started.All issues need to go into bugzilla. Issues not in bugzilla do not get fixed.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.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 07 2020
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
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.mdWith 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
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 compileSuch a tool would indeed be welcome. Please write it! (Perhaps modify dfix?)
Jan 03 2020
On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:https://github.com/dlang/DIPs/blob/1b705f8d4faa095d6d9e3a1b81d6cfa6d688554b/DIPs/DIP1028.mdThe rationale is short and makes claims without any motivation, such as:the costs of unsafe code have become ever more apparent and expensiveUsers expect safety to be opt-out, not opt-inIt 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
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
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
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
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
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
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: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.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 06 2020
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
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: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.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
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
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: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.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 07 2020
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
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: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.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.
Jan 07 2020
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: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.Well all feedback I've received is that it fails at the rule of least surprise.admitted publicly that "unsafe" was a misnomer.
Jan 07 2020
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
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
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
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
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
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
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:How about "shrug" or "meh"? IE... "it might work ok but I couldn't be arsed to check."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
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: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.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
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: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.Well all feedback I've received is that it fails at the rule of least surprise.admitted publicly that "unsafe" was a misnomer.
Jan 08 2020
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
On Wednesday, 8 January 2020 at 02:48:19 UTC, Walter Bright wrote:On 1/6/2020 3:59 PM, Manu wrote:I was confused by the naming too at first.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.
Jan 07 2020
On Wednesday, 8 January 2020 at 02:48:19 UTC, Walter Bright wrote:On 1/6/2020 3:59 PM, Manu 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 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()); }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.If you can't prove it is safe, logic dictates it should then be identified as unsafe.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
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:Actually, this is a really good point! I've had this thought many times.On 1/6/2020 3:59 PM, Manu 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 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()); }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.
Jan 08 2020
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
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
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: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.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
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
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: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'.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
On 1/8/2020 9:57 PM, Manu wrote:You have to use the -inline switch (for DMD), that's true.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'.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
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
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
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. -SteveI 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
On 09.01.20 20:00, Steven Schveighoffer wrote:On 1/9/20 1:47 PM, Johannes Pfau 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.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.
Jan 09 2020
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
On 09.01.20 20:34, IGotD- wrote:On Thursday, 9 January 2020 at 19:22:28 UTC, Timon Gehr wrote:Sorry, but this is plain nonsense. Please read the documentation.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
On 1/9/20 2:22 PM, Timon Gehr wrote:On 09.01.20 20:00, Steven Schveighoffer wrote: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. -SteveOn 1/9/20 1:47 PM, Johannes Pfau 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.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.
Jan 09 2020
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:[...][...] 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?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.
Jan 09 2020
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: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.On 1/9/20 2:22 PM, Timon Gehr 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: ... Tsafe 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.
Jan 09 2020
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
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
On 1/9/20 3:08 PM, ag0aep6g wrote:On Thursday, 9 January 2020 at 19:35:36 UTC, Steven Schveighoffer wrote: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.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.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
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.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.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);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
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
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
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
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
On Thursday, 9 January 2020 at 18:47:23 UTC, Johannes Pfau wrote:Am Thu, 09 Jan 2020 10:12:23 +1000 schrieb Manu: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 blocksunsafe 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?
Jan 09 2020
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
On 15.01.20 19:08, Walter Bright wrote:On 1/9/2020 10:47 AM, Johannes Pfau wrote:Or perhaps #include <vector> void foo(std::vector<int> const &array);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. ...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(); }It will not. The "nice" version is bad.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
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
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
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
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: [...]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.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.
Jan 08 2020
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: [...]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.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.
Jan 08 2020
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
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: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_xc2wjRgWzo3XVZXjVVgOn 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
Jan 08 2020
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: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.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?
Jan 08 2020
On Wednesday, 8 January 2020 at 18:59:38 UTC, Timon Gehr wrote:On 08.01.20 08:10, Arine wrote: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.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.Did you miss the example?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
On 09.01.20 07:19, Arine wrote:On Wednesday, 8 January 2020 at 18:59:38 UTC, Timon Gehr wrote: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.On 08.01.20 08:10, Arine wrote: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.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.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.Of course not. Your example is either terrible or covered by trusted statement blocks. Not sure which.Did you miss the example?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 09 2020
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
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: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.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 don't think it makes any less sense. It seems reasonable that safe code can't call unsafe code, unless we `trust` it.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.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.Whatever you reckon. I was just offering that there's an opportunity here.
Jan 08 2020
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
On Thursday, 9 January 2020 at 05:37:18 UTC, Walter Bright wrote:On 1/8/2020 3:42 AM, Manu wrote:Isn't that exactly what's happening right now with changing the default to be safe... ?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.
Jan 08 2020
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
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
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
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
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
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
On Saturday, 4 January 2020 at 06:43:16 UTC, Walter Bright wrote:On 1/3/2020 2:37 PM, monkyyy wrote: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.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 04 2020
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
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 trustedWhat 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 functionsI 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
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
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
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 yearsThis 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 overstatedDefaults 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
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
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: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.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.
Jan 03 2020
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
On 1/3/20 3:59 PM, Guillaume Piolat wrote:On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote: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.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- 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
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
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: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.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
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
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.htmlThank you!
Jan 04 2020
On Saturday, 4 January 2020 at 10:22:34 UTC, WebFreak001 wrote:On Friday, 3 January 2020 at 22:36:17 UTC, Alex wrote:Thank you very much![...] 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
On 1/4/20 5:22 AM, WebFreak001 wrote:On Friday, 3 January 2020 at 22:36:17 UTC, Alex wrote:Awesome! I'll look into the bitmanip problems. Can you do us a favor and sort by package name? -Steve[...] 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
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.htmlI 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
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:Please everyone, take this discussion to a new thread and keep this one focused on review of DIP 1028. Thanks!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.htmlI 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
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
On 1/4/20 4:17 PM, Walter Bright wrote:On 1/4/2020 2:22 AM, WebFreak001 wrote: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. -SteveCurrently a lot of issues are caused by phobos' std.bitmanip.bitfields.Please add all issues to Bugzilla.
Jan 04 2020
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
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.htmlThis is good work. Thanks!
Jan 04 2020
On Saturday, 4 January 2020 at 10:22:34 UTC, WebFreak001 wrote:On Friday, 3 January 2020 at 22:36:17 UTC, Alex 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.[...] 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 07 2020
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: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[...]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 08 2020
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: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.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
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:(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.On Friday, 3 January 2020 at 22:13:28 UTC, Steven Schveighoffer wrote: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'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
On 1/3/2020 2:13 PM, Steven Schveighoffer wrote: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.- 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.
Jan 03 2020
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.mdYes, please! All the way. Thanks, Walter
Jan 04 2020
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
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 safeThere 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
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
On 05/01/2020 10:25 AM, Walter Bright wrote:On 1/4/2020 3:23 AM, rikki cattermole wrote: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.We defer this going live till D3.D's future will be in incremental improvements, not creating a new language.
Jan 04 2020
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
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
On 1/4/2020 2:42 AM, Atila Neves wrote:most code is safe anywayAnd 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
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
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
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
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: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.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.
Jan 04 2020
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
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
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
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: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.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.Exactly the point, people are trying to push system: as some easy alternative solution. Its not.
Jan 04 2020
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
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: [...]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.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
Jan 05 2020
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
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: [...]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.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.Bzz, wrong. You can void initialize 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.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.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.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
Jan 05 2020
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
On Monday, 6 January 2020 at 02:17:42 UTC, Walter Bright wrote:On 1/5/2020 12:13 PM, jxel wrote: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.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
On 05.01.20 18:57, H. S. Teoh wrote:Writing `bool b = void;' is systemI 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
On 1/5/2020 3:48 PM, Timon Gehr wrote:On 05.01.20 18:57, H. S. Teoh wrote:I'm glad there's a bugzilla for it marked with the `safe` keyword so I don't have to harangue anyone :-)Writing `bool b = void;' is systemI 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
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
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
On Monday, 6 January 2020 at 13:18:01 UTC, James Blachly wrote:On 1/4/20 8:43 PM, NaN wrote:Rust, just like most safe systems programming languages provides an escape hatch (which requires unsafe), and also does bounds checking elision via dataflow analysis.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
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.mdFrom 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
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
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
On 1/8/20 9:14 PM, Steven Schveighoffer wrote:On 1/2/20 4:47 AM, Mike Parker wrote: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. -SteveThis 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.
Jan 08 2020
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
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
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.mdFirst, 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
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 haveWhoops, 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
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
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 thereCan 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
On Monday, 13 January 2020 at 17:33:12 UTC, Steven Schveighoffer wrote:On 1/13/20 12:13 PM, Arine wrote: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?This DIP is a big breaking change that is going to break basically all code out thereCan 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.
Jan 13 2020
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
On 1/13/20 1:38 PM, bachmeier wrote:On Monday, 13 January 2020 at 17:33:12 UTC, Steven Schveighoffer wrote: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)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.You will have lots of time to get your code ready for the DIP to be the default. -Steve
Jan 13 2020
On Monday, 13 January 2020 at 20:32:32 UTC, Steven Schveighoffer wrote:On 1/13/20 1:38 PM, bachmeier wrote: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.On Monday, 13 January 2020 at 17:33:12 UTC, Steven Schveighoffer wrote: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: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?
Jan 13 2020
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
On 14/01/2020 10:46 AM, Adam D. Ruppe wrote:On Monday, 13 January 2020 at 21:43:24 UTC, bachmeier 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. Otherwise I'm on board.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
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
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-defaultsI like this approach. Looks like DIP 1029 is moving in that direction.
Jan 14 2020
On 13.01.20 22:46, Adam D. Ruppe wrote:On Monday, 13 January 2020 at 21:43:24 UTC, bachmeier wrote: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).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 14 2020
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
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: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.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).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).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?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.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
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.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 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.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 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
On 14.01.20 15:56, Joseph Rushton Wakeling wrote:On Tuesday, 14 January 2020 at 05:23:10 UTC, Arine wrote:Which features and DIPs are those?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.
Jan 14 2020
On Wednesday, 15 January 2020 at 02:08:18 UTC, Timon Gehr wrote: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.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 15 2020
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
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
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.orgI 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
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: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.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.orgI 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
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
On Wednesday, 15 January 2020 at 18:26:31 UTC, Walter Bright wrote:[snip]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")); } }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
On 1/15/2020 11:13 AM, jmh530 wrote:Hmm, I think you're right.Templated functions get their safety inferred if not explicitly marked.Even for templated member functions?
Jan 15 2020
On 1/15/20 1:26 PM, Walter Bright wrote:On 1/13/2020 12:37 PM, Steven Schveighoffer wrote: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.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.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 } -SteveI 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 16 2020
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