5 ms·
> Languages need to offer control flow mechanisms that allow you to separate common cases in the code from the uncommon cases. Strong disagree with this senten
by enriquto 6y ago
> Languages need to offer control flow mechanisms that allow you to separate common cases in the code from the uncommon cases.
Strong disagree with this sentence. It represents the exact opposite of what I deem a good programming language. The difference between "common" and "uncommon" execution paths must be of no bearing. Moreover, this "likeliness" depends on the (unknown to the programmer) usage that the program will be put through. For all you know, the uncommon path may be the only one that will be ever traversed in all instances of your program. A correctly specified program must deal with all possible input conditions, and that includes missing files, inconsistent parameters, and lack of resources. A filename existing or not is the same boolean value as an integer being even or odd.
- creata 6y ago> The difference between "common" and "uncommon" execution paths must be of no bearing. Why? I think that a good programming language should help readers focus on the "essence" of an algorithm. Usually, handling stuff like memory allocation errors is just noise in that effort. Besides, most errors will usually be propagated to the caller, so I think the programming language should make that convenient, like Rust does with its ? syntax, and most languages do (perhaps too implicitly) with some concept of exceptions.
- simiones 6y agoCode is primarily meant to be read by humans. Humans can't focus on 30 things at once when reading code. A function that should take a list of strings and return a list of all the strings in the first list starting with 'A' will be harder to read if it must also handle allocation errors for the new list, because they are a completely different kind of concern. Even outside of programming, human thought often works exactly in terms of general cases and exceptions. It's just what comes naturally, and we shouldn't be fighting it in code. > The difference between "common" and "uncommon" execution paths must be of no bearing. Moreover, this "likeliness" depends on the (unknown to the programmer) usage that the program will be put through. For all you know, the uncommon path may be the only one that will be ever traversed in all instances of your program. As the designer of that program, I obviously know up to a very good degree of confidence what the usage of the program will be: I am designing my program for a particular use, by definition. Sure, I may not know exactly how flaky your network may be, but I know that this program only really works on networks that deliver more packets than they drop, that can read all of the bytes I wrote to disk back, at least most of the time, and so on. Or, perhaps I'm writing a program that is meant to run on very flaky networks (say, a device for wireless thunderstorm sensors): I expect that program to look very different from the Netflix app's networking code.
- enriquto 6y ago> I am designing my program for a particular use, by definition. No; this is bad engineering. You write a program to conform to a specification. In the specification, it says what must happen when a file does not exist, what must happen when there's not enough memory, etc. Then you write the specified behavior into code.
- junke 6y agoThe specification and boundary conditions directly comes from an analysis of the expected usage. Except for some all-purpose libraries you don't develop in a vacuum (assuming you don't work for Roomba).
- enriquto 6y agoBut design and coding are different steps, best kept separate. When you are designing, I agree with you, the expected usage is very important. But in the design step the particular language mechanism for dealing with conditions does not matter. Once you get a specification to program to, all input conditions can be treated as equal. That is, unless you need to optimize heavily by biasing your execution path for a certain percentage of input cases (which should be clearly described in the specification).
- junke 6y ago> Once you get a specification to program to, all input conditions can be treated as equal. And if the spec says "try downloading the file 3 times at 5 seconds interval; if that fails, give up the update", I am free to implement it however I want (?) unless I missing your point.
- enriquto 6y agosure! for example, in your case you only need a for loop and an if/else statement
- 6y ago
- junke 6y agoStrongly disagree with your disagreement. Programming features help you organize your code. The fact that you actually have a robust software or not with what the language offers is another problem. When people say "errors are values", I say: yes, but they are a special kind of values. The same way floats are special (signaling NaNs), or that bools are special (short-circuit operators). It is great to have special support for values which need to be used in a certain way (here: don't lose any error, bubble up by default). It is great to have the opportunity (not the obligation) to use features for separation of concerns. This makes it a bit like an aspect-oriented approach where normal code emits errors and error handling code elsewhere knows how to handle/restart them. If you language allows it, it makes also sense also to decouple logging (tracing functions) or data-access permissions (postgresql row level security). In the C code I maintain at work, everything is here in plain view, logging, error handling, etc., and I am not complaining, but more recently we tend to use other languages or code generation a lot (think of something like protobuf) because it makes code a lot easier to maintain.
- enriquto 6y agoThanks for explaining so clearly your view. I'm totally biased towards programming practices that make execution paths 100% explicit and local. Yet it is interesting to understand the other point of view (and somewhat liberating, to be honest).
- junke 6y agoThanks for the kind remarks (we are all biased :))