Stack Overflow make us lazy

Arseni Mourzenko
Founder and lead developer
177
articles
February 24, 2015
Tags: rant 34 stack-exchange 4 short 50

It is com­mon to think that the pur­pose of Stack Over­flow is to make the world bet­ter, and it does, some­how. I think that it in­creased the over­all qual­i­ty of de­vel­op­er-ori­ent­ed re­sources, pro­vid­ed a struc­tured way to look for help and doc­u­ment cer­tain as­pects of pro­gram­ming lan­guages, frame­works and li­braries, and got rid of fo­rums. This is the good part.

The bad part is that it en­cour­ages lazi­ness and the lack of ba­sic rea­son­ing.

Here's a ba­sic ex­am­ple. I was work­ing on a Python pro­ject where I need­ed to check whether at least one el­e­ment with­in a set of el­e­ments has a prop­er­ty equal to a giv­en val­ue. The ac­tu­al code would be too dif­fi­cult to ex­plain, so let's con­sid­er the fol­low­ing imag­i­nary sit­u­a­tion: prod­ucts are loaded from the data­base, and we should check whether there is a prod­uct with a spe­cif­ic iden­ti­fi­er.

Two pos­si­ble al­ter­na­tives are the one which uses list com­pre­hen­sions:

if product_id in [c["id"] for c in self.data.load_products()]:
    # Do something

and the one with gen­er­a­tor ex­pres­sions (no­tice the paren­the­ses in­stead of square brack­ets):

if product_id in (c["id"] for c in self.data.load_products()):
    # Do something

The ques­tion I was ask­ing my­self is whether I should use the sec­ond al­ter­na­tive, that is whether gen­er­a­tor ex­pres­sion would short-cir­cuit in a pres­ence of an in. While I know that it would in C#, I wasn't sure if the same log­ic ap­plies to Python as well.

Do­ing the right thing

The ques­tion is not that hard. In fact, it is el­e­men­tary to an­swer, and it took me 3 min­utes and 40 sec­onds:

  1. Open two ter­mi­nals.

  2. Type vi lazy.py in the first one.

  3. Type the fol­low­ing code:

    def get_values():
        values = [1, 5, 7, 7, 9, 2, 6]
        for value in values:
            print("    Yielding %s." % (value,))
            yield value
    
    print("Demo 1:")
    if 10 in [c + 1 for c in get_values()]:
        print("Found a match.")
    
    print("Demo 2:")
    if 10 in (c + 1 for c in get_values()):
        print("Found a match.")
    
  4. Switch to the sec­ond ter­mi­nal and type python3 lazy.py, which re­sults in the fol­low­ing out­put:

    Demo 1:
        Yielding 1.
        Yielding 5.
        Yielding 7.
        Yielding 7.
        Yielding 9.
        Yielding 2.
        Yielding 6.
    Found a match.
    Demo 2:
        Yielding 1.
        Yielding 5.
        Yielding 7.
        Yielding 7.
        Yielding 9.
    Found a match.
    

I now have the de­fin­i­tive an­swer.

Do­ing the Stack Over­flow thing

An­oth­er way to get an an­swer is to post a ques­tion on Stack Over­flow. That's what I did as an ex­per­i­ment. Sur­pris­ing­ly, it takes much longer, that is nine min­utes and ten sec­onds to post the ques­tion, and an­oth­er four min­utes to get an an­swer.

This is ex­treme­ly prob­lem­at­ic. The whole Stack Over­flow sys­tem en­cour­ages such ques­tions. Not ex­plic­it­ly, but still. With­in min­utes, I re­ceived two up­votes. Why?! This is a “I don't want to think by my­self,” bor­ing ques­tion which shows no re­search ef­fort what­so­ev­er. How could it be up­vot­ed?! And still, it is, be­cause of its good shape rather than its in­her­ent qual­i­ties.

The first post­ed an­swer is straight­for­ward: the sec­ond piece of code makes it pos­si­ble to short-cir­cuit the eval­u­a­tion. Great. This an­swers the ques­tion, and is the only thing that I, as a naive per­son ask­ing the ques­tion, would prob­a­bly want to know.

But here re­sides the prob­lem. While Stack Over­flow is a Q&A web­site, it is not a web­site which en­cour­ages learn­ing and think­ing, at least not in per­sons ask­ing ques­tions. What could an an­swer which in­vites think­ing look like? Well, there are sev­er­al points it may con­tain:

  1. Most im­por­tant: the sug­ges­tion to find the so­lu­tion your­self. Not nec­es­sar­i­ly in a mean way, but, for in­stance, by show­ing how the au­thor of the ques­tion could find the so­lu­tion by his own.

  2. The ex­pla­na­tion of what hap­pens un­der the hood. While I in­clud­ed enough in­for­ma­tion in my ques­tion to show that I know the right ter­mi­nol­o­gy, I wasn't show­ing that I un­der­stand how it works.

  3. The re­view of the code it­self. Se­ri­ous­ly, I copy-paste a piece of code where I load every prod­uct from the data­base to check whether a prod­uct iden­ti­fi­er is in use, and no­body makes a re­mark about how wrong this is?

    I could be a be­gin­ner who doesn't know that load­ing data from the data­base and then fil­ter­ing it is ter­ri­ble. I could be ig­no­rant of caching as well.

    I mean, the idea of load­ing all the prod­ucts and search­ing for the iden­ti­fi­er (which is by the way prob­a­bly the pri­ma­ry key, which means that it is in­dexed) is so ter­ri­ble that it should catch an eye of every de­vel­op­er who is in­volved in code re­views. This is like con­cate­nat­ing strings to build an SQL query. The only pos­si­ble re­sponse is: “Stop! Lis­ten, you are do­ing it com­plete­ly wrong. This is what you should do in­stead.”

Why is this hap­pen­ing?

The cor­re­la­tion of mu­tu­al in­ter­ests makes such sit­u­a­tions pos­si­ble. The goal of Stack Over­flow is to catch as many users as pos­si­ble through Google. My ques­tion prob­a­bly con­tributes to that. The goal of an imag­i­nary per­son ask­ing a ques­tion like this is to get a straight an­swer. This need is ful­filled. The goal of the per­son an­swer­ing the ques­tion is to re­ceive up­votes and to have a sense of ac­com­plish­ment by know­ing that the an­swer was help­ful. A short, straight an­swer does the trick.

But this cor­re­la­tion doesn't make the world bet­ter. If I was an in­ex­pe­ri­enced pro­gram­mer, I couldn't pos­si­bly guess from my Stack Over­flow ex­pe­ri­ence that I could have found the an­swer much faster by be­ing on my own. Nei­ther could I guess that my piece of code has a huge is­sue in it, and that I should be learn­ing how to use data­bas­es prop­er­ly. While every­body—the per­son who asked and the per­son who an­swered—has a sense of ac­com­plish­ment, the world be­came slight­ly worse by en­cour­ag­ing a bad be­hav­ior from a bad pro­gram­mer post­ing a bad ques­tion.

This is es­sen­tial­ly why it is so im­por­tant to have a men­tor and to have code re­views. Men­tors or code re­view­ers don't give straight an­swers; in­stead, they are ex­pect­ing you to im­prove, to grow, to learn some­thing.