开发者

Do you like languages that let you put the "then" before the "if"?

开发者 https://www.devze.com 2022-12-28 12:24 出处:网络
I was reading through some C# code of mine today and found this line: if (ProgenyList.ItemContainerGenerator.Status != System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated) return;

I was reading through some C# code of mine today and found this line:

if (ProgenyList.ItemContainerGenerator.Status != System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated) return;

Notice that you can tell without scrolling that it's an "if" s开发者_如何学Pythontatement that works with ItemContainerGenerator.Status, but you can't easily tell that if the "if" clause evaluates to "true" the method will return at that point.

Realistically I should have moved the "return" statement to a line by itself, but it got me thinking about languages that allow the "then" part of the statement first. If C# permitted it, the line could look like this:

return if (ProgenyList.ItemContainerGenerator.Status != System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated);

This might be a bit "argumentative", but I'm wondering what people think about this kind of construct. It might serve to make lines like the one above more readable, but it also might be disastrous. Imagine this code:

return 3 if (x > y);

Logically we can only return if x > y, because there's no "else", but part of me looks at that and thinks, "are we still returning if x <= y? If so, what are we returning?"

What do you think of the "then before the if" construct? Does it exist in your language of choice? Do you use it often? Would C# benefit from it?


Let's reformat that a bit and see:

using System.Windows.Controls.Primitives;

...

if (ProgenyList.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated)
{
    return;
}

Now how hard is it to see the return statement? Admittedly in SO you still need to scroll over to see the whole of the condition, but in an IDE you wouldn't have to... partly due to not trying to put the condition and the result on the same line, and party due to the using directive.

The benefit of the existing C# syntax is that the textual order reflects the execution order - if you want to know what will happen, you read the code from top to bottom.

Personally I'm not a fan of "return if..." - I'd rather reformat code for readability than change the ordering.


I don't like the ambiguity this invites. Consider the following code:

doSomething(x)
if (x > y);
doSomethingElse(y);

What is it doing? Yes, the compiler could figure it out, but it would look pretty confusing for a programmer.


Yes. It reads better. Ruby has this as part of its syntax - the term being 'statement modifiers'

irb(main):001:0> puts "Yay Ruby!" if 2 == 2
Yay Ruby!
=> nil
irb(main):002:0> puts "Yay Ruby!" if 2 == 3
=> nil

To close, I need to stress that you need to 'use this with discretion'. The ruby idiom is to use this for one-liners. It can be abused - however I guess this falls into the realm of responsible development - don't constrain the better developers by building in restrictions to protect the poor ones.


It's look ugly for me. The existing syntax much better.

if (x > y) return 3;


I think it's probably OK if the scope were limited to just return statements. As I said in my comment, imagine if this were allowed:

{
   doSomething();
   doSomethingElse();

   // 50 lines...

   lastThink();
} if (a < b);

But even just allowing it only on return statements is probably a slippery slope. People will ask, "return x if (a); is allowed, so why not something like doSomething() if (a);?" and then you're on your way down the slope :)

I know other languages do get away with it, but C#'s philosophy is more about making The One Right WayTM easy and having more than one way to do something is usually avoided (though with exceptions). Personally, I think it works pretty well, because I can look at someone else's code and know that it's pretty much in the same style that I'd write it in.


I don't see any problem with

return 3 if (x > y);

It probably bothers you because you are not accustomed to the syntax. It is also nice to be able to say

return 3 unless y <= x

This is a nice syntax option, but I don't think that c# needs it.


I think Larry Wall was very smart when he put this feature into Perl. The idea is that you want to put the most important part at the beginning where it's easy to see. If you have a short statement (i.e. not a compound statement), you can put it before the if/while/etc. If you have a long (i.e. compound) statement, it goes in braces after the condition.


Personally I like languages that let me choose.

That said, if you refactor as well as reformat, it probably doesn't matter what style you use, because they will be equally readable:

using System.Windows.Controls.Primitives;

...
var isContainersGenerated = 
    ProgenyList.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated;

if (!isContainersGenerated) return;
//alternatively

return if (!isContainersGenerated);


There is a concern reading the code that you think a statement will execute only later to find out it might execute.

For example if you read "doSomething(x)", you're thinking "okay so this calls doSomething(x)" but then you read the "if" after it and have to realise that the previous call is conditional on the if statement.

When the "if" is first you know immediately that the following code might happen and can treat it as such.

We tend to read sequentially, so reading and going in your mind "the following might happen" is a lot easier than reading and then realising everything you just read needs to be reparsed and that you need to evaluate everything to see if it's within the scope of your new if statement.


Both Perl and Ruby have this and it works fine. Personally I'm fine with as much functionality you want to throw at me. The more choices I have to write my code the better the overall quality, right? "The right tool for the job" and all that.

Realistically though, it's kind of a moot point since it's pretty late for such a fundamental addition in C#'s lifecycle. We're at the point where any minor syntax change would take a lot of work to implement due to the size of the compiler code and its syntax parsing algorithm. For a new addition to be even considered it would have to bring quite a bit of functionality, and this is just a (not so) different way of saying the same thing.


Humans read beginning to end. In analyzing code flow, limits of the short term memory make it more difficult to read postfix conditions due to additional backtracking required. For short expressions, this may not be a problem, but for longer expressions it will incur significant overhead for users that are not seasoned in the language they are reading.


Agreed with confusing , I never heard about this construction before , so I think correct way using then before if must always contents the result of else, like

return (x > y) ? 3 : null;

else way there is no point of using Imperative constructions like

return 3 if (x > y);
return 4 if (x = y);
return 5 if (x < y);

imho It's kinda weird, because I have no idea where to use it...


It's like a lot of things really, it makes perfect sense when you use it in a limited context(a one liner), and makes absolutely no sense if you use it anywhere else.

The problem with that of course is that it'd be almost impossible to restrict the use to where it makes sense, and allowing its use where it doesn't make sense is just odd.

I know that there's a movement coming out of scripting languages to try and minimize the number of lines of code, but when you're talking about a compiled language, readability is really the key and as much as it might offend your sense of style, the 4 line model is clearer than the reversed if.


I think it's a useful construct and a programmer would use it to emphasize what is important in the code and to de-emphasize what is not important. It is about writing intention-revealing code.

I use something like this (in coffeescript):

index = bla.find 'a'
return if index is -1

The most important thing in this code is to get out (return) if nothing is found - notice the words I just used to explain the intention were in the same order as that in the code.

So this construct helps me to code in a way which reflects my intention slightly better.

It shouldn't be too surprising to realize that the order in which correct English or traditional programming-language grammar has typically required, isn't always the most effective or simplest way to create meaning.

Sometimes you need to let everything hang out and truly reassess what is really the best way to do something.


It's considered grammatically incorrect to put the answer before the question, why would it be any different in code?

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号