Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On 10/15/2018 2:23 PM, Walter Bright wrote: I'm giving a presentation at: http://nwcpp.org/ See you there! Had a nice crowd there last night. Apparently lots of people were interested in this topic! Video: https://www.youtube.com/watch?v=lbp6vwdnE0k&feature=youtu.be Slides: http://nwcpp.org/talks/2018/code_smells.pdf
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Friday, 19 October 2018 at 03:53:12 UTC, Walter Bright wrote: On 10/15/2018 2:23 PM, Walter Bright wrote: I'm giving a presentation at: http://nwcpp.org/ See you there! Had a nice crowd there last night. Apparently lots of people were interested in this topic! Video: https://www.youtube.com/watch?v=lbp6vwdnE0k&feature=youtu.be Slides: http://nwcpp.org/talks/2018/code_smells.pdf https://www.youtube.com/watch?v=lbp6vwdnE0k#t=42m01s Or it's a pain in the ass to try to get more than one pull request merged in due to lack of overseers. It's hard enough trying to get one pull request merged in, but trying to split one pull request into 4 and then try to micro manage it so that they are merged in order as the changes depend on each other (eg spelling error for a function). That becomes a nightmare when you don't have merging permission for a repo, especially for something like DMD where it's hard enough to get even a simple fix through the door.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
luckoverthere wrote: > On Friday, 19 October 2018 at 03:53:12 UTC, Walter Bright wrote: >> On 10/15/2018 2:23 PM, Walter Bright wrote: >>> I'm giving a presentation at: >>> >>> http://nwcpp.org/ >>> >>> See you there! >> >> Had a nice crowd there last night. Apparently lots of people >> were interested in this topic! >> >> Video: >> https://www.youtube.com/watch?v=lbp6vwdnE0k&feature=youtu.be >> >> Slides: http://nwcpp.org/talks/2018/code_smells.pdf > > https://www.youtube.com/watch?v=lbp6vwdnE0k#t=42m01s > > Or it's a pain in the ass to try to get more than one pull > request merged in due to lack of overseers. It's hard enough > trying to get one pull request merged in, but trying to split one > pull request into 4 and then try to micro manage it so that they > are merged in order as the changes depend on each other (eg > spelling error for a function). That becomes a nightmare when you > don't have merging permission for a repo, especially for > something like DMD where it's hard enough to get even a simple > fix through the door. I unfortunately ran into this with my make-ddoc-support-markdown PR. The original PR was considered too big, and I was asked to split it into multiple PRs against a feature branch, which would then be merged into master. I was fine with this, and started the process. It was a bit slow, but seemed like it would work. Oh, what a fool I was! When my second PR to the feature branch was approved, it couldn’t be merged because it caused unrelated errors in the tests. My best theory is that the feature branch had drifted too far away from master, and since dmd, druntime and phobos have dependencies on each other it was somehow causing the test servers to fail. There’s a bit more to the story, but it boils down to the fact that since I don’t have permissions to update the feature branch, I’m basically dead in the water. So the work is all done and ready, but I have no path forward to get it in. And it’s a bit disheartening to be foiled by the machines :)
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On 10/21/2018 1:29 PM, David Gileadi wrote: There’s a bit more to the story, but it boils down to the fact that since I don’t have permissions to update the feature branch, I’m basically dead in the water. So the work is all done and ready, but I have no path forward to get it in. And it’s a bit disheartening to be foiled by the machines :) Just PR them against master.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Friday, 19 October 2018 at 03:53:12 UTC, Walter Bright wrote: On 10/15/2018 2:23 PM, Walter Bright wrote: I'm giving a presentation at: http://nwcpp.org/ See you there! Had a nice crowd there last night. Apparently lots of people were interested in this topic! Video: https://www.youtube.com/watch?v=lbp6vwdnE0k&feature=youtu.be Slides: http://nwcpp.org/talks/2018/code_smells.pdf https://www.reddit.com/r/programming/comments/9qbhw2/nwcpp_walter_bright_talks_about_the_code_smells/
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Friday, 19 October 2018 at 03:53:12 UTC, Walter Bright wrote: Had a nice crowd there last night. Apparently lots of people were interested in this topic! Video: https://www.youtube.com/watch?v=lbp6vwdnE0k&feature=youtu.be Interesting talk. Thanks for the link. I did find it confusing however, that you discuss leaky abstractions, and putting your public interface at the beginning of your code (and all the other crap below it)... but then, in D, once your write your abstraction, say a class, with it's public interface, all the code below it can do whatever it likes to that class, making it a leaky abstraction. That's sure sound like code smell to me. i.e. A class (perhaps one of the most important abstractions in programming) within a module, is *always* a leaky abstraction (within the module), because of the way the code further down can just ignore the interface. In fact, there is no way at all to ensure code below the class uses that interface. So I can't help but see contradictions everywhere, in D.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Wednesday, 31 October 2018 at 05:00:12 UTC, myCodeDontSmell wrote: I did find it confusing however, that you discuss leaky abstractions, and putting your public interface at the beginning of your code (and all the other crap below it)... but then, in D, once your write your abstraction, say a class, with it's public interface, all the code below it can do whatever it likes to that class, making it a leaky abstraction. That's sure sound like code smell to me. i.e. A class (perhaps one of the most important abstractions in programming) within a module, is *always* a leaky abstraction (within the module), because of the way the code further down can just ignore the interface. In fact, there is no way at all to ensure code below the class uses that interface. So I can't help but see contradictions everywhere, in D. That is by design, because in D the unit of abstraction is the module, not the class. Running into such problems is a sign that your module is too large, and should become a package.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Wednesday, 31 October 2018 at 05:00:12 UTC, myCodeDontSmell wrote: in D, once your write your abstraction, say a class, with it's public interface, all the code below it can do whatever it likes to that class, making it a leaky abstraction. I think there might be some confusion between "leaky abstraction" and "insufficient encapsulation". Here's the Wikipedia definition of leaky abstractions: "In software development, a leaky abstraction is an abstraction that *requires* knowledge of an underlying complexity* to be able to know how to use it. This is an issue, as the whole point of an abstraction is to be able to abstract away these details from the user. " Why would imply that: as long as the user of your class isn't *required* to know about the underlying implementation specifics, this isn't a "leaky abstraction". My understanding is that: "Leaky abstractions" are about the interface design, and how one component is meant to be used. Those are unrelated to the programming language (e.g translating the code to another language doesn't make the leaky abstraction disappear). For example, a shared directory can be a leaky abstraction, if the network is unstable (because then, the client code, which only sees file descriptors, now has to deal with disappearing files). "Encapsulation" is about implementation hiding and access control ("public/private"), and requires programming language support (e.g most dynamic languages don't have it).
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Wednesday, 31 October 2018 at 05:42:26 UTC, Nicholas Wilson wrote: Running into such problems is a sign that your module is too large, and should become a package. I seen modules with more then thousand lines of code in the Phobos library. What exactly consist a module of being "too large"? If having two classes in a module with around 200-300 lines of code "too large"?
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On 01/11/2018 2:16 AM, 12345swordy wrote: On Wednesday, 31 October 2018 at 05:42:26 UTC, Nicholas Wilson wrote: Running into such problems is a sign that your module is too large, and should become a package. I seen modules with more then thousand lines of code in the Phobos library. What exactly consist a module of being "too large"? If having two classes in a module with around 200-300 lines of code "too large"? We have been splitting Phobos modules up: std.algorithm and most recently std.datetime They were MASSIVE as in 30k+ LOC massive.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Wednesday, 31 October 2018 at 13:16:45 UTC, 12345swordy wrote: I seen modules with more then thousand lines of code in the Phobos library. $ wc simpledisplay.d nanovega.d dom.d cgi.d 14152 54984 443111 simpledisplay.d 15289 63707 573986 nanovega.d 7159 24473 187572 dom.d 4132 16727 128299 cgi.d lol
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On 01/11/2018 2:25 AM, 12345swordy wrote: On Wednesday, 31 October 2018 at 13:22:28 UTC, rikki cattermole wrote: On 01/11/2018 2:16 AM, 12345swordy wrote: On Wednesday, 31 October 2018 at 05:42:26 UTC, Nicholas Wilson wrote: Running into such problems is a sign that your module is too large, and should become a package. I seen modules with more then thousand lines of code in the Phobos library. What exactly consist a module of being "too large"? If having two classes in a module with around 200-300 lines of code "too large"? We have been splitting Phobos modules up: std.algorithm and most recently std.datetime They were MASSIVE as in 30k+ LOC massive. That's nice. Again what consist of a module of being "too large"? That seems to me that more of a art then a science. Because it is. My rules (which tend to be a little stricter than most peoples) are: Soft split 1k LOC, hard split 3k LOC without a very good reason not to. But at the end of the day, it just depends on the scope of the module. Is it getting to large? If so, split.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Wednesday, 31 October 2018 at 13:22:28 UTC, rikki cattermole wrote: On 01/11/2018 2:16 AM, 12345swordy wrote: On Wednesday, 31 October 2018 at 05:42:26 UTC, Nicholas Wilson wrote: Running into such problems is a sign that your module is too large, and should become a package. I seen modules with more then thousand lines of code in the Phobos library. What exactly consist a module of being "too large"? If having two classes in a module with around 200-300 lines of code "too large"? We have been splitting Phobos modules up: std.algorithm and most recently std.datetime They were MASSIVE as in 30k+ LOC massive. That's nice. Again what consist of a module of being "too large"? That seems to me that more of a art then a science.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Wednesday, 31 October 2018 at 13:28:54 UTC, rikki cattermole wrote: But at the end of the day, it just depends on the scope of the module. Is it getting to large? If so, split. Yup. LOC aren't a particulalry informative metric. Documentation, comments, unit tests, blanks, all contribute to it. Split by scope, by concept, by responsibility, by any implementation-relevant metric, not by LOC. As the joke goes, your word processor is doomed to fail once it also starts sending out emails...
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On 01/11/2018 2:33 AM, Stanislav Blinov wrote: On Wednesday, 31 October 2018 at 13:28:54 UTC, rikki cattermole wrote: But at the end of the day, it just depends on the scope of the module. Is it getting to large? If so, split. Yup. LOC aren't a particulalry informative metric. Documentation, comments, unit tests, blanks, all contribute to it. Split by scope, by concept, by responsibility, by any implementation-relevant metric, not by LOC. As the joke goes, your word processor is doomed to fail once it also starts sending out emails... Actually it is quite informative. As a code smell it does tell you pretty decently in my experience if your scope is too large or if you are in need of refactoring.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On 01/11/2018 2:35 AM, 12345swordy wrote: On Wednesday, 31 October 2018 at 13:28:54 UTC, rikki cattermole wrote: On 01/11/2018 2:25 AM, 12345swordy wrote: On Wednesday, 31 October 2018 at 13:22:28 UTC, rikki cattermole wrote: On 01/11/2018 2:16 AM, 12345swordy wrote: [...] We have been splitting Phobos modules up: std.algorithm and most recently std.datetime They were MASSIVE as in 30k+ LOC massive. That's nice. Again what consist of a module of being "too large"? That seems to me that more of a art then a science. Because it is. My rules (which tend to be a little stricter than most peoples) are: Soft split 1k LOC, hard split 3k LOC without a very good reason not to. But at the end of the day, it just depends on the scope of the module. Is it getting to large? If so, split. Ok, you agree that it is subjective. Why is having more then one class per file "too large"? It doesn't. It is a group of related symbols. If it doesn't have function bodies (e.g. extern(C++) or COM) I would call that module to have too small of a scope.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Wednesday, 31 October 2018 at 13:28:54 UTC, rikki cattermole wrote: On 01/11/2018 2:25 AM, 12345swordy wrote: On Wednesday, 31 October 2018 at 13:22:28 UTC, rikki cattermole wrote: On 01/11/2018 2:16 AM, 12345swordy wrote: [...] We have been splitting Phobos modules up: std.algorithm and most recently std.datetime They were MASSIVE as in 30k+ LOC massive. That's nice. Again what consist of a module of being "too large"? That seems to me that more of a art then a science. Because it is. My rules (which tend to be a little stricter than most peoples) are: Soft split 1k LOC, hard split 3k LOC without a very good reason not to. But at the end of the day, it just depends on the scope of the module. Is it getting to large? If so, split. Ok, you agree that it is subjective. Why is having more then one class per file "too large"?
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Wednesday, 31 October 2018 at 13:37:07 UTC, rikki cattermole wrote: On 01/11/2018 2:33 AM, Stanislav Blinov wrote: On Wednesday, 31 October 2018 at 13:28:54 UTC, rikki cattermole wrote: But at the end of the day, it just depends on the scope of the module. Is it getting to large? If so, split. Yup. LOC aren't a particulalry informative metric. Documentation, comments, unit tests, blanks, all contribute to it. Split by scope, by concept, by responsibility, by any implementation-relevant metric, not by LOC. As the joke goes, your word processor is doomed to fail once it also starts sending out emails... Actually it is quite informative. As a code smell it does tell you pretty decently in my experience if your scope is too large or if you are in need of refactoring. Well, yes, it can be a litmus test, I guess. I meant to say that it isn't per se a deciding factor.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On 01/11/2018 2:42 AM, Stanislav Blinov wrote: Well, yes, it can be a litmus test, I guess. I meant to say that it isn't per se a deciding factor. It is a deciding factor for me. Because it seems to be almost always correct. As I said, my rules are stricter than what most people have. My preferences may or may not be applicable for others tho.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On 10/31/2018 3:48 AM, Sebastien Alaiwan wrote: I think there might be some confusion between "leaky abstraction" and "insufficient encapsulation". Thanks for the excellent description of the difference.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Wednesday, 31 October 2018 at 13:39:25 UTC, rikki cattermole wrote: On 01/11/2018 2:35 AM, 12345swordy wrote: On Wednesday, 31 October 2018 at 13:28:54 UTC, rikki cattermole wrote: On 01/11/2018 2:25 AM, 12345swordy wrote: [...] Because it is. My rules (which tend to be a little stricter than most peoples) are: Soft split 1k LOC, hard split 3k LOC without a very good reason not to. But at the end of the day, it just depends on the scope of the module. Is it getting to large? If so, split. Ok, you agree that it is subjective. Why is having more then one class per file "too large"? It doesn't. It is a group of related symbols. If it doesn't have function bodies (e.g. extern(C++) or COM) I would call that module to have too small of a scope. Why do anyone have to create a file for every class if they wanted them to be encapsulated then? Why can't we put them in the same file if they are relativity small?
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Wednesday, 31 October 2018 at 13:24:10 UTC, Adam D. Ruppe wrote: On Wednesday, 31 October 2018 at 13:16:45 UTC, 12345swordy wrote: I seen modules with more then thousand lines of code in the Phobos library. $ wc simpledisplay.d nanovega.d dom.d cgi.d 14152 54984 443111 simpledisplay.d 15289 63707 573986 nanovega.d 7159 24473 187572 dom.d 4132 16727 128299 cgi.d This is an counter argument how?
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On 10/31/2018 6:25 AM, 12345swordy wrote: Again what consist of a module of being "too large"? That seems to me that more of a art then a science. If you're looking for a rigid rule, you won't find one. But a good indicator is if it contains more than one abstraction that has nothing particular in common with each other.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Wednesday, 31 October 2018 at 20:24:36 UTC, 12345swordy wrote: This is an counter argument how? It isn't a counter argument (at least not to you). Just saying that I wrote a 14,000 line module, and maintain a contributed 15,000 line one. It works for me! lol
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Wednesday, 31 October 2018 at 20:23:21 UTC, Walter Bright wrote: On 10/31/2018 6:25 AM, 12345swordy wrote: Again what consist of a module of being "too large"? That seems to me that more of a art then a science. If you're looking for a rigid rule, you won't find one. But a good indicator is if it contains more than one abstraction that has nothing particular in common with each other. Sure thing, however I wonder why "protected package" doesn't exist for classes, seems to me a missing opportunity there.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Wednesday, 31 October 2018 at 13:28:54 UTC, rikki cattermole wrote: On 01/11/2018 2:25 AM, 12345swordy wrote: On Wednesday, 31 October 2018 at 13:22:28 UTC, rikki cattermole wrote: On 01/11/2018 2:16 AM, 12345swordy wrote: On Wednesday, 31 October 2018 at 05:42:26 UTC, Nicholas Wilson wrote: Running into such problems is a sign that your module is too large, and should become a package. I seen modules with more then thousand lines of code in the Phobos library. What exactly consist a module of being "too large"? If having two classes in a module with around 200-300 lines of code "too large"? We have been splitting Phobos modules up: std.algorithm and most recently std.datetime They were MASSIVE as in 30k+ LOC massive. That's nice. Again what consist of a module of being "too large"? That seems to me that more of a art then a science. Because it is. My rules (which tend to be a little stricter than most peoples) are: Soft split 1k LOC, hard split 3k LOC without a very good reason not to. But at the end of the day, it just depends on the scope of the module. Is it getting to large? If so, split. I really do disagree. It's is not at all, about LOC. It is about clean architecture. D module's do not promote clean architecture. Why? Because private state is exposed to all code within a module. What will happen to clean architecture, when you make that available to programmers? Well.. we get phobos like architecture. Another thing to look for, is signs of code smell. I would include in this, unit tests calling private methods (which seems to be a popular thing for D programmers to do). Some will disagree that this is a code smell, but I have yet to see a good argument for why it is not. Forget LOC. Look for good architecture, decoupling, modularity, encapsulation, information hidingetc..etc... again, sadly, these concepts are not directly promoted when writing modules in D, since the module exposes everything to everything else in the module - and programmers will surely make use of any convenient hack that avoids them having to think about good architecture ;-)
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Thu, Nov 01, 2018 at 02:45:19AM +, unprotected-entity via Digitalmars-d-announce wrote: [...] > Another thing to look for, is signs of code smell. I would include in > this, unit tests calling private methods (which seems to be a popular > thing for D programmers to do). Some will disagree that this is a code > smell, but I have yet to see a good argument for why it is not. White-box testing. In principle, I agree with you that if your unittests are doing black-box testing, then they should definitely not be calling private methods. However, limiting yourself to black-box testing means your private functions can be arbitrarily complex and yet it's not thoroughly tested. Sometimes you really do want a unittest to ensure the private method is doing what you think it's doing, and this requires white-box testing. This is especially important to prevent regressions, even if it seems redundant at first. Only doing black-box testing means a later code change in the private method can subtly introduce a bug that's not caught by the unittest (because it cannot call a private method directly to verify this). > Forget LOC. Look for good architecture, decoupling, modularity, > encapsulation, information hidingetc..etc... again, sadly, these > concepts are not directly promoted when writing modules in D, since > the module exposes everything to everything else in the module - and > programmers will surely make use of any convenient hack that avoids > them having to think about good architecture ;-) [...] Actually, code within a module *should* be tightly coupled and cohesive -- that's the whole reason to put that code inside a single module in the first place. If two pieces of code inside a module are only weakly coupled or completely decoupled, that's a sign that they should not be in the same module at all. Or at the very least, they should belong in separate submodules that are isolated from each other. But besides all this, D's philosophy is about mechanism rather than policy. The goal is to give the programmer the tools to do what he needs to do, rather than a bunch of red tape to dictate what he cannot do. That's why we have @trusted, @system, and even asm. The programmer is responsible for making sane architectural decisions with the tools he is given, rather than being told what (not) to do within the confines of his cell. If you're looking for policy, maybe Java would suit you better. :-P T -- Nobody is perfect. I am Nobody. -- pepoluan, GKC forum
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Thursday, 1 November 2018 at 03:10:22 UTC, H. S. Teoh wrote: Actually, code within a module *should* be tightly coupled and cohesive -- that's the whole reason to put that code inside a single module in the first place. If two pieces of code inside a module are only weakly coupled or completely decoupled, that's a sign that they should not be in the same module at all. Or at the very least, they should belong in separate submodules that are isolated from each other. How does one determine, whether a 10,000 line module, is tightly coupled and cohesive? Only the author can make that statement - which they naturally will, even if it's not true. An outsider, seeking to verify that statement, has a hell of a job on their hands...(I for one, think code smell immediately). As soon as you see a class interface in a module, in D, you have to assume their is other code in the module, perhaps down around line 9,900, that is bypassing its interface, and doing who knows what to it Sure, the author might be happy, but an auditor/code reviewer, will likely have a different view, when a 10,000 line module is shoved in front of them, and they know, that 'anything goes', 'all bets are off', inside the D module But besides all this, D's philosophy is about mechanism rather than policy. The goal is to give the programmer the tools to do what he needs to do, rather than a bunch of red tape to dictate what he cannot do. That's why we have @trusted, @system, and even asm. The programmer is responsible for making sane architectural decisions with the tools he is given, rather than being told what (not) to do within the confines of his cell. If you're looking for policy, maybe Java would suit you better. :-P I don't use a particular language. I'm more interested in design and architecture. In the age of 'lock-down-everything', increased modularity is becoming more important. A monolithic module approach, is already outdated, and risky, in terms of developing secure, maintainable software I think providing an additional tool, to those who seek to use D, such as 'strict private' (syntax can be argued about), would aid better design - it can't make it any worse, that's for sure). Although. I don't mean strict private like freepascal, but strict private, as in it inherits everything that private already does, but additionally, become private within the module too. Is that really such a bad idea? Are there no programmers out there in the D world that might think this could be a good, additional tool, to give programmers, so they can better architect their solution? The amount of push back in the D community on this idea, is really odd to me. I'm still trying to understand why that is. Are D programmers just hackers, insterested in getting their code to work, no matter what? Are their not enough Java/C# programmers coming to D - and bringing their design skills with them?
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Thu, Nov 01, 2018 at 10:37:59PM +, unprotected-entity via Digitalmars-d-announce wrote: > On Thursday, 1 November 2018 at 03:10:22 UTC, H. S. Teoh wrote: > > > > Actually, code within a module *should* be tightly coupled and > > cohesive -- that's the whole reason to put that code inside a single > > module in the first place. If two pieces of code inside a module > > are only weakly coupled or completely decoupled, that's a sign that > > they should not be in the same module at all. Or at the very least, > > they should belong in separate submodules that are isolated from > > each other. > > How does one determine, whether a 10,000 line module, is tightly > coupled and cohesive? > > Only the author can make that statement - which they naturally will, > even if it's not true. > > An outsider, seeking to verify that statement, has a hell of a job on > their hands...(I for one, think code smell immediately). The code reviewer can reject a 10,000-line module off the bat as being too large. It's up to the project to enforce such conventions. > As soon as you see a class interface in a module, in D, you have to > assume their is other code in the module, perhaps down around line > 9,900, that is bypassing its interface, and doing who knows what to > it > > Sure, the author might be happy, but an auditor/code reviewer, will > likely have a different view, when a 10,000 line module is shoved in > front of them, and they know, that 'anything goes', 'all bets are > off', inside the D module Yes, and this is when you, or the project manager, puts down the foot and say this is unacceptable, break this module up into smaller submodules or else it doesn't go into the master repository. Simple. [...] > I don't use a particular language. I'm more interested in design and > architecture. > > In the age of 'lock-down-everything', increased modularity is becoming > more important. A monolithic module approach, is already outdated, and > risky, in terms of developing secure, maintainable software I don't understand what D's approach to modules has to do with being monolithic. Why can't you just write smaller modules if private being module-wide bothers you so much? D has package.d that can make a set of smaller submodules appear as a larger module to outside code. Use it. > I think providing an additional tool, to those who seek to use D, such > as 'strict private' (syntax can be argued about), would aid better > design - it can't make it any worse, that's for sure). > > Although. I don't mean strict private like freepascal, but strict > private, as in it inherits everything that private already does, but > additionally, become private within the module too. > > Is that really such a bad idea? Are there no programmers out there in > the D world that might think this could be a good, additional tool, to > give programmers, so they can better architect their solution? It's not a bad idea. In fact, if I were in charge of designing D, I'd probably do the same. But D chose to do it differently -- and part of the rationale, if I understand it correctly, is to eliminate the need for `friend` declarations like in C++. But maybe Andrei or whoever it was that made this decision can step up and explain why it was designed this way. All we're saying is that it's not the end of the world if private is module-wide rather than aggregate-wide. You can still have your encapsulation by splitting up your code into smaller files, which, given what you said above, you want to be doing anyway since the idea of a 10,000-line source file is so abhorrent to you. The fundamental issue here is that there needs to be some kind of unit of encapsulation. Java and C# chose to make the class that unit; D chose the module. If the Java/C# unit of encapsulation is what you want, all you have to do is to make the module equivalent to the class, problem solved. It's not as though there is no encapsulation at all and you're left out in the wild west of C's global namespace, or that the workaround is too onerous to be practical. > The amount of push back in the D community on this idea, is really odd > to me. I'm still trying to understand why that is. Are D programmers > just hackers, insterested in getting their code to work, no matter > what? Are their not enough Java/C# programmers coming to D - and > bringing their design skills with them? It's not so much push back, as being worn out from every other newcomer clamoring for the same thing year after year without ever having tried to do it the D way. Not saying that you're doing that, but it just becomes a sort of knee-jerk reaction after X number of newcomers barge in repeating the same old complaints that has the same old answers that everyone is tired of repeating. Having said that, though, there are some here who *do* want something like what you describe... IIRC Manu has voiced this before, and there may be others. (I myself don't consider it a bi
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Wednesday, 31 October 2018 at 10:48:24 UTC, Sebastien Alaiwan wrote: "Encapsulation" is about implementation hiding and access control ("public/private"), and requires programming language support (e.g most dynamic languages don't have it). "Encapsulation is sometimes referred to as the first pillar or principle of object-oriented programming. According to the principle of encapsulation, a class or struct can specify how accessible each of its members is to code outside of the class or struct. Methods and variables that are not intended to be used from outside of the class .. can be hidden to limit the potential for coding errors or malicious exploits." https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/ D simply has *zero* support for encapsulation of classes or structs, within the module (only encapsulation from code that is outside the module). Any programmers interested in enforcing encapsulation in D (the first pillar of OOP), are *forced* (because the language doesn't provide the tool to do anything else) to use the one class, one struct, per file solution. Which seems really silly to me. D forces you into Java like programming - just to encapsulate a little class or struct. Speaking of 'structs', I don't see anyone in the D community, telling others to use 'one struct per module'.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Fri, Nov 02, 2018 at 12:25:21AM +, unprotected-entity via Digitalmars-d-announce wrote: [...] > "Encapsulation is sometimes referred to as the first pillar or > principle of object-oriented programming. According to the principle > of encapsulation, a class or struct can specify how accessible each of > its members is to code outside of the class or struct. Methods and > variables that are not intended to be used from outside of the class > .. can be hidden to limit the potential for coding errors or malicious > exploits." > > https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/ That is a narrow definition of encapsulation that is very OO-centric, and IMO, it sorta misses the larger point behind encapsulation, focusing instead on the mechanics of it, and that the specific implementation of it in the OO paradigm. The concept of encapsulation goes beyond OO and classes; it has to do with modularity and well-defined interfaces between modules (or units of encapsulation -- this is not necessary the same thing as a D module). It's fine to explain how OO's concept of classes and methods implement encapsulation, but to *define* encapsulation in terms of classes and methods is IMO missing the forest for the trees. If *that's* your basis for understanding encapsulation, it would it explain a lot of your reactions to this thread. But there is more to the world than the narrow realm of the OO paradigm, and in a multi-paradigm language like D, it doesn't seem to make sense to be handicapped by a definition of encapsulation that really only makes sense in the context of an OO language. What encapsulation is really about, is the ability to modularize your code into self-contained units which have well-defined interfaces, with private code and data that cannot be accessed outside of that unit. In OO languages, this unit would be the class. But in D, it's the module. That doesn't make D non-encapsulated; it just means we're using a different unit than an OO language. It's just a difference between pounds and dollars, not some fundamental discrepancy. You just have to convert one currency to another, that's all. > D simply has *zero* support for encapsulation of classes or structs, > within the module (only encapsulation from code that is outside the > module). > > Any programmers interested in enforcing encapsulation in D (the first > pillar of OOP), are *forced* (because the language doesn't provide the > tool to do anything else) to use the one class, one struct, per file > solution. Which seems really silly to me. D forces you into Java like > programming - just to encapsulate a little class or struct. > > Speaking of 'structs', I don't see anyone in the D community, telling > others to use 'one struct per module'. Because we love UFCS, and structs just lend themselves very well to that sort of usage. And along that line, recent wisdom is that it's better to move things *out* of classes (and structs) if they don't need access to private members. (Sorry, I wanted to include a link for this, but I couldn't find the article -- the title eludes me and google isn't turning up anything useful.) Class and struct APIs should be as minimal as possible -- just enough to do what needs to be done and no more, and the rest of the syntactic sugar (that makes it more palatable to your users) belongs outside as optional convenience functions. T -- There is no gravity. The earth sucks.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Thursday, 1 November 2018 at 23:58:15 UTC, H. S. Teoh wrote: Having said that, though, there are some here who *do* want something like what you describe... IIRC Manu has voiced this before, and there may be others. (I myself don't consider it a big enough issue to be worth agonizing over.) So far, there has yet to be a strong enough argument for per-aggregate private to convince Walter & Andrei. It's them you have to convince, not the rest of us. Even if we were to all agree with you, it doesn't mean squat if Walter and Andrei won't budge on the issue. Again, I feel it's Walter and Andrei that should be doing the convincing.. they are always silent on this matter, which is a real shame,as I think their insights might actually be useful ;-) If it's simply not practical, from a language design, to consider this further, then I'd like to know that - I work at a higher leve of abstraction and have no idea about this. So not hearing from Walter or Andrei, is really unhelpful, as to whether it's an idea worth pursuing, or an idea that Walter and Andrei would never accept - which is it? Anyway, the real 'problem' (in my opinion), is not the idea. The idea is sound (or at least, it's not unsound), and it's represented in all major langauges, already. The real problem, is that whenever this idea pops up (as it has, and will continue to do so), far too many people on this forum attempt to divert the discussion from 'what is the usefulness of this new idea' to 'what's the difficulty of finding ways to avoid any change.' The discussion can never move forward under those circumstances. I would like the discussion to move forwards, and people start to think about how such a change could be adopted, how difficult it would be to implement, how will it play with other features in the langauge..etc It's a real shame we can't get beyond "No. We don't like your idea, and even if we did, we don't want to do it".
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Thu, 01 Nov 2018 22:37:59 +, unprotected-entity wrote: > On Thursday, 1 November 2018 at 03:10:22 UTC, H. S. Teoh wrote: >> >> Actually, code within a module *should* be tightly coupled and cohesive >> -- that's the whole reason to put that code inside a single module in >> the first place. If two pieces of code inside a module are only weakly >> coupled or completely decoupled, that's a sign that they should not be >> in the same module at all. Or at the very least, they should belong in >> separate submodules that are isolated from each other. > > How does one determine, whether a 10,000 line module, is tightly coupled > and cohesive? You can get a pretty accurate result by just saying "no". 10KLOC in one module is almost always a problem. Failing that, you can do a code review. Which will take a very long time. The solution to that is to submit less code at a time, review as you go, and keep modules smaller. For instance, Phobos keeps most modules below 3000 lines of code, including unittests. The largest module, std.datetime.systime, has about 6000 lines of code -- but if you exclude unittests and test-only code, it's more like 1000. > Only the author can make that statement - which they naturally will, > even if it's not true. I think a lot of programmers are well aware of the failings of their code. > As soon as you see a class interface in a module, in D, you have to > assume their is other code in the module, perhaps down around line > 9,900, that is bypassing its interface, and doing who knows what to > it And so you have a rule against casting from an interface to a concrete type, if that's a thing that worries you. It's something you can check rather easily in a reasonably sized code review. > In the age of 'lock-down-everything', increased modularity is becoming > more important. A monolithic module approach, is already outdated, and > risky, in terms of developing secure, maintainable software That statement could be taken as being against an approach that recommends structuring a project as a monolithic module, or against an approach that treats modules as a monolith in terms of protection. > I think providing an additional tool, to those who seek to use D, > such as 'strict private' (syntax can be argued about), would aid better > design - it can't make it any worse, that's for sure). It would be more language complexity in order to make it easier to have large modules. But you already said that large modules are a problem. > Is that really such a bad idea? Are there no programmers out there in > the D world that might think this could be a good, additional tool, to > give programmers, so they can better architect their solution? The use case is when you don't want to break up a module and you don't trust yourself not to modify private members from the wrong parts of the module. That's not useless. It's also not obviously so useful as to merit inclusion. A lot of languages do without any notion of private. A lot, like the entire ALGOL family up to Oberon-2, Go, Rust, Lua, Haskell, and Node.js, use exported and unexported symbols instead, and that's per module. A fair number just don't have a notion of public and private symbols. > The amount of push back in the D community on this idea, is really odd > to me. I'm still trying to understand why that is. Are D programmers > just hackers, insterested in getting their code to work, no matter what? > Are their not enough Java/C# programmers coming to D - and bringing > their design skills with them? There are plenty of language designers that didn't think it obvious. Might be better to consider why instead of implying that no D programmers are familiar with or care about good design. I mean, if there are popular languages from the 1960s through the 2010s that do things the same way as D, that sounds like a pretty good indication that it's not an obviously bad idea. It's not rock-solid; actual evidence from the industry would be superior. But I think you would have presented that evidence already.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Friday, 2 November 2018 at 00:53:52 UTC, H. S. Teoh wrote: And along that line, recent wisdom is that it's better to move things *out* of classes (and structs) if they don't need access to private members. (Sorry, I wanted to include a link for this, but I couldn't find the article -- the title eludes me and google isn't turning up anything useful.) Class and struct APIs should be as minimal as possible -- just enough to do what needs to be done and no more, and the rest of the syntactic sugar (that makes it more palatable to your users) belongs outside as optional convenience functions. Maybe you are thinking of the "Prefer non-member non-friend functions to member functions" rule from Herb Sutter's "Effective C++" books?
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Fri, Nov 02, 2018 at 10:18:11AM +, ShadoLight via Digitalmars-d-announce wrote: > On Friday, 2 November 2018 at 00:53:52 UTC, H. S. Teoh wrote: > > > > And along that line, recent wisdom is that it's better to move > > things *out* of classes (and structs) if they don't need access to > > private members. (Sorry, I wanted to include a link for this, but I > > couldn't find the article -- the title eludes me and google isn't > > turning up anything useful.) Class and struct APIs should be as > > minimal as possible -- just enough to do what needs to be done and > > no more, and the rest of the syntactic sugar (that makes it more > > palatable to your users) belongs outside as optional convenience > > functions. > > > > Maybe you are thinking of the "Prefer non-member non-friend functions > to member functions" rule from Herb Sutter's "Effective C++" books? [...] Ah yes, that's the one. Thanks! T -- Democracy: The triumph of popularity over principle. -- C.Bond
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Friday, 2 November 2018 at 05:29:39 UTC, Neia Neutuladh wrote: It's also not obviously so useful as to merit inclusion. No. I don't say it merits inclusion. I do say it merits discussion, as to its merits. But from what I see, so far, is D, Go, Rust...they are seem to have a love affair with C like programming, but are to afraid to call it C. So they call it... modules. ... they're the wild west, where anything goes(sorry, that thought had to comejust playing too much RDR2 at the moment...and as much fun as it looks, gee I'm glad we have the law now...well.. not always..)
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Thursday, 1 November 2018 at 22:37:59 UTC, unprotected-entity wrote: On Thursday, 1 November 2018 at 03:10:22 UTC, H. S. Teoh wrote: Actually, code within a module *should* be tightly coupled and cohesive -- that's the whole reason to put that code inside a single module in the first place. If two pieces of code inside a module are only weakly coupled or completely decoupled, that's a sign that they should not be in the same module at all. Or at the very least, they should belong in separate submodules that are isolated from each other. How does one determine, whether a 10,000 line module, is tightly coupled and cohesive? You take a look through it and make a judgement. Only the author can make that statement - which they naturally will, even if it's not true. ? An outsider, seeking to verify that statement, has a hell of a job on their hands...(I for one, think code smell immediately). There is a basic question in life. Do you believe in discernment (if possible informed by data) or are you someone who makes decisions on the basis of evidence and believes that anything else is completely arbitrary and nothing more than a matter of opinion. My impression is that the values of the D community tend more in the direction of recognising the importance of discernment. If someone is somebody who believes more in 'evidence', policy and rules then it probably isn't going to be satisfying expecting one's values to be shared on a wide scale here. People also differ in their working memory and the degree to which they naturally think associatively. Chopping up everything into small pieces favours those who have a smaller working memory and who think more analytically but it's a disadvantage for those who have a large working memory and think associatively. For a private project that's something to be resolved between the relevant people, but I don't think it's reasonable to say that large files per se are wrong, just because they aren't your cup of tea personally. I think that lots of things seem clear in theory but the difference between theory and practice is often quite large. In practice Phobos is very readable. And on the other hand, I have seen an experienced and capable C# programmer struggle to understand an intranet site written in the approved way by an experienced person who was well-trained at Microsoft. I couldn't understand it either so I concatenated all the little itty bitty files, pulled out the data structures and then it was easy. I don't use a particular language. I'm more interested in design and architecture. Can one really speak of that kind of design in the abstract ? Language features shape your choices and lead to large shifts in the optimum. If you don't have design by introspection as a possibility you are going to pick something else. In the age of 'lock-down-everything', increased modularity is becoming more important. A monolithic module approach, is already outdated, and risky, in terms of developing secure, maintainable software If you can't understand the program does that make you more or less secure? Security requires also to understand the behaviour of the system as a coherent whole. I think D programs are pretty easy from that perspective. Is that really such a bad idea? Are there no programmers out there in the D world that might think this could be a good, additional tool, to give programmers, so they can better architect their solution? Burden of proof is on you to write a DIP and make an argument for it. I am not sure you would find it easier to get a change into C++. Look at how difficult it is for Walter sometimes ; and he has just a little earned credibility. Same thing for Guido - he had such little fun with a recent PEP he decided to retire from BDFL of python. The amount of push back in the D community on this idea, is really odd to me. I'm still trying to understand why that is. Persuading people isn't easy even if it's a good idea. Look at the pushback from C++ over static if. They crippled it when they finally did relent. It's a bit entitled to think that if you can't persuade people without having written a DIP that it's them not you! Are D programmers just hackers, insterested in getting their code to work, no matter what? Are their not enough Java/C# programmers coming to D - and bringing their design skills with them? Would you mind explaining why you think that people from mass communities have design skills by virtue of having come from a mass community? Walter and Andrei are just a little bit known for their design capabilities so the bar is quite high. I think it's possible you might have things topsy turvy. Making D code work is rarely a problem. Every nation has its own strengths and weaknesses and the same is true of language communities. Having worked with D professionally since 2015 and with a decent size codebase in re
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On 11/02/2018 03:18 AM, ShadoLight wrote: > Maybe you are thinking of the "Prefer non-member non-friend functions to > member functions" rule from Herb Sutter's "Effective C++" books? Scott Meyers. Ali
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Saturday, 3 November 2018 at 00:44:15 UTC, Laeeth Isharc wrote: When one encounters a new idea that's unfamiliar sometimes it's easy to think that because it's unfamiliar it must be unsound. That can be a mistake. It might be better to suspend judgement for a while and keep an open mind. I believe that responses like this, are really just designed to further obfuscate the point I'm trying to make, so that it cannot progress any further. Now, speaking of keeping an open mindlet's get back to my point.. can we? (q1) Why is it, that people who use D, object *so much* to the idea of allowing (at the choice of the programmer) for a type to have it's own private state *within* a module (so that its private state is respected by other code also within that module)? Or you ask it another way: (q2)Why must a type within a module *always* have its private state exposed to other code within the module? (the key word here, being 'always'). Both questions seem very reasonable to ask, in my opinion, not matter what background you have. (q3) Should a language intentionally set out to prevent a programmer from making that choice? please stop obfuscating, and try to answer the questions.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Sat, 03 Nov 2018 04:50:52 +, unprotected-entity wrote: > (q1) Why is it, that people who use D, object *so much* to the idea of > allowing (at the choice of the programmer) for a type to have it's own > private state *within* a module (so that its private state is respected > by other code also within that module)? We object because the people complaining can't point at a use case that seems reasonable. If you provided real-world examples, we'd consider them. We are further disinclined to engage with you as a collaborator because you're insulting us and ignoring a lot of our responses to you. > Or you ask it another way: > > (q2)Why must a type within a module *always* have its private state > exposed to other code within the module? (the key word here, being > 'always'). Because that is both simple and flexible. Swift forsakes simplicity in favor of high granularity, and it's exhausting just reading its protection modifier list. > (q3) Should a language intentionally set out to prevent a programmer > from making that choice? You're mischaracterizing the situation to make your preferred feature look like the default. That's the opposite of how language design works. Nothing is there by default. You add things as necessary to get a language that's good enough.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Saturday, 3 November 2018 at 06:57:50 UTC, Neia Neutuladh wrote: On Sat, 03 Nov 2018 04:50:52 +, unprotected-entity wrote: (q1) Why is it, that people who use D, object *so much* to the idea of allowing (at the choice of the programmer) for a type to have it's own private state *within* a module (so that its private state is respected by other code also within that module)? We object because the people complaining can't point at a use case that seems reasonable. If you provided real-world examples, we'd consider them. We are further disinclined to engage with you as a collaborator because you're insulting us and ignoring a lot of our responses to you. This reasoning is meaningless: one must not prove the obvious. During the writing of a complex module, it happened to me many times to desire what unprotected-entity asks. And if the validity of a person's reasoning is a function of his way of expressing them, well ... do not pose to software engineers at least Or you ask it another way: (q2)Why must a type within a module *always* have its private state exposed to other code within the module? (the key word here, being 'always'). Because that is both simple and flexible. Swift forsakes simplicity in favor of high granularity, and it's exhausting just reading its protection modifier list. (q3) Should a language intentionally set out to prevent a programmer from making that choice? You're mischaracterizing the situation to make your preferred feature look like the default. That's the opposite of how language design works. Nothing is there by default. You add things as necessary to get a language that's good enough. What he asks is reasonable and useful, and help in a myriad of cases. I can not even see a disadvantage in the introduction of a true private attribute. What you ask is reasonable and useful, and help in a myriad of cases. I can not even see a disadvantage in the introduction of a true private attribute. But already, it seems that nobody still really understands how to use the DIP1000 in the practicality of its code, "const-immutable" is a failure, five hundred pages of reasoning about "shared", entire sections of language abandoned halfway a poor man is asked to bring evidence that the water is wet gee
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Sat, 03 Nov 2018 11:24:06 +, FooledDonor wrote: > And if the validity of a person's reasoning is a function of his way of > expressing them, well ... do not pose to software engineers at least If you want other people to do work for you, you need to convince them to do it. This is an open source project, so the appropriate way of doing this is with good reasoning and examples, not by insulting people. This is true even if the feature seems obviously good and necessary to one or two people, if those people don't have abnormally large influence over the project.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Saturday, 3 November 2018 at 06:57:50 UTC, Neia Neutuladh wrote: On Sat, 03 Nov 2018 04:50:52 +, unprotected-entity wrote: (q1) Why is it, that people who use D, object *so much* to the idea of allowing (at the choice of the programmer) for a type to have it's own private state *within* a module (so that its private state is respected by other code also within that module)? We object because the people complaining can't point at a use case that seems reasonable. If you provided real-world examples, we'd consider them. We are further disinclined to engage with you as a collaborator because you're insulting us and ignoring a lot of our responses to you. Or you ask it another way: (q2)Why must a type within a module *always* have its private state exposed to other code within the module? (the key word here, being 'always'). Because that is both simple and flexible. Swift forsakes simplicity in favor of high granularity, and it's exhausting just reading its protection modifier list. (q3) Should a language intentionally set out to prevent a programmer from making that choice? You're mischaracterizing the situation to make your preferred feature look like the default. That's the opposite of how language design works. Nothing is there by default. You add things as necessary to get a language that's good enough. la..de.da..de.dah... really just sounds like more obfuscatation to me... As I said, I don't think the 'please no, don't do it, it'll just make our syntax too complex' position can be taken seriously. And in any case, and how many time do I have to tell you this (turning your phrase to me, back on you), that this is NOT a request for change. This is just a discussion about what benefit it might provide, if the programmer had the choice to have declare private state for a type, and have the compiler enforce that design choice, by preventing other code within the module to have direct access to that types private state. Now..go and read that last paragraph again... no more obfuscation...please.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Saturday, 3 November 2018 at 06:57:50 UTC, Neia Neutuladh wrote: We object because the people complaining can't point at a use case that seems reasonable. If you provided real-world examples, we'd consider them. -- module test; struct S { private uint a; void setA(uint n) { // damn implicit conversions! I just hate them! if(n != 4294967286) this.a = n; else assert(0); } } void func(ref S s) { s.a = -10; // this might be on line 856 in your module. // there's a good chance, that when you get to write line 856, // that you've forgotten why you had written setA, on line 7. // i.e. to get around D's outrageous implicit conversions! // Even worse, in D, you may never know you mistyped here, // until things go wrong.. // maybe terribly wrong. // That's why I made 'a' private, and declared an interface for using it. } // compile with: -unittest -main unittest { S s = S(); func(s); // oh no...why did you do that! no error though. s.setA(-10); // gee.. if only I could declare 'a' to be: __private // then would I know something is wrong. } --
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Saturday, 3 November 2018 at 20:38:29 UTC, unprotected-entity wrote: As has been pointed out several times before, this is a contrived example. Allow a simple transformation: ``` module test; struct S { private uint a; void setA(uint n) { // damn implicit conversions! I just hate them! if(n != 4294967286) this.a = n; else assert(0); } void func() { s.a = -10; // this might be on line 856 in your module. // there's a good chance, that when you get to write line 856, // that you've forgotten why you had written setA, on line 7. // i.e. to get around D's outrageous implicit conversions! // Even worse, in D, you may never know you mistyped here, // until things go wrong.. // maybe terribly wrong. // That's why I made 'a' private, and declared an interface for using it. } } // compile with: -unittest -main unittest { S s = S(); s.func(); // oh no...why did you do that! no error though. s.setA(-10); // gee.. if only I could declare 'a' to be: __private then would I know something is wrong... [except it's useless in this case] } ``` The only difference is that `func` became a member function. And now what? You can just as easily "forget" what's in your struct/class as in your whole module.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On 11/2/2018 5:44 PM, Laeeth Isharc wrote: When one encounters a new idea that's unfamiliar sometimes it's easy to think that because it's unfamiliar it must be unsound. That can be a mistake. It might be better to suspend judgement for a while and keep an open mind. So true. My ideas on how to write code have changed dramatically over the years, and continue to change.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Saturday, 3 November 2018 at 16:21:36 UTC, Neia Neutuladh wrote: On Sat, 03 Nov 2018 11:24:06 +, FooledDonor wrote: And if the validity of a person's reasoning is a function of his way of expressing them, well ... do not pose to software engineers at least If you want other people to do work for you, you need to convince them to do it. This is an open source project, so the appropriate way of doing this is with good reasoning and examples, not by insulting people. The answer to your "if" is: NO, this is not the topic. The argument is: does the induction of a true "private" attribute add value to the language or not? It is possible to discuss, in these forums, or everything must be truncated with "if you want to do it, and best wishes to convince then W & A" This is true even if the feature seems obviously good and necessary to one or two people, if those people don't have abnormally large influence over the project. Nothing is "necessary" to a language outside "turing completeness". Can we argue about the problems arising from the potential introduction of this feature?
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Sun, 04 Nov 2018 11:36:39 +, FooledDonor wrote: > Can we argue about the problems arising from the potential introduction > of this feature? There are many potential features that wouldn't cause problems in isolation. Should we add all of them? Obviously not; the result would be a horribly complex language that takes too much time to learn and is impossible to maintain. So instead, we need to aggressively filter out potential added features to ensure that what they add is sufficiently important to justify later maintenance costs and the effort of learning things. The justification for this feature rests on real-world examples of bugs that have been caused by its lack.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Saturday, 3 November 2018 at 03:58:16 UTC, Ali Çehreli wrote: On 11/02/2018 03:18 AM, ShadoLight wrote: > Maybe you are thinking of the "Prefer non-member non-friend functions to > member functions" rule from Herb Sutter's "Effective C++" books? Scott Meyers. Ali Thanks for the correction.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Sunday, 4 November 2018 at 15:40:03 UTC, Neia Neutuladh wrote: On Sun, 04 Nov 2018 11:36:39 +, FooledDonor wrote: Can we argue about the problems arising from the potential introduction of this feature? There are many potential features that wouldn't cause problems in isolation. Should we add all of them? Obviously not; the result would be a horribly complex language that takes too much time to learn and is impossible to maintain. No one should/need learn the entire tool itself in order to get thing done. If you found yourself in such a situation, then you seriously need to rethink on what you should be doing. -Alex
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Sunday, 4 November 2018 at 15:40:03 UTC, Neia Neutuladh wrote: There are many potential features that wouldn't cause problems in isolation. Should we add all of them? Obviously not; the result would be a horribly complex language that takes too much time to learn and is impossible to maintain. So instead, we need to aggressively filter out potential added features to ensure that what they add is sufficiently important to justify later maintenance costs and the effort of learning things. The justification for this feature rests on real-world examples of bugs that have been caused by its lack. You keep turning this argument around, as though it is a request to change D. We should be able to have a discussion, about ways to further improve type safety inside a module, without being constantly taunted by your hyperbole. The discussion might even lead to ways to help programmers address the issues being raised, that don't require a change to D (and I don't mean 'just put your class/struct in it's own module'). Now, the fact is, that the D module is a conglomeration of different types. None of the types declared within a module has any independence from any other type, within the module. Fact. Some clearly think this is a good thing. Fine, you have it that way already. That will never change. But some think this requires an undue burden on the part of the programmer to be extra vigiliant around how they compose their types. Sure a few lines in module, you can easily do that. But as the number of line increase, so would the chances of you doing something you never intended to do. There is no way the programmer to provide a guarantee around the use of a type, from other code in the module, since the data and methods in any type are mutable from outside that type. Some think this shared mutability between types within a module, can lead to bugs and unsafe behaviour. Some think it might be nice, if the programmer had a means to provide better guarantees for the their declared types. Type safety is an important and critical component in software architecture. It's not something you should 'agressively filter out' from discussion. Whether the language could handle a change to address this, would be a further stage of the discussion. From what I hear, it may not be able to handle such a change, and the D module is doomed to be what it is, and programmers will bear the responsibilty for type safety within a module.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Sunday, 4 November 2018 at 15:40:03 UTC, Neia Neutuladh wrote: There are many potential features that wouldn't cause problems in isolation. Should we add all of them? Obviously not; the result would be a horribly complex language that takes too much time to learn and is impossible to maintain. So instead, we need to aggressively filter out potential added features to ensure that what they add is sufficiently important to justify later maintenance costs and the effort of learning things. The justification for this feature rests on real-world examples of bugs that have been caused by its lack. I think there are more than enough real-world examples, of where issues around 'type safety', or lack of, have caused a sufficient number of bugs, to warrant a discussion about ways to further improve type safety. D module's are not type safe, at least as far as the code within that module is concerned. To have to go to silly lengths just to get type safety in D. D is language the favors convenience 1st. type safety 2nd... or is it 3rd.. This lack of enforcable type safety *within* a module, leads to undisciplned code. Phobos is a 'real-world' example of it. D needs an 'Industrial Strength D' book, as well as an 'Effective D'. I assume the moderator(s) doesn't like me anymore, as my posts are no longer being published. Great way to run a discussion forum by the way.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Monday, 5 November 2018 at 01:23:44 UTC, nobodycares wrote: I assume the moderator(s) doesn't like me anymore, as my posts are no longer being published. Great way to run a discussion forum by the way. It not just you, my post had disappear only to reappear on later dates. I can vouch for them by saying that this is a bug that you and I are experiencing. -Alex
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Saturday, 3 November 2018 at 21:35:04 UTC, Walter Bright wrote: On 11/2/2018 5:44 PM, Laeeth Isharc wrote: When one encounters a new idea that's unfamiliar sometimes it's easy to think that because it's unfamiliar it must be unsound. That can be a mistake. It might be better to suspend judgement for a while and keep an open mind. So true. My ideas on how to write code have changed dramatically over the years, and continue to change. I hear the advantages of the way D does it. But nobody wants to hear about the disadvantages. Am I the only one who needs to keep an 'open mind'? What harm can come, from an optional tool, that enables enforceable encapsulation of a type, within a module (from code also in the module, but outside that type)? Can someone please answer that? And yet again, I remind people that this is not a request for change. This is a discussion about what benefit such a tool can bring.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Mon, 05 Nov 2018 01:23:44 +, nobodycares wrote: > I think there are more than enough real-world examples, of where issues > around 'type safety', or lack of, have caused a sufficient number of > bugs, to warrant a discussion about ways to further improve type safety. You do realize we can all see that you're posting from the same IP address with three different usernames, don't you? How's the dual boot working out? Firefox 52 is kind of old; are you holding off on updating for addon compatibility? If you want to make a good sockpuppet, you'll need to invest some effort. Different browsers for each. Different IP addresses. Usernames that look like reasonable human names or forum handles. Posting about topics other than your personal cause. And if you had actual examples, you'd have shown them already.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Saturday, 3 November 2018 at 21:35:04 UTC, Walter Bright wrote: On 11/2/2018 5:44 PM, Laeeth Isharc wrote: When one encounters a new idea that's unfamiliar sometimes it's easy to think that because it's unfamiliar it must be unsound. That can be a mistake. It might be better to suspend judgement for a while and keep an open mind. So true. My ideas on how to write code have changed dramatically over the years, and continue to change. what are your thoughts on implicit conversions, given your obvious experience? To me, implicit conversion are code smells, as they undermine the independence of types (and as you've probably gathered, I very much like type independence..a lot). Did you do it this way for C like compatability? Would you do it differently, if you could? uint x = -10; // what! int x; bool y = true; x = y; // what! etc..
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Saturday, 3 November 2018 at 21:28:22 UTC, Stanislav Blinov wrote: The only difference is that `func` became a member function. And now what? You can just as easily "forget" what's in your struct/class as in your whole module. ok. Now, what are your options then (assuming you want an independent type)? (option 1) define one encapsulated type, per module. (option 2) have a means for type independence within a module - i.e. selective hiding. D only gives you one choice here, not two. I would say, that your response backs up my argument, that is, a second option might actually be worthwhile. perhaps, something like: __private (now __private is everything private already is, but additionally, its private outside the scope of the type declaring it, and now, you'd get a compile time guarantee of correctness - e.g. if you accidently tried to ignore that types independence. It's call 'type encapsulation' ;-)
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Monday, 5 November 2018 at 05:55:02 UTC, unprotected-entity wrote: ok. Now, what are your options then (assuming you want an independent type)? (option 1) define one encapsulated type, per module. (option 2) have a means for type independence within a module - i.e. selective hiding. D only gives you one choice here, not two. Is having two choices really better than having one choice? When you only have one choice, you don't have to make any decisions. When you have two choices, you are *forced* to make a decision, whether you want to or not. That can be a good thing, when the decision you're making is meaningful--for example, when you're deciding whether to use GC or manual memory management. But when the decision you're making is meaningless--for example, when you're deciding whether to indent with tabs or spaces--it's just a waste of time. It doesn't matter which you choose, but you're forced to make a decision anyway. (Or, even worse, your entire team is forced to waste time *agreeing* on a decision together.) When it comes to encapsulation, it makes no *functional* difference whether you achieve it by putting all your types into separate modules, or by using something like `__private`. The end result is the same either way. The only reason to prefer one over the other is personal taste--in other words, it's a matter of style, just like tabs vs. spaces. Personally, I don't think there's anything wrong with preferring `__private` over separate modules, just like I don't think there's anything wrong with preferring spaces over tabs. But I think being forced to make meaningless decisions is bad no matter what you prefer, and because of that, I don't think `__private` should be added to D.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Monday, 5 November 2018 at 05:55:02 UTC, unprotected-entity wrote: On Saturday, 3 November 2018 at 21:28:22 UTC, Stanislav Blinov wrote: The only difference is that `func` became a member function. And now what? You can just as easily "forget" what's in your struct/class as in your whole module. ok. Now, what are your options then (assuming you want an independent type)? (option 1) define one encapsulated type, per module. (option 2) have a means for type independence within a module - i.e. selective hiding. Option 3 - don't access private state unless you intend to. That's literally how you write implementations, in pretty much any language that has access modifiers. D only gives you one choice here, not two. Nope. You can have a type spanning several modules. That's what packages do, among other things. I would say, that your response backs up my argument, that is, a second option might actually be worthwhile. perhaps, something like: __private No, it really doesn't. Your argument was that the programmer might accidentally forget, and I've shown quite clearly that no keyword is going to protect them from that. If you can forget in module scope, you can forget in class scope. There can be only one solution: don't forget. As in: stop inventing imaginary examples. People, in practice, don't "accidentally" modify the guts of their own types. That horse is quite dead, I'm afraid. (now __private is everything private already is, but additionally, its private outside the scope of the type declaring it, and now, you'd get a compile time guarantee of correctness - e.g. if you accidently tried to ignore that types independence. No, you do not. You still have that same "problem" inside the type's definition. It's call 'type encapsulation' ;-) If you're afraid of implicit conversions, define your own type that disallows them, problem solved. Has nothing to do with private. That is what's called 'type encapsulation'.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Monday, 5 November 2018 at 09:03:59 UTC, Stanislav Blinov wrote: On Monday, 5 November 2018 at 05:55:02 UTC, unprotected-entity wrote: On Saturday, 3 November 2018 at 21:28:22 UTC, Stanislav Blinov wrote: The only difference is that `func` became a member function. And now what? You can just as easily "forget" what's in your struct/class as in your whole module. ok. Now, what are your options then (assuming you want an independent type)? (option 1) define one encapsulated type, per module. (option 2) have a means for type independence within a module - i.e. selective hiding. Option 3 - don't access private state unless you intend to. That's literally how you write implementations, in pretty much any language that has access modifiers. D only gives you one choice here, not two. Nope. You can have a type spanning several modules. That's what packages do, among other things. I would say, that your response backs up my argument, that is, a second option might actually be worthwhile. perhaps, something like: __private No, it really doesn't. Your argument was that the programmer might accidentally forget, and I've shown quite clearly that no keyword is going to protect them from that. If you can forget in module scope, you can forget in class scope. There can be only one solution: don't forget. As in: stop inventing imaginary examples. People, in practice, don't "accidentally" modify the guts of their own types. That horse is quite dead, I'm afraid. (now __private is everything private already is, but additionally, its private outside the scope of the type declaring it, and now, you'd get a compile time guarantee of correctness - e.g. if you accidently tried to ignore that types independence. No, you do not. You still have that same "problem" inside the type's definition. It's call 'type encapsulation' ;-) If you're afraid of implicit conversions, define your own type that disallows them, problem solved. Has nothing to do with private. That is what's called 'type encapsulation'. I'm glad you've worked only with excellent programmers, who in solitary write code in a module, knowing it to perfection, until the end of time. And I'm also glad you did not have to debug inherited code, maybe before the packages existed, tens of thousands of lines, and to make sure you do not start you had to cut and sew classes and private structures, just to check that the intentions of the programmer, who perhaps was not as good as you are. This your reiterate to every topic, thread, or question post on these forums with a "NO", is simply pathetic, as Manu has expounded a few weeks ago. Get off your pedestal, and drop into the real life of those who program in D with colleagues not as perfect as you are.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Monday, 5 November 2018 at 09:43:06 UTC, FooledDonor wrote: Get off your pedestal, and drop into the real life of those who program in D with colleagues not as perfect as you are. So where are these teams of imperfect D programmers who are plagued by accidental modifications of private class members? Sociomantic? Funkwerk? Weka?
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Monday, 5 November 2018 at 11:07:11 UTC, Mike Parker wrote: On Monday, 5 November 2018 at 09:43:06 UTC, FooledDonor wrote: Get off your pedestal, and drop into the real life of those who program in D with colleagues not as perfect as you are. So where are these teams of imperfect D programmers who are plagued by accidental modifications of private class members? Sociomantic? Funkwerk? Weka? You're right! How did I not think about it! I have to write on a public forum the name of the company and the name and surname of the colleagues I think are mediocre! Plagued, guess it! I deal with modules from well over 10k loc, I feel the lack of __private, during the study or debugging of certain monsters. You can believe it or not, it does not matter, it's your problem. But frankly this attitude where EVERYTHING must be demonstrated when talking to you veterans of the forum, has reached ridiculous peaks. As someone wrote before me, you should seriously rethink your open mind.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Wednesday, 31 October 2018 at 13:33:52 UTC, Stanislav Blinov wrote: On Wednesday, 31 October 2018 at 13:28:54 UTC, rikki cattermole wrote: But at the end of the day, it just depends on the scope of the module. Is it getting to large? If so, split. Yup. LOC aren't a particulalry informative metric. Documentation, comments, unit tests, blanks, all contribute to it. Split by scope, by concept, by responsibility, by any implementation-relevant metric, not by LOC. As the joke goes, your word processor is doomed to fail once it also starts sending out emails... This is why the only measure is SLOC, not total lines, and one can measure SLOC easily with `dscanner --sloc` (for other languages I use sloccount). It probably counts unit tests though, which is unfortunate, but since my tests are always out-of-tree these days anyway...
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Thursday, 1 November 2018 at 03:10:22 UTC, H. S. Teoh wrote: On Thu, Nov 01, 2018 at 02:45:19AM +, unprotected-entity via Digitalmars-d-announce wrote: [...] Another thing to look for, is signs of code smell. I would include in this, unit tests calling private methods (which seems to be a popular thing for D programmers to do). Some will disagree that this is a code smell, but I have yet to see a good argument for why it is not. White-box testing. In principle, I agree with you that if your unittests are doing black-box testing, then they should definitely not be calling private methods. However, limiting yourself to black-box testing means your private functions can be arbitrarily complex If any of your functions are arbitrarily complex, you're doing it wrong (if alone) or your colleagues are (because it passed code review). and yet it's not thoroughly tested. If it's not thoroughly tested via the public API, then either some of the private code is useless and should be deleted, or the public API tests aren't good enough. Sometimes you really do want a unittest to ensure the private method is doing what you think it's doing, and this requires white-box testing. Only when writing the private method TDD-style. After it's written, I'd delete any and all tests for the private code and rely on the public API instead. Possibly useful when debugging though. This is especially important to prevent regressions, even if it seems redundant at first. Only doing black-box testing means a later code change in the private method can subtly introduce a bug that's not caught by the unittest (because it cannot call a private method directly to verify this). This makes no sense to me. If the public API tests didn't catch a regression, then the tests are bad. End of.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Friday, 2 November 2018 at 10:18:11 UTC, ShadoLight wrote: On Friday, 2 November 2018 at 00:53:52 UTC, H. S. Teoh wrote: And along that line, recent wisdom is that it's better to move things *out* of classes (and structs) if they don't need access to private members. (Sorry, I wanted to include a link for this, but I couldn't find the article -- the title eludes me and google isn't turning up anything useful.) Class and struct APIs should be as minimal as possible -- just enough to do what needs to be done and no more, and the rest of the syntactic sugar (that makes it more palatable to your users) belongs outside as optional convenience functions. Maybe you are thinking of the "Prefer non-member non-friend functions to member functions" rule from Herb Sutter's "Effective C++" books? C++ however doesn't have reflection. The problem with non-member functions is I can't reflect on a type and loop over its member functions if some of the functionality is somewhere else.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Saturday, 3 November 2018 at 04:50:52 UTC, unprotected-entity wrote: On Saturday, 3 November 2018 at 00:44:15 UTC, Laeeth Isharc wrote: [...] I believe that responses like this, are really just designed to further obfuscate the point I'm trying to make, so that it cannot progress any further. Now, speaking of keeping an open mindlet's get back to my point.. can we? (q1) Why is it, that people who use D, object *so much* to the idea of allowing (at the choice of the programmer) for a type to have it's own private state *within* a module (so that its private state is respected by other code also within that module)? Because it adds no value. Creating a new file is not expensive. (q2)Why must a type within a module *always* have its private state exposed to other code within the module? (the key word here, being 'always'). Because then `friend` isn't needed. (q3) Should a language intentionally set out to prevent a programmer from making that choice? Yes, given that it decreases the overall complexity of the language.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Monday, 5 November 2018 at 01:39:46 UTC, unprotected-entity wrote: On Saturday, 3 November 2018 at 21:35:04 UTC, Walter Bright wrote: On 11/2/2018 5:44 PM, Laeeth Isharc wrote: When one encounters a new idea that's unfamiliar sometimes it's easy to think that because it's unfamiliar it must be unsound. That can be a mistake. It might be better to suspend judgement for a while and keep an open mind. So true. My ideas on how to write code have changed dramatically over the years, and continue to change. I hear the advantages of the way D does it. But nobody wants to hear about the disadvantages. We heard you, we just disagree it's a disadvantage. What harm can come, from an optional tool, that enables enforceable encapsulation of a type, within a module (from code also in the module, but outside that type)? Can someone please answer that? The harm is complexity. But hey, if you want to write such a tool go right ahead. And yet again, I remind people that this is not a request for change. This is a discussion about what benefit such a tool can bring. In my opinion, no benefit at all.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Monday, 5 November 2018 at 11:07:11 UTC, Mike Parker wrote: So where are these teams of imperfect D programmers who are plagued by accidental modifications of private class members? Sociomantic? Funkwerk? Weka? First, nobody needs to explain the problems that type errors create. Any decent programmer should already be well aware of such problems. Second, it's a matter of scale. How many D programmers are there? The probability that someone will do something silly, like below, will increase with scale. That's just how it is. Now. How many C++/Java/C# programmers are there? And, since the chance of error will increase with the number of users (and also the number of lines) how many of them would find that their compiler will happily compile the code below? and the is answer: zero no matter how many of them - it'll *always* be zero. unless they do it in D. -- module test; class Firefighter { private void DoSomethingATraineeShouldNotDo() {} } class TraineeFirefighter : Firefighter {} unittest { TraineeFirefighter joe = new TraineeFirefighter(); joe.DoSomethingATraineeShouldNotDo(); } --
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Wednesday, 7 November 2018 at 11:00:49 UTC, TheFirefighter wrote: Now. How many C++/Java/C# programmers are there? Even if a `super private` attribute or something is introduced, the semantics of private in D will not change. Your hypothetical C# programmer who switches to D assuming identical visiblity semantics to C# will still write that program that makes the plane crash. Luckily Java programmers write one class per file anyway. On Wednesday, 7 November 2018 at 11:00:49 UTC, TheFirefighter wrote: First, nobody needs to explain the problems that type errors create. Any decent programmer should already be well aware of such problems. Look, you can keep making new accounts and restating that it's so obvious you don't need to convince anyone, and that D programmers are just stubborn. But it won't help advancing the discussion like you want. If you can't show that there are actual programmers writing appropriately sized modules containg bugs simply because of the lack of a class-private visibility level, then people don't want to engineer a solution to a seemingly non-existant problem, write and maintain the compiler code + specification for it, update existing tutorials, editors and tools, inform existing users about the change, and making the language more complex overall. Imagine if I made a proposal like this: "Hello, MrHaltingProblem here! We obviously need a @noloops attribute. My co-workers are constantly writing buggy loops with wrong loop conditions so I NEED the extra protection. You're asking for a justification? Trust me, any decent programmer knows the importance of this. You are just too stubborn to see all the bugs that the lack of this attribute causes. Asking for real world examples? ``` class Plane { void doLandingProcedure() { // lots of code while (1) {} // OOPS! // lots of code } } ``` There! Now let's discuss the benefit of such a feature in D." This doesn't look like a compelling argument, so D programmers would probably suggest making more use of ranges instead.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Wednesday, 7 November 2018 at 13:15:03 UTC, Dennis wrote: [snip] "Hello, MrHaltingProblem here! We obviously need a @noloops attribute. My co-workers are constantly writing buggy loops with wrong loop conditions so I NEED the extra protection. You're asking for a justification? Trust me, any decent programmer knows the importance of this. You are just too stubborn to see all the bugs that the lack of this attribute causes. Asking for real world examples? ``` class Plane { void doLandingProcedure() { // lots of code while (1) {} // OOPS! // lots of code } } ``` There! Now let's discuss the benefit of such a feature in D." This doesn't look like a compelling argument, so D programmers would probably suggest making more use of ranges instead. I get what you're saying here, but just to play devil's advocate, this feature could be added broadly to D without breaking any code. In particular, the @disable attribute could be extended to 1) take some input, in this case a keyword (foreach, while, goto, etc) but potentially also symbols (I'm thinking mainly function names here), and 2) @disable's behavior could be extended so that it works with like the protection attributes in terms of being able to use it as in @disable(keyword) { } or @disable(keyword):. For a start, something like @nogc and @nothrow are really just a special cases of @disable(GC) and @disable(Exception), or something. Also, the idea could be improved if there was some easy way to combine multiple attributes (there might be, but I don't know off the top of my head). Where I'm coming from is that these attributes aren't really based on any primitives. They are rather ad hoc. For instance, even this proposal would need additional work to enable @safe and pure to be based on primitives. What if someone wanted to make @disable(template) and have that enforced throughout their code? What if the decision not to include textual macros in D were instead set up as a default for @disable(textual_macros)?
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Wednesday, 7 November 2018 at 13:15:03 UTC, Dennis wrote: If you can't show that there are actual programmers writing appropriately sized modules containg bugs simply because of the lack of a class-private visibility level, then people don't want to engineer a solution to a seemingly non-existant problem, write and maintain the compiler code + specification for it, update existing tutorials, editors and tools, inform existing users about the change, and making the language more complex overall. well you could say the same about pointers. but..what happens when a large number of programmers start using pointers? In the hands of few, it's not such a big issue. In the hands of the many, well.. we all know the result. Decades of bugs! Should we wait till the bugs start appearing? But my argument actually is less about bugs, or the potential for bugs (although that potential obviously exists). My argument is more about the 'untyped' nature of the D module. That is, a type (say a class) is 'naked' in a module, exposed for all (in that module) to see. It can be violated in any number of ways, by other code in the module. I mean that is just fact. It's not something I should need to continually point out. Some say that' fine. A class should be subjected to that humiliation. Other say, if you wan't to prevent that humiliation, then you can do it already - that is, you can clothe a class, in D, by 'walling it off' in it's *own* module. That immediately tells you something about the nature of the module. The module is essentially an untyped universe. It removes the clothes from the class, and allows it to be violated. On that basis, bugs (or the potential for them), becomes an immediate reality - and more so in the hands of the many, as opposed to the hands fo the few. Now, if you're one of those that object to the use of classes (and there are many in the D forums), then you would already be biased towards dismissing my argument, and don't mind at all if the class is subject to humiliation. I would prefer you refrain from the discussion, if such bias is going to be used to shutdown the argument. Because it just brings the tone of the discussion down to a level that nobody wants to participate in - likely it's goal in the first place. Lets be clear. My argument (not my DIP - as there is none) is, that it can only strengthen D, if D allowed the programmer the option (just the option) to ensure that a class wasn't subjected to such humiliation, when there is other code in the module besides that class. The major purpose of a class afterall (understood by most programmers), is to impose contraints on interactions with other objects (or other code), in order to enforce correctness and eliminate inconsistencies. It does this, by clothing itself, so that other types cannot operate directly on its naked representation. Yes, I know, you *can* clothe your class in D, but *only* if you wall it off in it's module. If you want 2 classes in your module, now you need to manage 2 classes across 2 different modules. That is an increase in complexity for the programmer. But you have no choice, because the very instance you put other code in that module, you remove that protective clothing. All I'm asking for, is the ability to have extra code in the module, without the module removing the clothes from my types. Is that really too much too ask? I do not understand the motivations of those that reject such an argument. (hopefully, the moderator will post this..you never know on these forums..peoples post are going missing, or show up in the wrong order, days laterwhat's going on?)
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Thursday, 8 November 2018 at 09:53:59 UTC, TheFireFighter wrote: well you could say the same about pointers. but..what happens when a large number of programmers start using pointers? I don't see the parallel between pointers and class-private. But my argument actually is less about bugs, or the potential for bugs (although that potential obviously exists). My argument is more about the 'untyped' nature of the D module. That's a shame, I think the bug-argument is the stronger one. Now, if you're one of those that object to the use of classes (and there are many in the D forums), then you would already be biased towards dismissing my argument, and don't mind at all if the class is subject to humiliation. I would prefer you refrain from the discussion, if such bias is going to be used to shutdown the argument. My guess, based on my experience, is that bad coders will seek the shortest path to something that works. So if they need to quickly access a class-private member in the module they're working on, they'll remove the private attribute. But I don't know, I'm biased like everyone. I haven't worked in the same setting as you. That's why I'm really interested in hearing your perspective. I don't have a strong opinion on the importance of visibility attributes within a module, so I'm interested in hearing strong arguments from you. But so far, your arguments boil down to: - Avoiding justification - "Obviously" "I don't have to explain this" "Any decent programmer knows this" - Appeal to fear - "Just wait for all the problems that come in the future!" - Appeal to feeling - "Classes are naked, humiliated, their private parts are violated. That's so clearly wrong." I don't find such arguments strong. If they were, you could also justify adding the @noloops attribute as I jokingly did in my previous post. Lets be clear. My argument (not my DIP - as there is none) is, that it can only strengthen D, if D allowed the programmer the option (just the option) to ensure that a class wasn't subjected to such humiliation, when there is other code in the module besides that class. That sounds like "I just want there to be the option for aggregate value types... without using struct.". The question this raises is why the current solution is so problematic. I do not understand the motivations of those that reject such an argument. Do you agree that language additions add a lot of weight? If yes, then it's simply the fact that people don't think your suggestion bears that weight because it's already possible to do what you want in another way.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Thursday, 8 November 2018 at 13:18:30 UTC, Dennis wrote: That sounds like "I just want there to be the option for aggregate value types... without using struct.". The question this raises is why the current solution is so problematic. I just want (for example) to be able to write a module, that contains a class, and also has non-member, non-friend functions. You simply cannot do that in a D module, as the class has no clothes - to extend the metaphor from my recent post. I refer you to Scott Meyers article about the benefits of having 'non-friend' non-member functions: How Non-Member Functions Improve Encapsulation (btw. people misread that title - it should be been "How Non-Friend, Non-Member..." http://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197?pgno=1 Do you agree that language additions add a lot of weight? If yes, then it's simply the fact that people don't think your suggestion bears that weight because it's already possible to do what you want in another way. No it is not. You can keep saying there is, but it doesn't make it so. We don't seem to be on the same page here...do you misunderstand what I want? Fact: I cannot have a class in a module, and specify (so that the compiler can enforce it) that I want other code in the module to respect the specification of that class. It just cannot happen. Don't say it can. It can't. It's fact. As a result, one of my core guidelines are not applicable anymore, if I used D: " Don’t force together into a module things that will be used or maintained separately, and don’t separate things that will always be used and maintained together." Regarding the 'burden' to the D langauge, by providing the programmer with a tool to specify better encapsulation of code *within* the module: "I have become more and more convinced that the key to code reusability and scalability is encapsulation — having subsystems communicate through small, well-defined interfaces and letting them hide their own implementation details." - Walter Bright http://www.drdobbs.com/cpp/uniform-function-call-syntax/232700394?queryText=Scott%2BMeyers i.e. better encapsulation really is a good thing (although for many, it a lesson that needs to be learned).
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Thursday, 8 November 2018 at 23:50:18 UTC, TheFireFighter wrote: No it is not. You can keep saying there is, but it doesn't make it so. ... We don't seem to be on the same page here...do you misunderstand what I want? Fair enough, the exact thing you want is not possible. I understand that. It's also a fact that you can't have a value-type class. But just because you can't have a value type *class* doesn't mean you can't have a value-type aggregate: there is struct. The higher goal of encapsulating classes is possible by writing one per module and using package.d, it's just not possible with the restriction that multiple classes must be in the same file. Regarding the 'burden' to the D langauge, by providing the programmer with a tool to specify better encapsulation of code *within* the module: [quote] i.e. better encapsulation really is a good thing (although for many, it a lesson that needs to be learned). Walter considers the module the lowest level of encapsulation, while you consider the class to be that. Neither is proven to be better so far. To change the D language in that regard, you have to convince people that class-private is superior/important enough to warrant the language change. Unfortunately, the arguments given so far have not done that yet, since they mostly appeal to feeling, fear and 'the obvious' as mentioned earlier.
Re: Wed Oct 17 - Avoiding Code Smells by Walter Bright
On Thursday, 8 November 2018 at 23:50:18 UTC, TheFireFighter wrote: i.e. better encapsulation really is a good thing (although for many, it a lesson that needs to be learned). Public/private/protected are hacks anyway - and many object-oriented languages don't have it. They only provide extremely limited encapsulation ; the client still sees the non-public part, and can depend on it in unexpected ways: // my_module.d struct MyStruct { private: char[1024] data; } class MyClass { protected: abstract void f(); }; // main.d import my_module; import std.traits; import std.stdio; int main() { // depends on the list of private writefln("MyStruct.sizeof: %s", MyStruct.sizeof); members // depends on wether 'f' is declared abstract or not. writefln("isAbstractClass!MyClass: %s", isAbstractClass!MyClass); return 0; } If you want perfect encapsulation, use interfaces (as already said in this thread), or PIMPL.