[HN Gopher] -2000 Lines of Code
___________________________________________________________________
-2000 Lines of Code
Author : pcr910303
Score : 394 points
Date : 2021-03-08 16:07 UTC (6 hours ago)
(HTM) web link (www.folklore.org)
(TXT) w3m dump (www.folklore.org)
| methyl wrote:
| If you want to read about flawed metrics, how they affect the
| production and what to do about it in a form of interesting novel
| - check out The Goal by Elijjahu M. Goldratt. It's a classic, but
| gets recommended seldom for how good it is.
| meepmorp wrote:
| There are some fascinating stories on the site, including some
| ones about Bill Atkinson (the programmer here) that really help
| to flesh out the sheer absurdity of asking him, in particular, to
| fill out a sheet like that. I believe he personally wrote
| something like 2/3 of the original Macintosh ROM.
|
| edit: here's one that I find to be an interesting character
| study:
| https://www.folklore.org/StoryView.py?story=Round_Rects_Are_...
| Twirrim wrote:
| Years ago I worked for an ISP & managed hosting company as third
| line support. 1st and 2nd line support were pretty good, and
| would handle a lot of the cases that came through.
|
| Generally by the time it'd reach us, it was something requiring
| more in depth troubleshooting.
|
| They introduced a metric to measure ticket performance. The rough
| idea was "faster it's resolved, the better" (reasonable measure,
| if you're also tracking customer satisfaction), combined with
| "fewer interactions with customer the better" which was an
| absolutely stupid way to measure performance.
|
| About a month after it came out, we were getting chewed out for
| our "conversion score" being low. Too many interactions with
| customers, and tickets taking a while to handle. No shit, we're
| the top tier of support. If it got to us it was _bound_ to take
| time to resolve, and almost certainly involved a lot of customer
| interaction.
|
| One of the engineers in the team managed to dig up how to get a
| "conversion" rate report up for any support engineer, though not
| the code that generated the figures, and very quickly realised
| that the way to get 100% conversion rate was just to resolve and
| immediately re-open the ticket as soon as you picked it up. We
| all promptly started doing that, and they stopped chewing us out.
|
| If you incentivise the wrong behaviour, you're going to get
| results you likely don't want.
| sanj wrote:
| I once removed 4 lines of code.
|
| The change, annualized, was somewhere around $12M in profit.
|
| I'm still pretty proud of making -$3M/LOC!
| cbsks wrote:
| One of my most proud accomplishments was reducing the size of a
| driver from ~3000 lines of code to ~800. The file was 15 years
| old and had been modified by many people since. There were
| conditionals that were impossible to hit, features that had been
| abandoned years ago, duplicate code, and lots of comments that
| didn't match the code anymore. After my changes and a few new
| tests, the driver had full MCDC code coverage and the code
| actually matched the device specification!
| Zelphyr wrote:
| > There were conditionals that were impossible to hit
|
| The number of times I've seen: if (my_var ==
| 'some value' || true == false) { ... }
|
| Why do people do this instead of commenting out the code?!
| xdavidliu wrote:
| Just to clarify, what do you mean "instead of commenting out
| the code"? The above is equivalent to if
| (my_var == 'some value') { ... }
|
| which is not the same as commenting it out entirely.
| giomasce wrote:
| Because if you comment out the code you don't benefit any
| more from the compiler checking that the inner block is still
| legal, or from your IDE to do the refactoring operations you
| want. The code would bit rot much faster in a comment (or
| removed from the code base altogether).
|
| The thing I really can't understand is why you would compare
| a boolean condition to `true` instead of checking the
| condition itself (in other words, writing `false` instead of
| `true == false`). Also, let me suggest to use `&&`, not `||`.
| And while we're at that, I would actually write:
| if (false && my_var == 'some value') { ... }
|
| just in case operator `==` can have side effects or relevant
| computational cost in your language.
| [deleted]
| klyrs wrote:
| I have used constructs like this in debugging / exploration
| phases (especially in languages without good debuggers, when
| print debugging is unavoidable or just faster). I'd be
| horribly embarrassed if they got committed. But... the
| snippet you posted isn't equivalent to a comment; `x or
| false` is equivalent to `x`. So it's actually equivalent to a
| commented-out short-circuit if (my_var ==
| 'some value' || true == false) { ... } //if (my_var == 'some
| value') { ... } if (my_var == 'some value' ||
| true == true) { ... } //if (true) { ... } if
| (my_var == 'some value' && true == false) { ... } //if
| (false) { ... }
|
| That said... I would never use the comparisons `true == true`
| and `true == false`... that's just silly
| drewzero1 wrote:
| > that's just silly
|
| Right? Wouldn't it be more readable to use just 'true' or
| 'false' instead of the comparisons, or is that not a
| feature in some languages? I don't understand what might be
| gained from the extra comparison, besides confusion.
|
| if (my_conditional || true) { etc }
| teolandon wrote:
| That's not equivalent to commenting out the code block, it's
| just equivalent to if (my_var == 'some
| value') { ... }
| ulucs wrote:
| Why even comment out? We have version control for a reason
| Zelphyr wrote:
| I guess I've been assuming they did that because they
| wanted to temporarily disable whatever was within the
| conditional block but, yeah, you're right. Just delete it
| if you don't want that to run. Either way, that code should
| never be committed.
| slaymaker1907 wrote:
| Version control is not immediately visible to future
| developers. You need to know that there is something to
| look for, particularly if it is a frequently changed file.
| gregmac wrote:
| Really the only time a future developer will care about
| the old code is when there's a bug in the current code.
| (Or maybe an edge case like a request to "make it work
| like it used to in v1.0").
|
| Looking at history via "blame" is useful to see why a bug
| was introduced (was it fixing another bug, and if so, is
| your fix going to break that bug again?), and how long
| it's existed for.
|
| Leaving old code commented out doesn't help either with
| of those things. Unless maybe it's accompanied by lots of
| comments and date stamps, in which case you've not only
| re-invented a very crappy, half-baked version control
| system, but also made the code hard to read and work
| with.
| JoeAltmaier wrote:
| That is a win for everybody!
|
| My similar story was removing a 10,000 line module that built
| hundreds of different packets for sending over a mailbox to a
| wifi module. Each method was almost identical, with the
| exception of building a slightly different header.
|
| I replaced it with a template that given the structure, built a
| packet to send it. Less than 1 page of code.
| jjice wrote:
| There is nothing more satisfying than refactoring code to
| something nice and condensed, but still very readable. A lot of
| my personal favorite experiences come from working with trees,
| since recursive code can be so lean and beautiful. I write a
| 5ish line function to generate a graphviz file to render by AST
| once and I still look back on that as beautiful code.
| hctaw wrote:
| The tricky side of this is languages that encourage terseness
| through "clever" syntax.
|
| But that's arguing syntax instead of principle, I think
| generally "less code" means "fewer expressions to evaluate"
| noveltyaccount wrote:
| +1 to this. Code is fundamentally harder to read than write.
| If I use clever syntax, my plain-English comments make up the
| difference for characters saved :)
| apozem wrote:
| That's awesome. Clearing out cruft without breaking anything or
| losing functionality is tricky, but man does it feel good.
| Zelphyr wrote:
| I had a manager once tell a co-worker (who is easily one of the
| best programmers I have ever worked with), "There's no way this
| can work. There's not enough code."
|
| Why we keep promoting these people into positions of management
| is beyond me.
| beaconstudios wrote:
| This take is probably going to be controversial here, but I
| suspect that most metrics don't accomplish anything beyond giving
| control freak managers a sense of control or insight.
|
| Most complex processes can't be reduced to a handful of simple
| variables - it's oversimplification at its worst. The best you
| can do is use metrics for a jumping-off point for where something
| /might/ be going wrong and thus start engaging with actual humans
| (or reading code/logs/some other source of feedback). Too often
| I've had to deal with management who go straight from metrics to
| decisions and end up making bad decisions (or wasting everyone's
| time shuffling paper to generate good looking metrics).
| munk-a wrote:
| I don't disagree that metrics can cause problems - but they
| could also helpful when working on difficult problems. I don't
| know of one that exists but there are times that a really tough
| nut lands on my desk and I can't bring back a solution for a
| few weeks A good metric would highlight the fact that, a week
| in, while I may have no solution to the problem, progress is
| being made.
|
| Right now our metric is basically - talk to the developer and
| try and see if he's BSing you and goofing off, that's super
| subjective and very vulnerable to personal biases, but, it is a
| metric - it's just not an objective metric.
|
| I don't know what it is - I've never seen evidence of a good
| one out there - but I don't begrudge managers trying to find
| new objective measures for productivity. I'd be quite excited
| to see one myself.
| beaconstudios wrote:
| The mistake is in trying to quantify a qualitative issue.
| Trying to reduce progress building a program to the number of
| lines and such. It inherently doesn't make any sense and it's
| not possible to accurately represent such things as a number
| or collection of numbers without losing all the detail (and
| thus, being wrong).
|
| The idea that only truths expressable in abstract equations
| are objective and thus true is exactly the kind of false
| belief that gets us in trouble.
|
| > Right now our metric is basically - talk to the developer
| and try and see if he's BSing you and goofing off, that's
| super subjective and very vulnerable to personal biases, but,
| it is a metric - it's just not an objective metric.
|
| That isn't a metric. Metric, having the same root as metre,
| is about measuring. What you're talking about there is a
| heuristic, and they're much more effective for tracking
| qualitative issues.
| jrochkind1 wrote:
| It gets even worse, the metric can _harm_. As suggested in the
| OP, if the number of lines of code you wrote was supposed to
| show your productivity, programmers will start optimizing for
| maximizing lines of code, which will make their code worse.
|
| Goodhart's law rephrased by Marilyn Strathern: "When a measure
| becomes a target, it ceases to be a good measure"
| https://en.wikipedia.org/wiki/Goodhart%27s_law
|
| Campbell's law: "The more any quantitative social indicator is
| used for social decision-making, the more subject it will be to
| corruption pressures and the more apt it will be to distort and
| corrupt the social processes it is intended to monitor"
| https://en.wikipedia.org/wiki/Campbell%27s_law
| beaconstudios wrote:
| Yes precisely this, because you close your feedback loop not
| over the actual result you wish to achieve, but a crude
| numerical reduction which probably won't correct your actions
| effectively (as per your example, optimising for lines
| written rather than features shipped).
| andrewflnr wrote:
| > This take is probably going to be controversial here, but...
|
| You then state what seems to be the mainstream view on HN.
| Certainly I don't see it as controversial, just kind of obvious
| beaconstudios wrote:
| I figure it to be controversial because I see the HN crowd as
| leaning more towards maths/reductionism/measuring than
| intuition/holism/feedback and while I'm specifically levying
| the anti-quantification argument against managers in this
| case it also applies to that approach in general.
| SamBam wrote:
| A large percent of HN are software developers, and no
| developer wants to be held to some metric by some non-
| developer boss.
| andrewflnr wrote:
| Yeah, but OTOH we're mostly software people who have seen
| first-hand what happens when you try to apply naive metrics
| to software. In other fields you're more likely to be
| right.
| bawolff wrote:
| I'm not sure why you would think this is controversial. Fot
| example, Goodhart's law is commonly cited around here and its
| saying roughly something similar.
| beaconstudios wrote:
| Goodharts law applies to using a metric as a target. I'm
| talking about metrics being bad for measuring because they
| inherently overgeneralise.
| AmericanChopper wrote:
| In order to get any insight into whether a chosen course of
| action is working or not, you need to be able to perform some
| type of measurement. All of these measurements are called
| metrics. The default single metric that every company has
| available to them is revenue, but really you want to have
| feedback loops that provide insight prior to performing a
| measurement to determine whether you're bankrupt or not. The
| more precisely you try to measure something, the more
| uncertainty and error you're going to introduce to your
| measurements, something that's true for all forms of empirical
| measurement.
|
| If you point was that companies are generally bad at doing
| this, or that they often measure the wrong things, or that the
| process can be abused, or that you should not attempt to
| measure something beyond a certain level of precision, then I'd
| agree with you. But to write the entire process off as useless
| is just as unproductive as the problematic situation you're
| criticizing.
| beaconstudios wrote:
| There's measurements (say, increase in customer retention as
| a % after a new feature is deployed) and then there's
| heuristics (discussing the feature with customers to gauge
| sentiment, being careful not to fall prey to bias or lead the
| customer's answers).
|
| My point is that an obsession with empiricism can make you
| think that only #1 is valid evidence and thus use it for
| qualitative analysis where it should not be used.
|
| Only using metrics for feedback is giving yourself tunnel
| vision.
| zeroxfe wrote:
| So, what would you do differently? Say you run an organization
| with 200 engineers all with different levels of skill. You have
| a budget, maybe a year of runway, and a set of deliverables.
|
| How would you, as a leader, keep track of how your organization
| is running?
| [deleted]
| beaconstudios wrote:
| By implementing a systems solution similar to Stafford Beer's
| VSM (https://en.m.wikipedia.org/wiki/Viable_system_model). Or
| to ovrrsimplify the idea, self-managing teams which integrate
| with their environment for feedback and management for
| direction (which I believe is the agile/lean practices done
| properly).
|
| The specific approach to metrics I was referencing as being
| better is known in cybernetics as an algedonic alert. It
| doesn't seek or claim to provide information, it only rings
| the bell of "investigate this area", like a CloudWatch alert
| for your organisation.
|
| Using metrics to make decisions is the mistake in my mind.
| Ma8ee wrote:
| The Streetlight effect [0]. Just because you think that it is
| the only place that you can see anything doesn't mean that it
| is meaningful to look there. A number with high precision
| doesn't mean it will tell you anything meaningful. Some
| problems just don't have any easy solutions.
|
| So in your example, you just have to rely on the judgement of
| all your professional project leaders and architects and what
| they tell you.
|
| [0] https://en.wikipedia.org/wiki/Streetlight_effect
| protomyth wrote:
| Say what you want about Steve Balmer but he had the right
| attitude towards that https://www.youtube.com/watch?v=kHI7RTKhlz0
| ChrisMarshallNY wrote:
| The best code is the code I don't write.
|
| As a manager, I would value a developer that spent a week,
| refining a small, high-quality, robust and performant class, than
| one that churned out rococo monsters in a short period of time.
|
| I tend to write a lot of code, and one of the things that I do,
| when I refactor, is look for chunks I can consolidate or remove.
|
| OO is a good way to do that. It's a shame it's so "out of
| fashion," these days. The ability to reduce ten classes into ten
| little declarations of five lines each, because I was able to
| factor out the 300 lines of common functionality, is a nice
| feeling.
|
| An interesting metric for me, is when I run cloc on my codebase.
| I tend to have about a 50/50 LoC (Lines of Code) vs. LoC (Lines
| of Comments).
| fredley wrote:
| I am a staunch code minimalist. Less code is (almost?) always
| better. The best, fastest, cleanest code is the code that doesn't
| exist at all. Always aim to write the least code. Less code is
| less maintenance, it's less to grok for the next person to read
| it.
| computerex wrote:
| I agree with this, with the side note that simple code is
| better than clever code when working with a team of people for
| most things. Barring performance constraints, I'd choose the
| code that's easier to grok/simpler even if it's more LOC.
| fredley wrote:
| Yes. Code is read many more times than it's written, so
| optimise for the common case.
| jugg1es wrote:
| I think there is a big difference between the the amount of
| code versus the number of decisions a piece of code has to
| make. When I think of 'code minimalism', I think of it along
| the lines of reducing the number of decisions made, but that
| doesn't always track with the amount of code. Bugs are always
| going to increase as the number of decisions are increased.
| [deleted]
| jackson1442 wrote:
| Exactly. You can get to the goal of less lines rather easily
| but it results in absolutely disgusting code since you're
| doing things like creating overly complex lines with nested
| ternary expressions.
|
| Easy to read code with fewer decisions should be the goal of
| a code minimalist.
| dnautics wrote:
| I don't think this is always true. For example, if you are
| writing tests, the DRY rule of three doesn't apply. It's very
| okay to repeat code if it prevents a layer of indirection for
| the person who is reading the test.
| dang wrote:
| I puzzled about that for years and concluded that tests are a
| completely different kind of system, best thought of as
| executable requirements or executable documentation. For
| tests, you don't want a well-factored graph of abstractions--
| you want a flat set of concrete examples, each as
| independently understandable as possible. Duplication
| actually helps with that, and since the tests are executable,
| the downsides of duplication don't bite as hard.
|
| A test suite with a lot of factored-out common bits makes the
| tests harder to understand. It's similar to the worked
| examples in a math textbook. If half a dozen similar examples
| factored out all the common bits (a la "now go do sub-example
| 3.3 and come back here", and so on), they would be harder to
| understand than spelling out the common steps each time. They
| would also start to use up the brain's capacity for
| abstraction, which is needed for understanding the math that
| the exercises illustrate.
|
| There are two different cognitive styles: the top-down
| abstract approach of definitions and proofs, and the bottom-
| up concrete approach of examples and specific data. The brain
| handles these differently and they complement one another
| nicely as long as you keep them distinct. Most of us secretly
| 'really' learn the abstractions via the examples. Something
| clicks in your head as you grok each example, which gives you
| a mental model for 'free', which _then_ allows you to
| understand the abstract description as you read it. Good
| tests do something like this for complex software.
|
| Years ago when I used to consult for software teams, I would
| sometimes see test systems that had been abstracted into
| monstrosities that were as complicated as the production
| systems they were trying to test, and even harder to
| understand, because they weren't the focus of anybody's main
| attention. No one really cares about it, and customers don't
| depend on it working, so it becomes a sort of twilight zone.
| Bugs in such test layers were hard to track down because no
| one was fresh on how they worked. Sometimes it would turn out
| that the production system wasn't even being tested, because
| the monster middle layer did so much magic.
|
| An example would be factory code to initialize objects for
| testing, which gradually turns into a complex network of
| different sorts of factory routines, each of which contribute
| some bit and not others. Then one day there's a problem
| because object A needs something from both factory B and
| factory C, but other bits aren't compatible, so let's make a
| stub bit instead and pass that in... All of this builds up ad
| hoc into one of those AI-generated paintings that looks sort
| of like reality but also like a nightmare or a bad
| psychedelic trip. The solution in such cases was to gradually
| dissolve the middle layer by making the tests as 'naked' as
| possible, and the best technique we had for that was to
| shamelessly duplicate whatever data and even code we needed
| to into each concrete test.
| ketamine__ wrote:
| https://mobile.twitter.com/dhh/status/1368957511118843908
|
| True?
| rkangel wrote:
| I used to think this and have come to realise that this is
| definitely not true. The problem that a thorough automated
| test suite can cause is that it becomes very painful to
| refactor code.
|
| As you add code, the best structure for that code changes and
| you want to refactor. I'm not just talking here about pulling
| some shared code into a new function, I'm talking about
| moving responsibilities between modules, changing which data
| lives in which data structures etc. These changes are the key
| to ensuring your code stays maintainable, and makes sense.
| Every unit test you add 'pins' the boundary of your module
| (or class or whatever is appropriate to your language). If
| you have lots of tests with repeated code, it can take 5
| times as long to fix the tests as it can to make the actual
| refactors. This either means that refactors are painful which
| usually means that people don't do them as readily (because
| the subconscious cost-benefit analysis is shifted).
|
| If - on the other hand - you treat your test suite as a bit
| of software to be designed and maintained like any other,
| then you improve this situation. Multiple tests hitting the
| same interface are probably doing it through a common helper
| function that you can adjust in one place, rather than in 20
| tests. Your 'fixtures' live in one place that can be updated
| and are reused in multiple places. This usually means that
| your test suite helps more with the transition too - you get
| more confidence you've refactored correctly.
|
| The other part of this problem (which is maybe more
| controversial?) is that I try not to rely too much on lots of
| unit tests, and lean more on testing sets of modules
| together. These tests prove that modules interact with each
| other correctly (which unit tests do not), and are also
| changed less when you refactor (and give confidence you
| didn't break anything when you refactor).
| sneak wrote:
| I used to have this approach, but when you start to take deps
| into account, it is often preferable to have a medium amount of
| code in your own codebase (that eliminates some bulky deps) to
| a small, fast, clean/easy to read in full codebase that depends
| on some large external libraries that bloat the overall size of
| "lines of code in use in this application".
|
| Now I am a dependency minimalist (as much as is practical, it's
| a continuous gradient trade-off and naturally YMMV) more than I
| am a pure code-written-here minimalist.
|
| I'll happily double my SLOC for most small apps if it means my
| app can be stdlib only.
| fredley wrote:
| Yes, fully agree. The only thing worse than code you have
| written is code you haven't.
| folkrav wrote:
| To a point. Some things are complex enough that relying on
| a well tested and supported third-party makes way more
| sense than re-inventing the wheel.
| colejohnson66 wrote:
| I think a great example of that is GUI toolkits. If your
| program is supposed to be cross platform, using something
| like Qt, GTK, wxWidgets, etc. is generally preferred to
| writing your own GUI code.
| srgpqt wrote:
| Those GUI toolkits only look and behave acceptably on
| linux, because every other linux app uses those toolkits.
| They look horrible and incredibly jarring on windows and
| mac.
|
| Can still be fine for opensource/hobby work, anything
| professional needs better integration with the individual
| platform native UI apis.
|
| Which is one of the reasons Electron became so popular --
| nobody has any expectations from a webapp UI, yet they
| still look better than Qt/GTK/wx on average...
| Wowfunhappy wrote:
| Shouldn't you be counting the lines of code in the
| dependency?
| tyingq wrote:
| I imagine the trouble there is that you often pull in a
| library for some smallish, but suitable subset of what it
| can do.
| colejohnson66 wrote:
| A big problem with that is: what counts as a dependency? If
| I pull in Qt, am I supposed to add how many lines of code
| are in the parts I'm using? Many would say yes. But does
| using the Win32 API count? glibc? Where is the line drawn?
| toast0 wrote:
| Every piece of code you rely on is a dependency.
|
| You may not be able to count lines of win32 code, and its
| awfully hard to make a patch, but if it's broken and you
| depend on it, your product is broken.
|
| There's also a multiplier that should be attached though.
| Most products don't have developer time or skills to
| write their own OS, so there's value in using someone
| else's even if it's probably more code than a custom
| built one that only satisfies the needs of the product.
| renewiltord wrote:
| The real reason objective measures don't work is that this
| is a subjective thing. When you think about the good things
| about code (readability, maintainability, extensibility)
| they don't lend themselves to mechanical analysis.
|
| We can proxy a little but the core problem is that the
| function that spits out your metrics for those actually has
| a hidden parameter of the audience you are writing for and
| the purpose it is for.
|
| So when the audience is highly familiar with Linux (the
| kernel and platform) idioms, you could choose an exotic
| microkernel with far fewer SLOC and actually have true
| lower score.
|
| Of course that's pointlessly edge case, but the natural
| simple easier to understand version of that is just using a
| different utility library instead of the one currently used
| in the codebase. This one could be smaller by far and still
| be worse in truth.
| lstamour wrote:
| Another way of looking at it is that your dependencies are
| still part of your code and to minimize those as well. It
| can't easily be taken literally because who really wants to
| consider the Linux kernel and glibc as part of their everyday
| app dependencies unless writing code very close to the metal,
| but at the same time it can be a very useful perspective to
| have. Especially when you consider that you might (for
| security) need to code review all those dependencies as they
| change over time.
| vidarh wrote:
| A reasonable approximation, to me, is whether or not
| another developer should be expected to have at least a
| reasonable understanding of the API of that dependency.
|
| E.g. we don't generally count (g)libc because a
| C-programmer should be familiar with the C API. We don't
| count Linux syscalls for the same reason, generally. But we
| might want to keep in mind that many APIs have dark corners
| that few users of the API are aware of, and so we may make
| exceptions.
|
| But the more obscure the API, the more important it is to
| count the complexity of the dependency as well.
|
| Both because it increases the amount of code your team must
| learn to truly understand the system, and because if it is
| obscure it also reduces the chance that you can hire
| someone to compartmentalise the need for understanding that
| dependency as well.
| Havoc wrote:
| You can tell it's folklore by the part where they stop making him
| fill out the form
|
| 3/10 for realism
| mynameisash wrote:
| "It seems that perfection is attained not when there is nothing
| more to add, but when there is nothing more to remove." - Antoine
| de Saint Exupery
| noarchy wrote:
| There are still companies trying to impose metrics on software
| development. It isn't just lines of code, it may also include
| commits per day. And this isn't even taking into account various
| "Agile"-related metrics, like story points per sprint and the
| like.
|
| I wonder if we should name the companies who do this, or if it is
| fighting a losing battle? In the end, some management just wants
| to look at charts.
| Zelphyr wrote:
| One of the greats is "number of bugs fixed". You're practically
| begging your less-than-ethical programmers to create silly bugs
| so they can "fix" them and get a cookie.
|
| Edit to add: This happens outside of programming as well. I
| know a guy who worked at AT&T as a DSL Installation & Repair
| tech. They had such a focus on how long techs spent on a given
| job (less time was encouraged, more time was penalized) that a
| lot of his co-workers would go to the DSLAM and snip a wire so
| that they would be called out the next day to fix the problem.
| He pushed back so heavily on the poor incentive of "getting
| your numbers up" that he eventually got written up for
| insubordination. We need a larger eye-roll emoji.
| Jtsummers wrote:
| Of questionable ethics, at one office there was no _reward_
| for finishing a large number of tasks. But there was an
| implicit _penalty_ for delays and the tasks were not properly
| segregated by effort. One of the testers had something like
| 300-400 test cases he was automating. The majority were
| simple, minutes to an hour of work, and easily sharing common
| code. 50 or so were large, taking several days or even a
| couple weeks of effort. Even though he, technically, could
| have finished the majority of test cases in a couple weeks,
| he knew that they 'd expect that pace to continue.
| Consequently, he left all those small cases for later. It was
| simpler this way than fighting the misperception that all the
| work was of similar effort. If he ever seemed to be falling
| behind, he'd churn out 20+ test cases on Friday and the
| reports for the week looked good to management.
|
| I've never done this myself, but I've seen developers do
| similar things rather than fight management. Measuring and
| rewarding the right things is important.
| quercusa wrote:
| There's a old Dilbert to that effect. Wally: "I'm going to
| write myself a minivan!"
| einpoklum wrote:
| More than the story itself, the website:
|
| https://www.folklore.org/
|
| is packed with stories which will make you smile, cry, or more
| enlightened. Or all of the above at the same time.
| josalhor wrote:
| Just the other day I was in my logistics class and the professor
| started deviating into something that I believe was pure
| nonsense.
|
| He started the lecture by analyzing how many pieces a machine
| could manufacture per day. Fair enough. He extended the model to
| measure different ratios of capacity. Makes sense.
|
| Then he tried to extend the model to all machines, including
| humans. His example was: "How do you measure the capacity of a
| legal team?". I thought it was a trick question, so I answered
| (paraphrasing) "You can't answer that question the same way you
| answer for the machine. You can't give a single metric." He told
| me I was wrong and that the _right_ measure would be (total
| number of working hours/day).
|
| I was tempted to try to convince him otherwise. The analogy was
| deeply flawed. He certainly measured the machines in (number of
| pieces / day) but measured the legal team in (hours/day). So, in
| analyzing a machine, you take into account its efficiency, but
| you don't do the same thing for humans.
|
| I believe that is exactly the same thing that is going on in the
| post. Managers/Logistics/Economists are very susceptible to this
| kind of generalization pitfalls.
|
| Edit: Given that this answer has generated some discussion I feel
| the need to expand on it. The legal team was not expected to sell
| their services "by the hour". In fact, any discussion about how
| their services were sold was shut down by the professor. From his
| point of view, the lawyers were machines and he was asking the
| question "how much can this machine produce?"
|
| Yes, other students also suggested taking the number of billable
| hours/revenue into account, but that's not the answer the
| professor was looking for.
|
| I don't criticize whether his answer is not _technically_ right,
| but I feel it holds no real-world meaning. It was a purely
| academic question that leads nowhere instead of having a debate
| about how you measure the productivity of a group of human
| beings. And on top of that, his final answer was definitive and
| (from his point of view) was irrefutable.
| rebuilder wrote:
| Well, lawyers are famously expensive. And time is money. So
| presumably a sufficiently expensive legal team will actually
| produce hours, and the measurement is perfectly reasonable.
| [deleted]
| program_whiz wrote:
| There's a simple mathematical argument to thwart your prof.
| Imagine an equation of two or more variables (such as
| "capacity"). For example the "capacity" of a storage unit is an
| equation relating height, width, and depth to volume (3
| independent variables).
|
| Any such equation can only be represented by a single number
| ("capacity" or "productivity") if all variables are dependent
| (and therefore, there is only one independent variable in the
| equation).
|
| So the assertion your professor is making is that the
| "capacity" of a team is always exactly dependent on hours
| worked per day, and any other proposed dimension of capacity
| (such as years experience, field of study, languages spoken,
| cases won, relationships with judges) are dependent on "hours
| worked per day". If he agrees any one of those variables
| affects capacity, but does not depend on "hours worked per
| day", then a single number can never reduce the dimensionality
| of the output (you need at minimum 2 numbers to represent two
| independent variables, you can never "collapse" the data).
| thaumasiotes wrote:
| > Imagine an equation of two or more variables (such as
| "capacity"). For example the "capacity" of a storage unit is
| an equation relating height, width, and depth to volume (3
| independent variables).
|
| > Any such equation can only be represented by a single
| number ("capacity" or "productivity") if all variables are
| dependent (and therefore, there is only one independent
| variable in the equation).
|
| This doesn't seem right. You can have storage units with
| varied combinations of height, width, and depth, sure. But
| whether that matters depends on what you want to use them to
| store. An example of an approach that doesn't work would be
| storing unboxed fragile antique dollhouses. They have weird
| shapes, so you can't fill the floor area, and you can't stack
| them, so adding height to the storage unit doesn't add any
| capacity.
|
| Except that of course you wouldn't just toss them into a
| garage and call it a day. (They'd break!) You'd keep them in
| boxes. Those pack and stack perfectly. Suddenly volume is
| what matters again, and increasing the width, length, or
| height of the unit by 10% will increase the amount you can
| store by about 10%.
|
| This is even more obvious if you're storing water or oxygen.
| Fluids take the shape you give them. Your unit might have
| length, width, and height (though it really shouldn't... you
| want to store fluids in cylinders), but the only thing that
| matters for how much water you can put in there is volume.
| Retric wrote:
| The Knapsack problem is arguably a counter argument to
| measuring storage space by volume.
|
| However, air freight is a much more direct one. You have 2
| largely independent measurements for weight and volume with
| either being the limiting metric for each load.
| thaumasiotes wrote:
| Yes, in air freight weight and volume are independently
| significant.
|
| But the point of my comment is that it isn't true that --
| as the parent comment asserted -- it is impossible to
| usefully report multidimensional data with a one-
| dimensional value. To the contrary, it is quite possible
| that the multidimensional data adds zero value over the
| one-dimensional summary.
| Akronymus wrote:
| If you can barely store a box in a storage slot, increasing
| the space doesn't allow you to store more boxes.
|
| You can't really assume a 100% packing rate along with
| increasing x dimension by y% meaning you can store y% more
| stuff
| thaumasiotes wrote:
| You can as long as the size of your box is significantly
| smaller than the size of your warehouse. This is in fact
| the general case.
|
| It's even truer if you're considering larger expansions;
| increasing the length of your warehouse by 200% will mean
| you can store 200% more stuff regardless of how awkward
| the original fit was.
| Viliam1234 wrote:
| how many pieces a machine can manufacture = output
|
| working hours = input
|
| Would the professor be okay to pay me for the time I spend
| reading web? I mean, from his perspective, it is the time I
| spend that is important, not what I do.
| lmilcin wrote:
| There is certain need for people to be able to simplify
| problems in terms that they can understand an manage.
|
| This is necessary, because humans have very limited capacity to
| understand world around them and otherwise it would not be
| possible to make _informed_ decisions, as gathering all
| relevant information would necessarily take practically
| infinite amount of time.
|
| From that point of view I understand people like your professor
| is mostly result of bias also called Dunning Kruger effect.
| This is basically lack of education in a given area. You need
| at least some knowledge in an area to be able to appreciate
| complexity and unknown unknowns.
|
| If you don't want to be that guy, the best medicine is first to
| learn to be self aware, second to be aware of various biases
| (including Dunning Kruger effect) that you are subject to and
| third to get some knowledge/experience in an area you are
| trying to make decisions in.
| ulucs wrote:
| The underlying question is: what is the firm's utility from the
| lawyers? If the firm is not doing anything themselves but
| outsourcing the team, person-hours is the correct answer.
|
| If the team is doing work for the firm, but you don't want to
| complicate the model, you can stick a labor-enhancing constant
| (to allow for heterogeneity between workers) and use "work" as
| a unit. Sure this model is wrong, but all models are wrong.
| We're just trying to create some useful ones.
| program_whiz wrote:
| See my response above, but this suffers the same problem.
| Economics people talk about "utility" as a single number,
| when in reality its a multi-dimensional (perhaps infinitely
| dimensional) number. Because it depends on a multitude of
| independent variables (age, health, experience, intelligence,
| expertise, efficiency, relationships, persausion / charisma,
| etc.), it can never be simplified. This also makes it
| impossible to compare two utility values, because there's no
| way to strictly order variables in many dimensions (without
| arbitrary reduction in complexity that loses information like
| calling "cost" or "hours worked" the primary axis and sorting
| on that).
| ulucs wrote:
| You're right that the map is not the territory, but it
| doesn't change the fact that you need a map to navigate. No
| science is comprehensive enough to fully model the
| territory (even physics)
| kortex wrote:
| Turns out, machines also have some sort of duty cycle. Most
| mechanical contraptions can run faster than spec, at the
| expense of wear, heat, jams, and ruined parts. So you can't
| even measure machines in widgets/hour without more info.
| 908B64B197 wrote:
| Really curious what school is this?
|
| > Edit: Given that this answer has generated some discussion I
| feel the need to expand on it. The legal team was not expected
| to sell their services "by the hour". In fact, any discussion
| about how their services were sold was shut down by the
| professor. From his point of view, the lawyers were machines
| and he was asking the question "how much can this machine
| produce?"
|
| Pricing the value of in-house counsel is an interesting problem
| in itself (because they typically don't bill by the hour). One
| could use an insurance policy pricing model (the worst that
| could happen is a very costly loss in a lawsuit) to determine
| what's the counsel protecting the company from.
| josalhor wrote:
| > Really curious what school is this?
|
| My local university. If you want the specific school, my
| handle is associated with my real-world identity. It won't be
| hard to figure out.
|
| > Pricing the value of in-house counsel is an interesting
| problem in itself (because they typically don't bill by the
| hour).
|
| Absolutely!
|
| > One could use an insurance policy pricing model (the worst
| that could happen is a very costly loss in a lawsuit) to
| determine what's the counsel protecting the company from.
|
| Also true. The lack of cost analysis in my classes worries me
| very much.
| 908B64B197 wrote:
| > Also true. The lack of cost analysis cost in my classes
| worries me very much.
|
| Time to transfer somewhere else?
| josalhor wrote:
| I am fine where I am. I will graduate next year in
| Computer Science and Bussiness Management with good
| grades. I thought about quitting and enrolling in
| Computer Science and Mathematics when I started. But I
| think I can make a bigger impact in the world by staying
| in my current program.
| mumblemumble wrote:
| Responding to your edit: It's ironic that your professor seems
| to have taken pains to rule out all of the framings that would
| render their assertion correct, in (I presume) an effort to try
| and come up with some sort of universal rule that works in any
| industry and any context.
|
| I'm pretty sure it's due to exactly that sort of hubris that
| business school folks have invited so much disdain. The domain
| in which you're operating simply cannot be dismissed as an
| inconsequential detail.
|
| Tangentially, there is a subset of law firms that do operate as
| if total hours worked is the only thing that matters. Over the
| past decade or so, they've been _rapidly_ losing ground to law
| firms that, by not thinking that way, manage to do a better job
| of producing the kinds of output that clients actually want.
| josalhor wrote:
| To be fair to my professor, the question does make sense in
| the context of the subject. That is, the subject focuses on
| answering questions like: How much I am producing? How much
| could I produce? How do I measure that? Etc. The subject
| intentionally ignores business models.
|
| So, the question "How do you measure the capacity of a legal
| team?" (note it says capacity), makes sense. It's the answer
| I disagree with.
| AlexCoventry wrote:
| But doesn't capacity imply some kind of fungible unit,
| whereas outputs of intellectual labor tend to be non-
| fungible?
| josalhor wrote:
| My professor thinks otherwise
|
| As for my personal opinion, I haven't reflected on it too
| much, but I think capacity implies a quantitative (edit:
| measurable may be a better word?) output, but not
| necessarily fungible.
| mumblemumble wrote:
| Some legal work product is reasonably fungible,
| especially at the level of corporate law.
|
| What I think that a lot of management type folks fail to
| realize, though, is that both the quality of knowledge
| workers' output and the rate at which they produce it
| tends to drop precipitously when they are tired. I
| wouldn't be at all surprised if a lawyer who works 35
| hour weeks can get more done in a given calendar period
| than one who works 90 hour weeks. Big name law firms,
| though, bill by the hour, and, even if they share this
| conviction, they know that their clients went to business
| school, and have therefore been trained not to understand
| it.
| Gibbon1 wrote:
| I can see why, my limited experience with white shoe law
| firms was they billed us 100 hours for the 10 minutes it took
| a legal secretary to do a search and replace on another
| contract they did for someone else.
| samwillis wrote:
| No, I think he is right. Assuming the aim is to optimise for
| profitability, the machines output items are chargeable but it
| is a lawyers hours that are chargeable - so optimise (and
| measure) hours!
|
| (There are obviously some "jobs" a lawyer does that tend be
| charged at a fixed rate such as conveyancing, which you would
| want to optimise for throughout)
| josalhor wrote:
| > No, I think he is right. Assuming the aim is to optimise
| for profitability, the machines output items are chargeable
| but it is a lawyers hours that are chargeable
|
| I have updated the post to expand on your observation.
| appstorelottery wrote:
| It seems to me that one measure of productivity in a law firm
| is billable hours, however in the case of a litigator - it's
| also successful case outcome. Again, it's billable hours
| towards an outcome. So I can understand this heuristic based
| approach, on the other hand it seems like you're tending
| towards the quantitative side?
|
| Generalizations or rules of thumb can actually outperform
| complex quantitative approaches to decision making. Look at the
| 1/N heuristic for portfolio management for example.
|
| Anyhow just my opinion - something for your curious mind to
| consider !
| legulere wrote:
| This way of thinking has originated with scientific management,
| also known as Taylorism.
| nickelcitymario wrote:
| You were both right, and it all depends on your definition of
| productivity. In economic terms, I believe the standard way of
| looking at this is to consider how much economic activity
| resulted.
|
| For lawyers, most of them sell hours. The more hours they bill,
| the more productive they are.
|
| Most businesses who hire programmers do not make their money by
| billing programmer hours. So that metric wouldn't work. Lines
| of code seems reasonable until you think it through. Honestly,
| I don't know that anyone has come up with a good solution for
| measuring programmer productivity.
|
| But lawyers? They're in the business of selling time in 15
| minute increments. Their productivity is simple to measure in
| this respect.
| ncallaway wrote:
| What about the general counsel of an in-house legal team?
|
| Surely they care about their underlying activities and not
| just number of legal hours worked, right?
|
| I have to believe there is a legal team somewhere in the
| world that is measured on productivity beyond just "number of
| billable hours" generated.
| nickelcitymario wrote:
| I imagine an in-house team is being paid a salary or a
| retainer, in which case their work hours are moot. (Not a
| lawyer, so I could be wrong.)
|
| I think the problem is the word "productivity". When we say
| that word, we're implicitly suggested there's a simple
| integer or decimal that can capture whether a person's
| wages are money well spent or not. For most professions,
| programming included, I am highly skeptical of the
| existence or even potential for such a number.
| tetha wrote:
| > I imagine an in-house team is being paid a salary or a
| retainer, in which case their work hours are moot
|
| I would not call it moot, but opportunity cost - and
| opportunity cost is very hard to measure. Technical debt
| is similar.
|
| If you have current lawsuites to handle and avoid cost,
| their hours are better spend doing that than dishes. If
| you have future law suites to avoid... that get's even
| more tricky.
| nickelcitymario wrote:
| I meant "moot" only in so far as it's a useful measure of
| productivity.
|
| If the hours aren't tied to either the cost or the price,
| then I don't know how they can be tied to productivity in
| an economic sense.
| ncallaway wrote:
| Sure, I wasn't disagreeing with your overall point. I was
| just pushing back on the last sentence:
|
| > But lawyers? They're in the business of selling time in
| 15 minute increments. Their productivity is simple to
| measure in this respect.
|
| I don't think all lawyers are in that business. There are
| plenty of in-house counsel that aren't in that business.
| Just as there are plenty of engineers and software
| developers that _are_ in the business of selling time in
| 15 minute increments.
|
| I just don't think the productivity question actually
| breaks down along professional lines, but rather on
| business model lines (which, again, I think we're in
| agreement about your main point)
| nickelcitymario wrote:
| I was going to say "I didn't say all", but you're right,
| I didn't qualify. I meant the majority of lawyers, which
| I think is still accurate.
|
| I also agree it doesn't break down along professional
| lines. Just used lawyers as an example, but I shoulda
| been clearer about my intent.
| ncallaway wrote:
| Ah, sure, makes sense. Lawyers do skew more into service
| providers rather than in house, so make sense as an
| example of that.
| program_whiz wrote:
| Can you represent all the values in an equation of two
| variables using only a single variable? Only if the two
| are completely dependent (and therefore its actually an
| equation of just one variable). If the 2nd variable
| contains any information, its an impossible ask (and
| therefore the worth of people can only be boiled down to
| "productivity" if literally every measurable dimension of
| worth is 100% dependent on productivity).
| planet-and-halo wrote:
| Well this gets back to the question of the output. For the
| law firm itself, this might be a valid approach. For the
| client, though, this is a terrible way to measure
| productivity. At a certain point hours may even be inversely
| proportional to productivity (assuming the client's output is
| desirable legal outcomes). This works very much the same as
| software engineering, except that usually (ignoring the case
| of consulting firms) all of the work is done in-house.
| nickelcitymario wrote:
| Completely agreed.
| PeterisP wrote:
| But the question in the grandparent post was about capacity
| - and in this regard, if some customer needs "X much" of
| legal services performed, then it's reasonable to state
| that if your legal team that can devote twice as much hours
| to that customer, it has twice as much capacity.
| JoeAltmaier wrote:
| This may explain why lawyers are motivated to stir things up,
| rather than settle them. They're motivated by the wrong
| metric.
|
| As an Engineer, I sell my time by the hour too. No different
| than the lawyer. Yet I try to finish things efficiently. Huh.
| nickelcitymario wrote:
| > As an Engineer, I sell my time by the hour too.
|
| As in you literally bill for hours, and the more hours you
| work, the more you get paid?
|
| Most programmers that I know (which is obviously not a
| great metric) either get paid a salary (which is divorced
| from actual hours worked) or they get paid by the hour but
| have no say over how many hours they will. In both cases,
| time is independent from productivity. Therefor, there's no
| harm (and really only benefits) to coding efficiently.
|
| But if you a) control how much time you work (like lawyers
| do, to an extent), and b) get paid for your time, then yes
| the incentives are setup to encourage you to be
| inefficient. Completely agreed.
| the_only_law wrote:
| I'm guessing they're an independent contractor or
| freelancer of some sort.
| JoeAltmaier wrote:
| Yup
| nickelcitymario wrote:
| And that's great! But there's a reason I used qualifiers
| like "most", not "all".
|
| If you bill by the hour, there's a reasonable (but not
| necessarily correct or optimal) case to be made for
| measuring your productivity in terms of billable hours.
|
| But it makes zero sense to do so if your hours are
| disconnected from the economic activity that results from
| your work. In such cases, it would be completely
| arbitrary to measure hours and call that a measure of
| productivity. Just as arbitrary as lines of code.
| smabie wrote:
| I'm sure lawyers think they try and settle things
| efficiently as well.
|
| The software engineering profession is riff with wasted
| work: rewrites, new bullshit services and tech, insanely
| complex clustering and cloud deployments, etc.
| wahern wrote:
| > This may explain why lawyers are motivated to stir things
| up, rather than settle them. They're motivated by the wrong
| metric
|
| Most lawyers I know have many clients and are swamped with
| work. They have little incentive to "stir things up". It's
| similar with accountants and plumbers in my city. They
| aren't trying to make more work for themselves because they
| already have their hands full.
|
| But in regional markets where supply isn't so constrained
| relative to demand then, sure, there's an incentive to
| make-work once you've wrangled a client, just as with any
| other profession.
| tibbar wrote:
| Paradoxically, if you optimize for billable hours on your
| first job, you might never get to that highly-compensated
| 100th job. A selection effect of sorts.
| frenchy wrote:
| > You were both right, and it all depends on your definition
| of productivity
|
| Sure, but at some point, you can pick a definition that is so
| far removed from what was intended, that this exercise is
| utterly meaningless.
| nickelcitymario wrote:
| > Sure, but at some point, you can pick a definition that
| is so far removed from what was intended, that this
| exercise is utterly meaningless.
|
| You could say that anytime there's any lack of clarity
| about what is meant by any given term,
|
| With "productivity", you could reasonably mean any number
| of things.
|
| It's not like someone said "pizza" and I said "that depends
| on what you mean by pizza". You _could_ say that (is a
| calzone a pizza?), but it wouldn 't be reasonable to do so.
|
| In the case of productivity, I think it's reasonable to
| clarify what is meant.
|
| P.S. Was your use of "utterly meaningless" an intentional
| pun?
| mesozoic wrote:
| The real answer is revenue generated/hour
| rkagerer wrote:
| Wow. Even with such a basic analogy, there are still more
| useful metrics you could pick... contracts closed, cases won,
| client files completed, cigars smoked.
| [deleted]
| csours wrote:
| Even in terms of widgets per hour, you need to be VERY careful
| to include measures of quality.
|
| 1 - Underlying defects will absolutely sink your downstream
| production rate.
|
| 2 - If you only measure widgets per hour, the machine will make
| more, but smaller widgets (See Soviet Nail factory story -
| https://skeptics.stackexchange.com/questions/22375/did-a-sov...
| )
|
| 3 - Quality has a quantity all it's own. Many times, better
| widgets will improve efficiency many times over their own cost
| of production.
|
| 4 - Your professor was real dumb.
| jacobwilliamroy wrote:
| Your professor clearly knows nothing about legal work. Don't
| tell him that though, you'll just piss him off.
|
| Thank him for his "wisdom" but make sure you do it in a
| convincing way. Finish the class, get your A, move on with your
| life. You don't need him to acknowledge he's wrong, you just
| need him to give you good marks.
| niccl wrote:
| This makes me think of something that's intrigued me for a
| while: what's the productivity of a yacht racer? The better
| they are, the less time they spend actually racing in
| competitions.
|
| Doesn't this mean that by your professor's metric they are
| becoming less productive?
| wiml wrote:
| I would say that a yacht racer, or other athlete's, "output"
| is their wins/ranking in competitions. There are devils in
| the details of how you assign a simple number to that, and
| Goodhart's law is always lying in wait, but that seems to be
| the right kind of thing to measure.
|
| More cynically, you could measure a racer by the amount of
| revenue generated by sponsorships, ad placement on the yacht
| hull, endorsement fees/kickbacks, etc.. If you have two
| equally competitive racers, but one is more mediagenic,
| perhaps that one has higher "productivity"? If a racer often
| loses, but does so in engaging, nailbiting ways that create a
| following, perhaps that one is "productive"? A wrestling
| "heel" may lose their bouts but be a successful character,
| say.
| jetrink wrote:
| You would be interested in Sabermetrics, which is the use of
| statistics to quantify the contribution of baseball players
| to the outcomes of the games they play in. Yacht racing is
| also a competitive team activity and you could define the
| productivity of a racer in terms of how much that person's
| efforts contributed to the position or time their yacht
| finished a race in. It's a relative measure and would have to
| be defined relative to other racers or to a fictive
| 'standard' racer.
| minitoar wrote:
| For something high risk like that it might be you only
| "produced" something if you placed.
| csours wrote:
| Disclaimer: I work for GM - this is solely my own opinion.
|
| Whenever I hear people in the automotive industry boast about the
| complexity and lines of code in vehicles I weep and shake my
| head.
| Jtsummers wrote:
| It happens in aerospace as well. I had a manager boasting,
| once, about the skill of his people and the product with
| something like, "This was 100k lines of code!". In working with
| some of those people (a couple specific individuals) later I
| realized that the 100k lines of code was probably reducible to
| 10-20k lines of code if it was anything like their later work.
| The code they wrote worked, but was not extendable or
| comprehensible by anyone but them, and I spent more time
| refactoring and shrinking their work than actually extending
| it.
| tregoning wrote:
| Related :)
| https://twitter.com/tregoning/status/1286329086176976896
| dhosek wrote:
| I track my progress on the novel I'm writing by word count. I've
| had more than a few days of negative word count writing days
| which have invariably been some of my more productive days.
| hinkley wrote:
| Sometimes I wish I kept a better count of my deletions, because
| the 'best' I ever recorded was just under 600 lines and I
| honestly feel a little regret that other people are managing much
| bigger deletions.
|
| I think the real reason is that as I moved to refactoring (as
| part of that 600 LOC experience), my deletions per year went up
| but my deletions per story regressed toward the mean.
| closeparen wrote:
| There are various ways to extract this from Git, see for
| example: https://shinglyu.com/web/2018/12/25/counting-your-
| contributi...
| dang wrote:
| If curious, past threads:
|
| _-2000 Lines of Code_ -
| https://news.ycombinator.com/item?id=10734815 - Dec 2015 (131
| comments)
|
| _-2000 lines of code_ -
| https://news.ycombinator.com/item?id=7516671 - April 2014 (139
| comments)
|
| _-2000 Lines Of Code_ -
| https://news.ycombinator.com/item?id=4040082 - May 2012 (34
| comments)
|
| _-2000 lines of code_ -
| https://news.ycombinator.com/item?id=1545452 - July 2010 (50
| comments)
|
| _-2000 Lines Of Code_ -
| https://news.ycombinator.com/item?id=1114223 - Feb 2010 (39
| comments)
|
| _-2000 Lines Of Code (metrics == bad) (1982)_ -
| https://news.ycombinator.com/item?id=1069066 - Jan 2010 (2
| comments)
| pvg wrote:
| Looks like you have a small quoting problem in the query you
| generate with the 'past' link and -2000 blows it up.
| jansan wrote:
| Was there really a 5+ year gap since the last thread? We should
| not let this happen again.
| dang wrote:
| Perhaps someone will find other cases of this story showing
| up.
| utopcell wrote:
| (-:
| taneq wrote:
| So you're saying the last thread was -2000 days from now?
| TheDudeMan wrote:
| > they stopped asking Bill to fill out the form, and he gladly
| complied.
|
| Compiled with what? Can one comply with an absence of request?
| JoeAltmaier wrote:
| Consider the cost of lines of code in a solution. Double the
| lines means double the time spent to simply type them in. Double
| the time later to read them. Probably many more times than double
| to re-understand them. Double the time to explain them. Double
| the compile time. Execution time is probably around double.
|
| It's not just twice as good to write shorter code. Its something
| like 64X as good. By some ways of thinking.
| Jtsummers wrote:
| It's definitely a compounding issue as you grow and shrink
| SLOC.
|
| One bit of code I received was somewhere in the range of 5-10k
| SLOC when handed to me. I reduced it to around 1k SLOC.
|
| The original included numerous duplications, had a function
| that was itself on the order of 1-2k SLOC, was miserable to
| extend (which path do I need to follow to insert this new
| conditional? which paths will be impacted if I remove this
| conditionals?). Fortunately it wasn't _shipped_ code, but it
| was useful for testing the embedded system.
|
| My refactoring involved, first, re-coding one of the larger,
| outer if-else-if sequences as a simple switch/case. This
| quickly revealed which variables were common to a large number
| of the branches and could be brought to a higher level of
| scope. Then common series of statements were parameterized and
| extracted to functions (preambles and postambles, setup and
| teardown, if you will). Several hundred lines were replaced
| with something like one 20-line function which took a single
| parameter and one call to it with the parameter that was
| previously evaluated through some hairy if-else-if sequence.
|
| Once completed, new test sequences could easily be coded up or
| were available because there was already a path that led to it,
| you just had to feed it a different value or series of values
| to trigger that path. Then we could automate the whole thing
| because we knew what the parameters were that clearly led to
| each branch.
|
| In the end the code was 5-10x smaller, but immensely more
| valuable.
| carapace wrote:
| > My point today is that, if we wish to count lines of code, we
| should not regard them as "lines produced" but as "lines spent":
| the current conventional wisdom is so foolish as to book that
| count on the wrong side of the ledger.
|
| ~Dijkstra (1988) "On the cruelty of really teaching computing
| science (EWD1036).
|
| https://en.wikiquote.org/wiki/Edsger_W._Dijkstra
| mangomania wrote:
| Good job!
| khaledh wrote:
| My favorite quote about this topic: Measuring
| programming progress by lines of code is like measuring aircraft
| building progress by weight. - Bill Gates
|
| My personal point of view is that: every line of code you write
| is a liability. Code is not an asset; a solved problem is.
|
| Edit: To clarify, I'm definitely not encouraging writing "clever"
| short code. Always strive to write clear code. You write it once,
| but it will be read (and potentially changed) many, many times.
| Waterluvian wrote:
| Some take "line of code" literally. Others see it as a stand-in
| for complexity. Because one can certainly make a short program
| that's far more of a liability than a long one.
|
| I'm wondering if there's a quality term for a "unit of
| complexity" in code? Like when a single line has 4 or 5 "ideas"
| in it.
| segfaultbuserr wrote:
| There are many metrics for measuring the logic complexity of
| code. An early and best-known one is _Cyclomatic Complexity_
| [0] - The more possible execution paths, the higher the
| score. You can find more at _Software Metric_ [1].
|
| [0] https://en.wikipedia.org/wiki/Cyclomatic_complexity
|
| [1] https://en.wikipedia.org/wiki/Software_metric
| LanceH wrote:
| The real measure you want is the cyclomatic complexity
| divided by the complexity required by the problem. The
| problem with line counting (or cyclo counting) is that it
| assumes a constant ratio.
| Hammershaft wrote:
| It is not trivial to understand the necessary complexity
| of a problem. In SICP, there's an early practice problem
| that asks you to turn a recursive number pattern
| generator into an iterative generator. What the problem
| doesn't tell you is that the generator obscured by
| complex recursion is actually creating a tribbonaci
| number sequence. This hidden insight turns a difficult
| problem into a trivial problem.
| LanceH wrote:
| I certainly didn't mean to imply it was trivial (or even
| possible). I'm just pointing out that assuming increasing
| LoC implies an increase in necessary complexity is just
| wrong.
| agustif wrote:
| For VS Code have used this on the past: https://marketplace
| .visualstudio.com/items?itemName=kisstkon...
|
| and this one https://marketplace.visualstudio.com/items?ite
| mName=Stepsize...
|
| These two haven't tried before but doing it now:
|
| https://marketplace.visualstudio.com/items?itemName=selcuk-
| u...
|
| https://marketplace.visualstudio.com/items?itemName=TomiTur
| t...
| Waterluvian wrote:
| Perfect. This is what I was curious about. Haven't heard of
| either. Thank you.
| gurkendoktor wrote:
| If there is a useful metric, then I haven't found it yet.
| The data on cyclomatic complexity[1] does not convince me,
| and in practice, the linters I've seen have complained
| about boring code like this: switch (foo)
| { case KIND_1: return parseObjectOfKind1();
| case KIND_2: return parseObjectOfKind2(); case
| KIND_3: return parseObjectOfKind3(); ...
| case KIND_15: return parseObjectOfKind5(); case
| KIND_16: return parseObjectOfKind16(); }
|
| There are 16 paths and yet this code is easy to follow.
| There is no substitute for human judgement (code reviews).
|
| [1] https://en.wikipedia.org/wiki/Cyclomatic_complexity#Cor
| relat...
| colonelpopcorn wrote:
| Except it's not easy to follow. Why does kind 15 return a
| parsed object of kind 5? That's not counting the
| complexity of each function called, either.
| johncolanduoni wrote:
| I think they were using the numbers as stand-ins for what
| would be in reality names be descriptive names (foo, bar,
| etc.).
| gurkendoktor wrote:
| Ouch, sorry for the typo. But I'll double down on this:
| The fact that the typo is so obvious underlines that the
| structure is easy to follow :)
| wvenable wrote:
| > case KIND_15: return parseObjectOfKind5();
|
| I don't like this type of code for exactly this reason.
| Twisol wrote:
| The association between the two has to be written
| somewhere. Can you provide an alternative approach that
| isn't vulnerable to typos?
| wvenable wrote:
| This is basic DRY violation. The number is duplicated
| twice and that can get out of sync (as in the example).
|
| I think everyone has coded this way out of expedience and
| some of us have eventually messed it up too. But you
| could, for example, use a macro in C to only list the
| number once. It might not be a trade-off worth making
| though.
|
| Personally, I've used reflection to do this kind of
| mapping of enums to functions in a language that supports
| reflection.
| Twisol wrote:
| > This is basic DRY violation. The number is duplicated
| twice 2 and that can get out of sync (as in the example).
|
| I think it's pretty clear that the number is a
| placeholder for something reasonable, e.g. making an
| association between two distinct sets of concepts. You'll
| still be vulnerable to copy-paste or typo issues.
|
| > Personally, I've used reflection
|
| Now you have _two_ problems (and still have to maintain
| an association between two sets of concepts).
| wvenable wrote:
| I don't think most enum-to-function mappings are distinct
| sets of concepts.
|
| In my own code, I have used the enum name to map to a set
| of functions related to that enum value. The association
| is implicit in the name of the enum value and the name of
| the functions. No way to mess that up like this.
|
| If it was: case: KIND_BOX: return
| parseObjectOfKindBox();
|
| It's no difference. Still repeating "Box".
| gurkendoktor wrote:
| The code was inspired by a piece of Java code that
| rendered geometric primitives. It was basically case
| "box": return parseBox(); as you suggested in your other
| post.
|
| Turning "box" into "parseBox" using string operations and
| then using reflection to call the right method is an
| approach I'd consider in Ruby, but definitely not in
| Java. It breaks IDE features like "Find Usages" and
| static analysis, and the code to dynamically invoke a
| Java method is more annoying to review than the boring
| repetition in my posted snippet.
| Jtsummers wrote:
| Their point seems to be in the mismatch of names. Imagine
| seeing this sequence, with names instead of numbers:
| switch(HTTP_METHOD) { case PUT: processPut(...);
| case POST: processPost(...); case GET:
| processDelete(...); // wtf case DELETE:
| processGet(...); // mate? }
|
| To the reader that appears to be an error even if it is
| precisely the thing you want to happen.
| Leherenn wrote:
| Depends on your language, but you could use the type
| system instead; e.g. the function is chosen by the
| compiler based on the type of the value.
|
| In more dynamic languages, you could probably use
| introspection.
|
| Lastly, this does not alleviate the association issue,
| but I prefer the alternative of declaring the
| associations in an array/map somewhere, and using
| map[enum_value]() instead of the switch.
| slaymaker1907 wrote:
| In a lot of ways, I think the map solution is actually
| worse. There isn't an easy way to figure out what code is
| used for a given enum value with the map alone. The
| searchability depends on how the map is initialized. Not
| to mention a map will always introduce null or option
| types that you have to handle.
|
| A map can be a good solution though, particularly if it's
| something like mapping enum values to strings that is
| constructed via EnumClass.values().map... or something so
| that you know the map is a total function.
| gurkendoktor wrote:
| Using a map also completely sidesteps the point of
| cyclomatic complexity because there are no code paths to
| count anymore; now they're data. And even though the
| function does the same as before, the linter will
| congratulate you on the low complexity.
| nawgz wrote:
| I mean, hilarious point, but I'm not sure it's valid.
| Clearly he's numbering things here, but I am guessing in
| the real world you're far likelier to see tests of typing
| or some not-numerically-indexed value rather than
| literally numbered ENUMs
| wvenable wrote:
| This can happen with any enum to function mapping. You
| cut and paste and forget to change one or the other.
|
| In C, you could use a macro in this call to make sure
| that the name/number is only specified once.
| nawgz wrote:
| I mean, this can happen with any code by that logic if
| you're cut and pasting.
|
| I think the real issue is types aren't included in the
| example. I work in much higher-level languages, but if
| you are passing strongly typed objects thru and your
| switch is derived on this typing, it's probably going to
| be illegal in your type system to return certain results.
|
| If your type system doesn't validate your results, then
| you'll be prone to the class of error you are discussing.
| Maybe that's common in C.
| oftenwrong wrote:
| This is one of the benefits of Cognitive Complexity:
|
| https://www.sonarsource.com/docs/CognitiveComplexity.pdf
|
| >Switches
|
| >A `switch` and all its cases combined incurs a single
| structural increment.
|
| >Under Cyclomatic Complexity, a switch is treated as an
| analog to an `if-else if` chain. That is, each `case` in
| the `switch` causes an increment because it causes a
| branch in the mathematical model of the control flow.
|
| >But from a maintainer's point of view, a switch - which
| compares a single variable to an explicitly named set of
| literal values - is much easier to understand than an
| `if-else if` chain because the latter may make any number
| of comparisons, using any number of variables and values.
|
| >In short, an `if-else if` chain must be read carefully,
| while a `switch` can often be taken in at a glance.
| slaymaker1907 wrote:
| Great paper! I particularly liked how they treat boolean
| expressions. It kind of has a mathematical justification
| as well since a series of only && or || is trivial for a
| SAT solver.
|
| I disagree with them on assuming method calls being free
| in terms of complexity. Too much abstraction makes it
| difficult to follow. I've heard of this being called
| lasagna code since it has tons of layers (unnecessary
| layers).
|
| Maybe the complexity introduced by overabstraction
| requires other tools to analyze? It's tricky to look at
| it via cylcomatic complexity or cognitive complexity
| since it is non-local by nature.
| Waterluvian wrote:
| That's what I was thinking about when I used "ideas". To
| me there's one main idea in all that code: "we are
| returning a parsed object of a kind"
|
| Not that I'm trying to sell "ideas". I don't even know.
| But it's this very loose concept that floats around my
| mind when writing code. How many ideas are there in a
| stanza? Ahh too many. I should break out one of the
| larger ideas to happen before.
| segfaultbuserr wrote:
| Speaking of measuring "ideas", the holy grail of
| complexity metric is Kolmogorov complexity -
| theoretically, the inherent complexity of a piece of data
| (including code) can be defined as the shortest possible
| program that generates it. For example, 20 million digits
| of pi or a routine that uses 20 branches to return the
| same object has low Kolmogorov complexity, because it's
| easy to write a generator for that, meanwhile a parser is
| more complex.
|
| But it's only a mathematical construction and is
| uncomputable, just like the halting problem. In real
| life, for some applications a good compression algorithm
| like LZMA is sufficient to approximate it. But I'm not
| sure if it's suitable for measuring computer programs -
| it would still have a strong correlation to the number of
| lines of code.
| nitrogen wrote:
| It kind of encourages you to use a lookup table or
| polymorphism, which isn't far off from what the compiler
| is likely to do with that switch statement.
|
| As for correlation to number of defects, another
| important factor is maintainability (velocity of new
| features in growing programs, keeping up with
| infrastructure churn in mature programs). If reducing
| perceived complexity improves maintainability, and if
| measuring cyclomatic complexity despite its flaws helps
| reduce perceived complexity, then it's still a useful
| metric.
| Waterluvian wrote:
| Feels like one of those classic, "no one tool gives you
| the one correct answer. They all give you data and you
| come to an informed conclusion having utilized one or
| many of them."
| Twirrim wrote:
| My IDE spits out a warning when I reach a certain level of
| complexity in a method, using Mccabe's Cyclomatic Complexity
| as a measure. It roughly maps with "too many if statements"
| in my case.
| khaledh wrote:
| I'm definitely not encouraging writing "clever" short code.
| Always strive to write clear code. You write it once, but it
| will be read (and potentially changed) many, many times.
|
| As for complexity metrics, this is a contentious topic. It's
| hard to quantify "ideas" or "concepts". I think this is the
| part where technical design reviews and good code reviews
| help keep in check.
| WorldMaker wrote:
| Developers have tried to build metrics for "complexity" over
| the years. Cyclomatic Complexity is often pointed to as one
| of the more successfully deployed:
| https://en.wikipedia.org/wiki/Cyclomatic_complexity
|
| As with any metric, it's something to take as useful "advice"
| and becomes a terrible burden if you are optimizing
| for/against it directly. (Such as if you are incentivized by
| a manager to play a game of hitting certain metric targets.)
|
| It's also interesting to note that a complete and accurate
| complexity metric for software is likely impossible due to it
| being an extension/corollary of the Halting Problem.
| stocknoob wrote:
| "My point today is that, if we wish to count lines of code, we
| should not regard them as "lines produced" but as "lines
| spent": the current conventional wisdom is so foolish as to
| book that count on the wrong side of the ledger." -E. Dijkstra
| jjice wrote:
| I'd expect nothing less wise from Dijkstra. I feel like every
| week I learn something new from that man.
| mumblemumble wrote:
| I prefer the Gates version. Dijkstra's implicit premise
| rather naively assumes that it is somehow less expensive to
| produce fewer lines of code. It's arguably such an absolute
| statement that it subtly encourages people to engage in
| undesirable behaviors such as playing code golf at work.
|
| Gates's, on the other hand, accurately captures the reality:
| while, all else being equal, a lighter-weight design is
| preferable to a heavier one, it takes some skill and effort
| to actually produce the lighter design. Which leaves open the
| possibility that doing so may not actually be worth the
| effort.
| msla wrote:
| The relevant metric isn't lines but concepts: Which code does
| it in the fewest new ideas? Generally, that's the best, where
| "new ideas" would be ideas new to a domain expert. For
| example, in a video game, each of the specific monster types
| is an idea someone who is an expert in that game would know.
| The ideas in the memory management code are new. You can't
| remove all code relevant to a specific monster without
| removing that monster, at which point you're no longer
| implementing the same game, but slimming down the number of
| new concepts in the memory management code is not directly
| relevant to gameplay.
|
| In short: Make program logic similar to business logic.
| [deleted]
| rakoo wrote:
| To be more precise, every line of code is debt. You get
| immediate benefits (working software) but you need to pay
| recurring obligations (bugs).
|
| Just like debt, there is a right amount to have: too much and
| you are incapacitated because you owe more than you can
| produce, too little and you don't have enough runway to produce
| what you want. Note that I'm talking about from a company's
| point of view.
| ragnese wrote:
| I agree. But, like everything, even this concept gets abused.
|
| Example: "Zero code solutions". Hell, we even had that back in
| the old days with Java frameworks doing a ton of configuration
| via XML files. Sure, it's not "code", but it's basically the
| same thing and still a liability. Especially if there's a very
| steep learning curve to all of the features/configurations that
| you'll never use.
|
| A more subtle problem with abusing this idea is the over-
| dependency on third party code. Sure, it might _look_ like you
| haven 't written any code when you do `npm install foo`, but
| really, you've just placed a bunch of trust in some other
| person. Do you vet your dependencies' authors the same way you
| vet potential employees at your company?
|
| There's a fine line and it's an art form figuring out when to
| bring in outside code or to NIH it. IMO, of course.
| richardwhiuk wrote:
| > Sure, it's not "code"
|
| I utterly reject this assertion.
| [deleted]
| mikepurvis wrote:
| I'm hitting this right now with having just inherited
| maintenance of a complicated CI pipeline with a lot of
| intermediate containers based on generated Dockerfiles, all
| of which runs by bind-mounting docker.sock-- basically stuff
| that might have been best practice 3-4 years ago, but for
| which there are absolutely better solutions now.
|
| Anyway, it's interesting evaluating those potential
| solutions, because certain things like going to a daemonless,
| rootless, bind-less build based on podman/buildah is a no-
| brainer, but the next frontier beyond that has a bunch of
| tools like ocibuilder, cekit, ansible-bender, etc which want
| to establish various ways of declaratively expressing an
| image definition, and although the intent is good there, it's
| absolutely not worth getting sucked into long-term dependence
| on pre-1.0 tools with single-digit number of contributors and
| an uncertain maintenance future.
| jaylo2015 wrote:
| Agree. But then the problem becomes how to count solved
| problems. One equally terrible practice is to count number of
| tickets solved. I found this is somewhat true in my career: bug
| fixes == job security. I cannot morally accept this but I have
| seen this again and again.
| Cd00d wrote:
| I think it's in the application for DE Shaw that you're asked
| to number the lines of code you've written in your career in
| the various languages you claim to have experience in.
| asdff wrote:
| I wonder if they then normalize this by years of experience
| klingon78 wrote:
| This is great. Another thing is that sometimes leaving things
| as-is can be better than making changes.
|
| The problem you might be avoiding is change.
|
| Things that are bad should probably be fixed, though.
| AnimalMuppet wrote:
| > My personal point of view is that: every line of code you
| write is a liability.
|
| Very true... but also false in a way.
|
| Here's a little bit of functionality that has to be in there to
| implement the way we're solving the problem. That code is a
| liability; it would be better to solve the problem in a way
| where we don't need this bit of code.
|
| But given that we're solving it this way, let's say that this
| little bit of functionality may be implemented in one line,
| which is almost unreadable, or in five very clear lines. That
| one line is far more of a liability than the five lines are.
| sdevonoes wrote:
| Nowadays that should be phrased as: fewer features is better. But
| management doesn't understand. They always want more features to
| be delivered (and faster than our competitors!), and so we end up
| with more code to maintain and in the need of hiring more
| developers (that's actually another excuse as well to migrate our
| stuff to microservices!).
|
| Companies only want to grow, they don't care anymore about
| polished products.
|
| Of course, I'm generalizing, there are some few companies that
| care about the product, but they are just a few.
| neha555 wrote:
| RSMSSB Stenographer Admit Card 2021
| https://karnatakastateopenuniversity.in/rsmssb-stenographer-...
| jansan wrote:
| Aaah, now I understand how people came up with the strange idea
| to place opening curly brackets into a new line. Suddenly this
| all makes sense.
| Scarblac wrote:
| Those few days that I managed -1000 lines of real code are among
| the happiest work-related days I had. It feels so good to find a
| simple solution that enables you to remove so much.
| lambda_obrien wrote:
| Is there anywhere which optimizes for LOC count today? I figure
| everyone knows by now LOC is a bad metric.
| Waterluvian wrote:
| Folklore.org is full of fascinating anecdotes.
|
| I'm starving for more stories of this size from CS history. PARC,
| Bell Labs, wherever! I'm sure there's thousands of fun little
| stories out there.
| everybodyknows wrote:
| The management psychology side of this wants a sequel from some
| veteran who was in the meetings and is now ready to confess:
|
| > ... wrote in the number: -2000.
|
| > I'm not sure how the managers reacted to that, but I do know
| that after a couple more weeks, they stopped asking _Bill_ to
| fill out the form, and he gladly complied.
|
| _Bill_ -- but what about the rest of the team? The devil's
| answer: They were expected to keep supplying the number, because
| line management was forwarding the stats up, having previously
| "sold" upper management on their value. And to admit error on
| such a fundamental is career-threatening.
| mshockwave wrote:
| It's crazy that even in 2021, I know some of the teams are still
| measuring productivity by LOC _only_. People just never learn the
| lesson since '80
| adolph wrote:
| Ssh, this may be a feature, not a bug.
|
| See CIA (OSS) manual for details.
|
| https://www.openculture.com/2015/12/simple-sabotage-field-ma...
| newlisper wrote:
| Use Java, problem solved.
| goostavos wrote:
| I'd be happy if lessons from the '60s-'70s(ish?) could be
| applied. Despite Mythical Man Month being 'required reading', I
| still sit in planning meetings where management discusses how
| they'll make a baby in 1 month because they're putting 9
| "resources" on it.
| segfaultbuserr wrote:
| > Measuring programming progress by lines of code is like
| measuring aircraft building progress by weight. - Bill Gates
| (alleged)
|
| According to Wikiquote there is no primary source to show he
| really said that. Nevertheless, Steve Ballmer did,
|
| > "In IBM there's a religion in software that says you have to
| count K-LOCs, and a K-LOC is a thousand line of code. How big a
| project is it? Oh, it's sort of a 10K-LOC project. This is a
| 20K-LOCer. And this is 5OK-LOCs. And IBM wanted to sort of make
| it the religion about how we got paid. How much money we made
| off OS 2, how much they did. How many K-LOCs did you do? And we
| kept trying to convince them - hey, if we have - a developer's
| got a good idea and he can get something done in 4K-LOCs
| instead of 20K-LOCs, should we make less money? Because he's
| made something smaller and faster, less KLOC. K-LOCs, K-LOCs,
| that's the methodology. Ugh anyway, that always makes my back
| just crinkle up at the thought of the whole thing."
|
| Not really a fan of either of them, but we can all agree on the
| quote.
| asdff wrote:
| Must be great for those teams. Want to make an argument for a
| raise to non-tech management? Start writing paragraph comments
| and flowery code.
___________________________________________________________________
(page generated 2021-03-08 23:00 UTC)