The advanced concept of properties


  • area_pol

    Found in mission critical module. Anonymizing could only make it better, so here it is, in its raw uncompromising beauty.

    private string _value;
    public string Value
    {
        get
        {
            if (_value != null)
            {
                return _value;
            }
            else
            {
                return (string)null;
            }
        }
        set
        {
            if (value != null)
            {
                _value = value;
            }
            else
            {
                _value = (string)null;
            }
        }
    }
    

  • SockDev



  • if( value == true ){
        return true;
    }
    else if( value == false ){
        return false;
    }
    else{
        return FILE_NOT_FOUND;
    }
    


  • Obviously, string.Empty does not exist.

    Didn't try it out - what exactly is the result of the (string)null cast?



  • @rhywden string types can be null so I'd guess... Just null?



  • @the_quiet_one said in The advanced concept of properties:

    @rhywden string types can be null so I'd guess... Just null?

    Alright, now I'm curious.


  • area_pol

    @rhywden said in The advanced concept of properties:

    Obviously, string.Empty does not exist.

    Didn't try it out - what exactly is the result of the (string)null cast?

    Well, suprisingly, it's null.



  • @mrl Yeah, you're completely correct. I've let myself be confused by the casting shenanigans which Javascript usually does with shit like that...

    0_1503516480034_6fc5ab14-8e76-4025-95e2-88da395ec686-image.png


  • Impossible Mission - B

    That actually looks like it came out of a decompiler. I've seen (type)null casts there, but never in code written by a human being.



  • @mrl said in The advanced concept of properties:

    @rhywden said in The advanced concept of properties:

    Obviously, string.Empty does not exist.

    Didn't try it out - what exactly is the result of the (string)null cast?

    Well, suprisingly, it's null.

    That's what I'd expect. String is the type; null is the value. It's a null pointer which, if it contained a valid reference instead of null, would point to a string.



  • 0_1503522861914_ca4f566b-b524-4f54-8a53-b773242a4723-image.png

    That is all.



  • @rhywden said in The advanced concept of properties:

    Didn't try it out - what exactly is the result of the (string)null cast?

    It's just a null value with the type of "string".


  • area_pol

    @masonwheeler said in The advanced concept of properties:

    That actually looks like it came out of a decompiler. I've seen (type)null casts there, but never in code written by a human being.

    It was probably written by an intern. So you're kind of correct.



  • @mrl said in The advanced concept of properties:

    It was probably written by an intern.

    My current intern is quite good at doing:

    list< foo > tmp_foo_list;
    foo tmp_foo;
    foreach (bar b, bar_list) {
        tmp_foo = first_operation_on_list_item(b);
        tmp_foo_list.append(tmp_foo);
    }
    foreach (foo f, tmp_foo_list) {
        second_operation_on_list_item(f);
    }
    tmp_foo_list.clear(); 
    

    I don't know, doing two operations in the same loop must too hard? (note also the useless clear() at the end, and the declaration of the variable inside the loop)



  • @remi said in The advanced concept of properties:

    note...the declaration of the variable inside the loop

    I can't find it. But that's a great CodeSOD.



  • @boomzilla said in The advanced concept of properties:

    if( value == true ){
        return true;
    }
    else if( value == false ){
        return false;
    }
    else{
        return FILE_NOT_FOUND;
    }
    

    where FILE_NOT_FOUND is the result of (!true && !false).



  • @the_quiet_one said in The advanced concept of properties:

    Just null?

    Well, not just null. A string null.

    0_1503572859956_Capture.PNG

    :hanzo:

    @blakeyrat said in The advanced concept of properties:

    It's just a null value with the type of "string".



  • @mrl said in The advanced concept of properties:

    It was probably written by an intern.

    I want to make a joke about interned strings, but I won't.



  • @boomzilla said in The advanced concept of properties:

    @remi said in The advanced concept of properties:

    note...the declaration of the variable inside the loop

    I can't find it. But that's a great CodeSOD.

    Yep, I obviously (well, obviously for me...) meant the declaration outside the loop (while the only use is inside the loop).

    I keep repeating him that he should declare his variable as close as possible from their first use, but somehow he keeps doing it almost the C-way by declaring everything at the start of the function (he never learnt C, so he cannot possibly have picked it up from there, so pure :wtf:).



  • @remi There is a certain cleanliness of keeping all of your declarations in one place, though I do tend to put mine closer to use, too.


  • area_pol

    @remi said in The advanced concept of properties:

    he keeps doing it almost the C-way by declaring everything at the start of the function (he never learnt C, so he cannot possibly have picked it up from there, so pure :wtf:).

    Maybe stupid C conventions are natural way of doing things...



  • @boomzilla True, but I guess that while you might put several declarations together a bit earlier than strictly needed, you will still keep them not too far. For example, if you have a function that does 2 things (yeah I know, that's bad...), you might declare all variables used in the first thing in one block, and all the variables for the second thing in the second block, but I guess you won't declare all variables at the start of the function.

    As with all rules, there is a balance to find between keeping the code readable and following rules. But not even caring about the rule is bad. Especially when you're an intern and learning. When you know what you're doing, you can break rules, as long as you know that there is a rule and that you are breaking it.


  • Discourse touched me in a no-no place

    @remi said in The advanced concept of properties:

    but I guess that while you might put several declarations together a bit earlier than strictly needed, you will still keep them not too far.

    Well as long as your functions aren't 500+ line behemoths, sticking them at the start of the functions should still result in them not being too far away.. :passport_control:



  • @pjh said in The advanced concept of properties:

    Well as long as your functions aren't 500+ line behemoths,

    I'd rather have one 500-lines function than 500 1-line functions...



  • @remi said in The advanced concept of properties:

    @pjh said in The advanced concept of properties:

    Well as long as your functions aren't 500+ line behemoths,

    I'd rather have one 500-lines function than 500 1-line functions...

    void doStuff() {
        step1();
    }
    
    void step1() {
        int i = 10;
        step2(i);
    }
    
    void step2(int& i) {
       for (int j=0; j<i; j++)
           step3(j);
    } // etc.
    

    ?



  • @mrl said in The advanced concept of properties:

    Found in mission critical module. Anonymizing could only make it better, so here it is, in its raw uncompromising beauty.

    private string _value;
    public string Value
    {
        get
        {
            if (_value != null)
            {
                return _value;
            }
            else
            {
                return (string)null;
            }
        }
        set
        {
            if (value != null)
            {
                _value = value;
            }
            else
            {
                _value = (string)null;
            }
        }
    }
    

    This is what they get for paying scaled to KLOC...


  • Discourse touched me in a no-no place

    @marczellm said in The advanced concept of properties:

    @remi said in The advanced concept of properties:

    @pjh said in The advanced concept of properties:

    Well as long as your functions aren't 500+ line behemoths,

    I'd rather have one 500-lines function than 500 1-line functions...

    void doStuff() {
        step1();
    }
    
    void step1() {
        int i = 10;
        step2(i);
    }
    
    void step2(int& i) {
       for (int j=0; j<i; j++)
           step3(j);
    } // etc.
    

    ?

    I see some two line functions in there!!!!!


  • Impossible Mission Players - A

    @pjh said in The advanced concept of properties:

    @remi said in The advanced concept of properties:

    but I guess that while you might put several declarations together a bit earlier than strictly needed, you will still keep them not too far.

    Well as long as your functions aren't 500+ line behemoths, sticking them at the start of the functions should still result in them not being too far away.. :passport_control:

    You joke, just yesterday I smashed apart a 924 line function (tied as a timer callback) that did everything you could ever hope to do:

    • Refresh (rather pointlessly) the game server level definitions from the database.
    • Refresh (again, pointlessly) the Azure Virtual Machine definitions from the database
    • Ask Azure all about whatever VMs existed in a particular Resource Group (as defined in said definitions)
    • Confirm and translate the running/provisioning status of sad VMs
    • Update the app's cut-down representation cache of said VM statuses
    • Polled each VM for an up-to-date list of currently running game servers
    • Ping each game server and time the response for a ping rating
    • Check to see if we need to create or destroy a game server instance on each of the VMs based on player counts in a given level, and whether a level has been vacant for too long
    • Check to see if we need to create or destroy a VM
    • Do the needful and create/destroy game servers and VMs
    • Schedule the next run of the above

    Thing used to take almost 40 seconds to do all the above.
    Cleaning it up, it takes about three.


  • Impossible Mission Players - A

    @dkf said in The advanced concept of properties:

    @marczellm said in The advanced concept of properties:

    @remi said in The advanced concept of properties:

    @pjh said in The advanced concept of properties:

    Well as long as your functions aren't 500+ line behemoths,

    I'd rather have one 500-lines function than 500 1-line functions...

    void doStuff() {
        step1();
    }
    
    void step1() {
        int i = 10;
        step2(i);
    }
    
    void step2(int& i) {
       for (int j=0; j<i; j++)
           step3(j);
    } // etc.
    

    ?

    I see some two line functions in there!!!!!

    Yeah! Step1 could be defined as

    void step1() {
        step2(int i = 10);
    }
    

  • Dupa

    @boomzilla said in The advanced concept of properties:

    @remi There is a certain cleanliness of keeping all of your declarations in one place

    But it doesn't make sense. The kinds of instructions that do list all of the prerequisites at the top are those instructions where you (i.e. The person) need to collect all of the materials. Recipes, woodworking instructions. But here you are the reader, not the preparer.

    Declaring variables at the top tell you you're gonna to need stuff, but then it dilutes how the stuff is used and what for. Do we still need this string builder? Or this number? Or this whatever?

    It's much better when your functions are small and the declaration is close to the usage, but if your function is 100 lines long and you declare all variables at the top, then I pity the people who have to understand this code.




  • BINNED

    @remi said in The advanced concept of properties:

    the C-way by declaring everything at the start of the function

    I don't do that even in C these days. The C compilers knew how to handle shit like that for what, at least 2 decades now?

    It might also be that I'm doing it just to spite all the people who "taught" me C in school and uni; they all claimed that's where the variables HAVE to be. Also, that you can't declare a new variable in, for example, a for loop statement, or that you can't use a variable as a size when declaring an array.

    I'm very impressed you all used C back in the 70s, apparently, but Turing damn it, keep up with the language features and teach students about useful "modern" shit as well!


  • Discourse touched me in a no-no place

    @onyx said in The advanced concept of properties:

    The C compilers knew how to handle shit like that for what, at least 2 decades now?

    Almost. C99 codified it.


  • BINNED

    @pjh said in The advanced concept of properties:

    @onyx said in The advanced concept of properties:

    The C compilers knew how to handle shit like that for what, at least 2 decades now?

    Almost. C99 codified it.

    Yeah, I figured it's close enough to round up. You :pendant:



  • @kt_ said in The advanced concept of properties:

    @boomzilla said in The advanced concept of properties:

    @remi There is a certain cleanliness of keeping all of your declarations in one place

    But it doesn't make sense. The kinds of instructions that do list all of the prerequisites at the top are those instructions where you (i.e. The person) need to collect all of the materials. Recipes, woodworking instructions. But here you are the reader, not the preparer.

    I disagree. You are the one preparing the understanding of the code (when you read it, obviously not when you write it...), and knowing the "ingredients" in advance can help understanding what some code is for. To keep the recipe analogy: if you're baking and you see that there is milk in the recipe, then when you mix the rest of the ingredients you will not worry if the mix looks very dry, because you know there is milk that will be added at some point. If you were to discover the ingredients one by one at the time you put them in, you might think that something is going wrong, and go back to double-check quantities or even tweak the proportions, until you go one step further and it suddenly makes sense because you're adding milk.

    Same in your code, a snippet might look out of place, or useless, until you see that a further bit of code uses it and it suddenly makes sense. By declaring in advance a variable that hints at that further bit of code, you make the first snippet less weird.

    For example, let's say that you have a function where you see a snippet that seems to be computing the min of something, but for that function the min makes absolutely no sense. But above that snippet, there is a declaration of a variable "range": suddenly you can guess that there is a good reason to compute the min (and probably the max as well), which is to get the range. It might even help you to understand what that snippet is doing (if e.g. computing the min is not a trivial operation on that data): if you know that later you'll be computing a "range", then it makes sense that first you probably need to compute a min (and a max).

    if your function is 100 lines long and you declare all variables at the top

    Well obviously, we're not talking about that. The point is that the other extreme of "declare all variables strictly at the latest possible point" is not always helpful.



  • @onyx said in The advanced concept of properties:

    I'm very impressed you all used C back in the 70s, apparently, but Turing damn it, keep up with the language features and teach students about useful "modern" shit as well!

    As I said, the guy in question has never learned C. He probably (I didn't check with him, but that would match what I know of his training) started with Python, did a bit of Matlab or other similar scientific programming (maybe R, I'm not sure) and then did some C++ (which is what he's using here).

    I very much doubt that his teachers in Python, or in C++ (and I know that one so I am almost certain of what he would have taught him), would have told him to put all declarations at top. I don't know where that comes from. Maybe this is indeed something natural, like @MrL was saying...


  • I survived the hour long Uno hand

    @onyx said in The advanced concept of properties:

    It might also be that I'm doing it just to spite all the people who "taught" me C in school and uni; they all claimed that's where the variables HAVE to be. Also, that you can't declare a new variable in, for example, a for loop statement, or that you can't use a variable as a size when declaring an array.

    My coworker told me yesterday that "C++ hasn't changed a lot since you were 12". I told him I keep hearing it has >.>


  • SockDev

    @yamikuronue said in The advanced concept of properties:

    I told him I keep hearing it has

    It has at least three times, with two more on the way.


  • I survived the hour long Uno hand

    @raceprouk The sticking point here was "a lot", obviously. I told him it was my understanding that C++11 in particular brought big changes, but I wasn't sure exactly what. We both conceded it didn't matter because we don't want to write C++ at work anyway.


  • Dupa

    @remi said in The advanced concept of properties:

    @kt_ said in The advanced concept of properties:

    @boomzilla said in The advanced concept of properties:

    @remi There is a certain cleanliness of keeping all of your declarations in one place

    But it doesn't make sense. The kinds of instructions that do list all of the prerequisites at the top are those instructions where you (i.e. The person) need to collect all of the materials. Recipes, woodworking instructions. But here you are the reader, not the preparer.

    I disagree. You are the one preparing the understanding of the code (when you read it, obviously not when you write it...), and knowing the "ingredients" in advance can help understanding what some code is for.

    I knew you'd go this way. But I don't think you are right here. The fact that gore declaring a bunch of ints and strings doesn't say a lot and even if they're named well, this doesn't really prepare me for what's gonna happen. The function's name should, but not seeing a bunch of variables there.

    It's easier to understand what's happening when you see stuff being used, not when you see a bunch of stuff lying around.

    To keep the recipe analogy: if you're baking and you see that there is milk in the recipe, then when you mix the rest of the ingredients you will not worry if the mix looks very dry, because you know there is milk that will be added at some point. If you were to discover the ingredients one by one at the time you put them in, you might think that something is going wrong, and go back to double-check quantities or even tweak the proportions, until you go one step further and it suddenly makes sense because you're adding milk.

    But when you are reading the code, you are not creating it. You don't need to know that there is still water in the cup and the original developer might have used it later on. You want to see the whole procedure. And then you will know if the water was added. You shouldn't judge before you get to the end.

    Plus, when following a recipe for a cake, you will still worry that it looks dry, the only way you won't is if you read the recipe before starting work (as you should) or if it explicitly says so in the recipe itself. So you still need to read the recipe first to see what will happen with the ingredients, the sole fact they're there doesn't tell you much.

    However, when reading code it's better for stuff to appear magically. Here you're manipulating this string and now lo and behold! here you create puff! out of thin air something that could use that string.

    Again, if you write clean code, this doesn't really matter, because your functions are short, they are well-named and even if you declare variables at the top, it's still extremely close to where it's used.

    Same in your code, a snippet might look out of place, or useless, until you see that a further bit of code uses it and it suddenly makes sense.

    So shouldn't this snippet be there where it's used? yo spare you his moment of bewilderment?

    By declaring in advance a variable that hints at that further bit of code, you make the first snippet less weird.

    Ok, I kinda see your point here. But this just means that by declaring upfront you're trying to make do of a shitty situation. By writing short functions and properly arranging your code, you won't need to explain why the first snippet was there.

    For example, let's say that you have a function where you see a snippet that seems to be computing the min of something, but for that function the min makes absolutely no sense. But above that snippet, there is a declaration of a variable "range": suddenly you can guess that there is a good reason to compute the min (and probably the max as well), which is to get the range. It might even help you to understand what that snippet is doing (if e.g. computing the min is not a trivial operation on that data): if you know that later you'll be computing a "range", then it makes sense that first you probably need to compute a min (and a max).

    Wouldn't it be better to do:

    var range = CreateRange(params)

    In CreateRange:

    var min = CalculateMin(params)
    var max = CalculateMax(params)
    return new Range(min, max)

    if your function is 100 lines long and you declare all variables at the top

    Well obviously, we're not talking about that. The point is that the other extreme of "declare all variables strictly at the latest possible point" is not always helpful.

    Extremes are never helpful, of course you should always use your best judgment. But the extreme of "declare all variables strictly at the latest possible point" is always better than the regularity of "declare all your variables at the top".



  • @kt_ said in The advanced concept of properties:

    It's much better when your functions are small and the declaration is close to the usage, but if your function is 100 lines long and you declare all variables at the top, then I pity the people who have to understand this code.

    Yes.



  • @kt_ I think that a lot of what you're saying is, basically, if you write clean code then the question of where you declare variables doesn't matter that much as they will naturally happen close to where they're needed. And I do agree with that, of course.

    I won't comment more on the recipe analogy, I think we're stretching it too far (<insert baking joke here>) and it's not really helpful any more...

    @kt_ said in The advanced concept of properties:

    However, when reading code it's better for stuff to appear magically. Here you're manipulating this string and now lo and behold! here you create puff! out of thin air something that could use that string.

    Well, this is where I disagree. I kind of hate stuff that magically pops up in the middle of the code. When I read some code, I first skim it to get an idea of what's happening in the various bits, and knowing that something will happen later helps me a lot understanding what we're doing first. Why are you manipulating that string? What characteristic of that string do I need to worry about? For example if you're parsing that string and happen to use a regexp (yeah I know, then you have 2 problems), having a variable related to that declared before might help me understand that code without having to try and understand the regexp right now. If I see, I don't know, three variables day, month, year before a block that gets the string and parses it with a regexp, I know what this string-manipulation is about without having to look into the details (and I also know that the developer was :doing_it_wrong: and what I will post next here, of course).

    Of course, in a perfect world you have comments, well-named functions and so on and this isn't really needed. But in a perfect world there are also no bugs in the code and no ones uses regexps to parse dates, and TDWTF has no reason to exist, so really, that would be a sad world.

    Wouldn't it be better to do:

    var range = CreateRange(params)

    In CreateRange:

    And this is where I also disagrees, and the source for my other tongue-in-cheek comment about preferring one 500 lines function rather than 500 one line functions. If the only place in the code where you ever call this CreateRange() is here, I hate having it in a separate function. Because it breaks my reading flow, and because it forces me to assume that the CreateRange() function does what I think it does, and because I can't check easily whether edge cases are handled like I think they are (such as, what is the range if params is empty? if it contains null values or NaN? does it assume anything about the signedness, order, ... of params?).

    So I hate having tiny functions thrown around for trivial operations, and I'd rather have a couple more variable declarations before a block to kind of warn me that "this block is going to compute these 2-3 variables, it could be in a separate function but that would be pointless".

    My main rule when writing code is to make it so that it is easy to read. For me, all stylistic rules are just declinations of that single one (and yes, even performance is a secondary concern -- in the very large majority of cases, this isn't that much an issue, at least at the lower level of the order in which 2 lines of code should be written. Of course, at the scale of the design of a whole system/complex algorithm, that's different).

    Declaring too far from use makes it harder to read, because 1) I wonder when I see the declaration what it will be about and 2) by the time I come to its actual use I have forgotten what it was. Huge functions makes it harder to read, for the same reason. Tiny functions makes it harder to read because they require skipping to other bits of code or assuming a lot of things about what they really do. Always declaring strictly at the latest point makes it harder because it sometimes hides the bird's eye view in favour of the extreme close-up only. So yeah, it's all about finding a balance...

    Extremes are never helpful, of course you should always use your best judgment. But the extreme of "declare all variables strictly at the latest possible point" is always better than the regularity of "declare all your variables at the top".

    Oh, yes, if that's the point that you want to make, I agree. My rule is to declare as close as possible, but not to make it a cardinal rule that can't ever be broken.


  • Discourse touched me in a no-no place

    @yamikuronue said in The advanced concept of properties:

    My coworker told me yesterday that "C++ hasn't changed a lot since you were 12". I told him I keep hearing it has >.>

    Ask him what auto does these days :imp:


  • Discourse touched me in a no-no place

    @kt_ said in The advanced concept of properties:

    @remi said in The advanced concept of properties:

    @kt_ said in The advanced concept of properties:

    @boomzilla said in The advanced concept of properties:

    @remi There is a certain cleanliness of keeping all of your declarations in one place

    But it doesn't make sense. The kinds of instructions that do list all of the prerequisites at the top are those instructions where you (i.e. The person) need to collect all of the materials. Recipes, woodworking instructions. But here you are the reader, not the preparer.

    I disagree. You are the one preparing the understanding of the code (when you read it, obviously not when you write it...), and knowing the "ingredients" in advance can help understanding what some code is for.

    I knew you'd go this way. But I don't think you are right here. The fact that gore declaring a bunch of ints and strings doesn't say a lot and even if they're named well, this doesn't really prepare me for what's gonna happen. The function's name should, but not seeing a bunch of variables there.

    It's easier to understand what's happening when you see stuff being used, not when you see a bunch of stuff lying around.

    Case in point from something I've had cause to mess around with recently:

    static int snmp_considerVLAN(accesspoint_t* ap, const configInfo_t *ci){
    	const int *classarray = 0;
    	int lastitem = 0;
    	int currentVLAN, intendedVLAN;
    	size_t f;
    	int found;
    	struct variable_list* v=0;
    	char sa_tmp[INET_ADDRSTRLEN];
    	struct snmp_device_template* d = &ap->snmp_device;
    ...
    


  • @remi said in The advanced concept of properties:

    If the only place in the code where you ever call this CreateRange() is here, I hate having it in a separate function. Because it breaks my reading flow, and because it forces me to assume that the CreateRange() function does what I think it does, and because I can't check easily whether edge cases are handled like I think they are (such as, what is the range if params is empty? if it contains null values or NaN? does it assume anything about the signedness, order, ... of params?).

    So I hate having tiny functions thrown around for trivial operations, and I'd rather have a couple more variable declarations before a block to kind of warn me that "this block is going to compute these 2-3 variables, it could be in a separate function but that would be pointless".

    Hmm...here's a situation I had yesterday:

    private boolean okFoo( FrobnicatedWTF wtf ){
    	return fooFilter == null || fooFilter.equals( wtf.getFoo() );
    }
    
    private boolean okBar( FrobnicatedWTF wtf ){
    	return barFilter == null || barFilter.equals( wtf.getBarName() );
    }
    
    public void filterWTFs(){
    	filteredWTFs.clear();
    	for( FrobnicatedWTF wtf : wtfs ){
    		if( okFoo( wtf ) && okBar( wtf ) ){
    			filteredWTFs.add( wtf );
    		}
    	}
    }
    

    Even though the conditions are relatively simple, it made the code much cleaner to refactor them out as their own methods which are only ever called from that one place. Not that I completely disagree with your post, but like so many things there are good exceptions.



  • @boomzilla said in The advanced concept of properties:

    Even though the conditions are relatively simple, it made the code much cleaner to refactor them out as their own methods which are only ever called from that one place. Not that I completely disagree with your post, but like so many things there are good exceptions.

    That makes sense. Let's say that, like the rule to put declarations as close from use as possible, my rule to not make useless tiny functions has some exceptions.
    0_1503661238274_dc7e4f82-ff72-4407-a606-984ae7be9def-image.png


  • BINNED

    @yamikuronue said in The advanced concept of properties:

    @raceprouk The sticking point here was "a lot", obviously. I told him it was my understanding that C++11 in particular brought big changes, but I wasn't sure exactly what. We both conceded it didn't matter because we don't want to write C++ at work anyway.

    Dunno, I guess it's what you do with it. For me, my coding style changed a lot in certain areas since C++11. Since the service I spend most of my C++ coding on needs to frequently iterate over a bunch of data new for loop semantics and ability to use closures really made my code tidier and easier to follow. I actually went back and rewrote probably 90% of all loops in the code as soon as I could safely use C++11 for it.


  • Discourse touched me in a no-no place

    @remi said in The advanced concept of properties:

    Let's say that, like the rule to put declarations as close from use as possible, my rule to not make useless tiny functions has some exceptions.
    0_1503661238274_dc7e4f82-ff72-4407-a606-984ae7be9def-image.png

    It's better to make sure your functions are well named, with a clear purpose, and sensibly-chosen arguments that match the requirements of that purpose, than it is to hold over-much to some ideal of what length a function should be, for good names and purposes make use of that function much easier, whereas being short (or not) merely changes the load for the people who are reading the function, and it'd be good to keep that number as small as reasonably possible. Of course, what counts as short depends on what you're doing. Some languages are more verbose. Some application areas are more verbose, requiring more code simply because there's more that has to be specified (even if it is simple to do so).

    Bah! I usually describe this stuff as “having good taste in functions” as that covers the need for flexibility pretty well. It's either that or starting to blather on about optimisation tensors in a high-dimensionality metric space, and that's where I usually lose people. :laughing:


  • Impossible Mission Players - A

    @dkf said in The advanced concept of properties:

    make sure your functions are well named, with a clear purpose, and sensibly-chosen arguments that match the requirements of that purpose,

    I give to you MakeSureAzureMVcountsAreGood no parameters.


  • Dupa

    @remi said in The advanced concept of properties:

    @kt_ I think that a lot of what you're saying is, basically, if you write clean code then the question of where you declare variables doesn't matter that much as they will naturally happen close to where they're needed. And I do agree with that, of course.

    I won't comment more on the recipe analogy, I think we're stretching it too far (<insert baking joke here>) and it's not really helpful any more...

    Yeah, we should've gone the car analogy way! :smile:

    @kt_ said in The advanced concept of properties:

    However, when reading code it's better for stuff to appear magically. Here you're manipulating this string and now lo and behold! here you create puff! out of thin air something that could use that string.

    Well, this is where I disagree. I kind of hate stuff that magically pops up in the middle of the code. When I read some code, I first skim it to get an idea of what's happening in the various bits, and knowing that something will happen later helps me a lot understanding what we're doing first. Why are you manipulating that string? What characteristic of that string do I need to worry about? For example if you're parsing that string and happen to use a regexp (yeah I know, then you have 2 problems), having a variable related to that declared before might help me understand that code without having to try and understand the regexp right now. If I see, I don't know, three variables day, month, year before a block that gets the string and parses it with a regexp, I know what this string-manipulation is about without having to look into the details (and I also know that the developer was :doing_it_wrong: and what I will post next here, of course).

    I'm not really sure I follow you here. I'm feeling like what you mean is you'd prefer this:

    var regexQuery = "^[0-9]$";
    var regex = new Regex(regexQuery);
    var matches = regex.Matches(fileContents);
    

    Over:

    var matches = new Regex( "^[0-9]$").Matches(fileContents);
    

    If so, I'm feeling that we're violently agreeing.

    What I actually mean is:

    var url = "http://google.com";
    var contents = new WebClient().DownloadString(url);
    
    var regexQuery = "^[0-9]$";
    var regex = new Regex(regexQuery);
    var matches = regex.Matches(contents );
    

    Over:

    String url;
    string regexQuery;
    Regex regex;
    String contents;
    Matches matches;
    
    regexQuery = ^[0-9]$";
    regex = new Regex(regexQuery);
    url = "http://google.com";
    contents = new WebClient().DownloadString(url);
    matches = regex.Matches(contents);
    

    This is a simple example, but imagine there were many variables in a larger method

    Of course, in a perfect world you have comments, well-named functions and so on and this isn't really needed. But in a perfect world there are also no bugs in the code and no ones uses regexps to parse dates, and TDWTF has no reason to exist, so really, that would be a sad world.

    QFT

    Wouldn't it be better to do:

    var range = CreateRange(params)

    In CreateRange:

    And this is where I also disagrees, and the source for my other tongue-in-cheek comment about preferring one 500 lines function rather than 500 one line functions. If the only place in the code where you ever call this CreateRange() is here, I hate having it in a separate function. Because it breaks my reading flow, and because it forces me to assume that the CreateRange() function does what I think it does, and because I can't check easily whether edge cases are handled like I think they are (such as, what is the range if params is empty? if it contains null values or NaN? does it assume anything about the signedness, order, ... of params?).

    Well, I can't really agree with you here. I really like those small few lines long functions. First of all, they have names. Function names are better than comments. Comments age really bad, function names are definitely better maintained.

    Second of all, you shouldn't really care about the HOW, when looking at what the public function does. You might want to at a later date, but at the first look what's important is WHAT.

    Furthermore, they do one thing. This one thing should be done correctly, with edge-cases taken care of. When you're reading a body of a method, you don't need to know how it handles what it does straightaway. Again, you need to know WHAT it does and only after that: HOW.

    Small functions allow you to separate different levels of abstractions. This is hard to read, you need to switch between different levels of code multiple times:

    var url = "http://google.com";
    var contents = new WebClient().DownloadString(url);
    var myStuff = ParseContents(contents);
    var myLargerStuff = new MyLargerStuff { CreatedOn = DateTime.UtcNow, MyStuff = mystuff };
    PushStuff(myLargerStuff);
    

    You jump from nitty-gritty url and webclient to serious shit like parsing to object creation to abstracted away PushStuff. This is easier:

    var contents = DownloadWebsiteContents(url);
    var myStuff = ParseContents(contents);
    PushStuff(myStuff);
    

    Also, if you follow the rule that code should read like a newspaper: starting with the most important (top-level) things and then going deeper and deeper as you go down, it reads really well. Usually this means that the functions you call are right there, visible on your screen already.


    Of course I can't take credit for the above ideas. These are Uncle Bob's rules, I just happen to really like them.

    Take a look at this class:

    (Highly anonymized, I hope!)

    I know, it's not perfect, a lot going on there, but the way the methods are: short and sweet with pretty good naming. Of course, you won't really be able to appreciate that, because lack of domain knowledge (unfortunately!), but at least you should be able to appreciate that it's pretty clear what's happening and when reading a function you can easily see the full body of all of the methods it calls.

    As for the rest of your post, 100% agreed. :slight_smile:


Log in to reply
 

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.