Google Files Bill of Costs for Oracle to Pay - $4,030,669 - <AUTHOR> http://www.groklaw.net/article.php?story=20120706111715256 <comment><USER2> The cost bill filed by Google underscores the intensity of this case and shows that we caught only _surface glimpses_ of what surely were day-to-day firefights keeping the lawyers and their minions going round-the-clock for an intense year's worth of fighting.

A "cost bill" is not a bill for the attorneys' fees incurred in a case. Under U.S. rules, the parties bear their own legal fees in most cases (and that is the case here).

But federal court rules do permit a prevailing party to recover from the losing party necessary costs incurred in dealing with document production and similar matters in the litigation. The out-of-pocket bill here (not including attorneys' fees) for Google to filter through 97 million documents and to produce just over 3 million of them after careful assessment and screening: about $2.9 million (mostly paid to electronic discovery service providers, who surely found full-time employment in this case during this past year).

The bulk of the remaining bill for costs consists of nearly $1 million paid to expert witnesses for their assistance in helping to prepare and present Google's case.

In a case like this, Google's attorneys' fees had to run at least $10 million _per month_ , at least during the intense phases of the case. I would estimate, then, that total attorneys' fees in the case _easily_ exceeded $100 million and may well have done so _for Google alone_.

Big Law may be in the doldrums today in general but a case like this clearly offers a big payday. The law firms here were all exemplary and undoubtedly earned it. Still, the cost is staggering to contemplate for the casual outside observer.

<comment><USER3> They did _not_ earn it. Lawyers charge exorbitant prices because they can -- they have you by the balls, and you don't really have an option not to pay them -- not because their services are actually worth $100 million+. I've admired your posts for years here on HN, but it's not just staggering to a "casual observer"; it's staggering to anyone with a sense of decency and propriety.

<comment><USER4> The high rates that top lawyers get paid are simply market rates. We pay them too. Cheap lawyers are not a bargain.

Decency and propriety? What do you even mean by that? That you think the proper rate for legal work should be lower than the current market rate? What basis do you have for such a claim?

<comment><USER5> >The high rates that top lawyers get paid are simply market rates

Market rates propped up by having the ability to restrict entry into the market controlled by other lawyers.

<comment><USER6> I would argue that hiring lawyers is like hiring developers in SV. There are many developers but if you want to hire A class developers, you have to pay A class rates and compete with everyone else trying to hire A class developers. Lawyers are no different. If you want to hire A class lawyers, you're going to pay A class rates.

<comment><USER3> The "A class rates" for developers rarely approach the _minimum rates_ for legal services. The highest rate I've received from a consultancy was $200/hr, and they were working in an extremely specialized area with literally the best developers money could buy -- the only fundamental builders of that technology that weren't on board at that company were those who refuse to take a job. I know that Percona lists $300/hr as their rate, and we have the same story here; extremely specialized field, developers that are and have been deeply involved in the development of the technology for most of its lifetime. Generalized high-powered development help typically maxes out in the $100-$150/hr range, at least in my experience, and even that is difficult to get outside of California.

$250+/hr is the common baseline rate in my area for real commercial legal services (that is, more than emailing a template for a contract), _not_ the "A class rate", and I would guess areas with higher cost of living are worse off. I have associates that pay $450-$500+/hr for their legal help. I know of lawyers that charge $750+/hr; that, you may say, is the "A class" rate for lawyership. Note the disparity between development consultancies and legal firms -- we max out _near a law firm's minimum rate_.

Comparison to other highly-skilled professionals, like developers, is indeed valuable, but only further demonstrates the exorbitance of legal pricing.

<comment><USER7> Programmers outright _refuse_ to organize. Lawyers, like any other _professional_ organization, are highly organized which impacts rates.

You can start coding for hire right out of high school, if you've done the right prep work. It takes ~7 years before you can start practicing law.

I would argue that at least 50% of programmers out there are not 'highly- skilled professionals,' being neither highly skilled nor professional.

<comment><USER3> This isn't relevant at the price points we're discussing. I've never known a 16-year-old to get paid $100/hr for his consulting services -- they are usually excited to take gigs at $15/hr, and the problem sets they encounter are usually tractable for their as-yet basic skill set. I can say as an individual who has made this progression from fresh-from-high-school freelancer to full-scale consultancy owner, you really hit a ceiling once you get around $50/hr. Unprofessional developers usually have significant difficulty crossing that threshold, at least in my local market, and there are not many absolutely incompetent developers floating around at higher rates. Most of our peers that can remain in that price range are at least respectably competent, even if we're still better than them.

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER8> Whatever the result, the lawyers always win.

This is pocket change for Oracle. The real set back to them is the result of the case.

And though it's good to see the aggressor in one of these lawsuits actually lose, it's saddening to think that if Oracle or a pure patent troll went after a company without 4 million to pay for a defensive suit, they would have won.

<comment><USER9> Note that this does not actually include the attorneys' fees, though.

</comment></comment><comment><USER10> When I was a kid, I read comics or heard jokes where the punchline was about everyones unanimous hatred for lawyers, I was always a bit confused.

But witnessing the last few yrs in the tech industry (in addition to politics and divorce law), it's become very apparent to me _why_ thats the case.

<comment><USER11> I still don't see how the lawyers are the bad guys here. The company knows that the country's laws might allow it to weaken the competition. It wants to avail itself of that option. The laywers are just the executors of that action, the messengers if you will.

They're certainly happy to make a buck from the process, but unless they're the ones to actually create the laws and keep them in place despite their ridiculousness, they are not exactly to blame.

<comment><USER12> > _"they are not exactly to blame."_

Oh hell naw.

If someone leaves their car unlocked sitting by the curb with the keys in the ignition, is it right to steal it? The fact that someone has (stupidly or otherwise) created a situation that is _easy_ to take advantage of in no way excuses the person that exploits it.

The fact that we have creating a patent and copyright law situation that borders on the absurd is one thing, people actively seeking to profit from this sorry state of affairs are as guilty as they come.

<comment><USER13> I think the point is that it is _Oracle_ trying to exploit the situation. Not their lawyers.

</comment></comment></comment></comment><comment><USER14> I can't imagine Oracle being too bothered by the sum itself, but it must be pretty embarrassing for them to be the aggressors in this case, and ask for billions in the beginning from Google, then to find out that they could only get like $35 million at most, even if they do win, and finally to lose the case, and themselves be the ones paying millions to Google.

</comment><comment><USER15> What are the chances that they will actually receive this?

<comment><USER16> _What are the chances that they will actually receive this?_

An order of the court will determine the final award of costs. Both sides get to argue with the court about what's a reasonable award, but the judge decides, and I can't imagine that Oracle wouldn't follow the court's order (as it can well afford to do). Probably Google is initially asking for far more than it actually expects to get after the judge reviews the bill of costs.

</comment></comment><comment><USER17> Man... I gotta get back into economic consulting... $986,978 in expert witness fees.

<comment><USER18> That's probably one percent of the total lawyering costs. Maybe get into that :P

<comment><USER17> >That's probably one percent of the total lawyering costs. Maybe get into that :P

I don't think you know how much expert witnesses charge and what they do.

</comment></comment></comment><comment><USER19> It's nice to see Oracle reinventing it self into SCO

<comment><USER20> It hasn't, though. Larry Ellison has shown time and time again that Oracle is just about the bottom dollar. SCO was just a patent troll, but in Ellison's Oracle, patent trolling/litigation is just another "wing" of the business of making big bucks. Oracle did the math and thought it would be worth the risk/investment of taking this all the way in anticipation of a possible payout on the scale of billions of dollars, and it didn't pan out. That's what makes this all the more annoying: this isn't their core business model, they're _not_ SCO, but they choose to pursue this anyway.

<comment><USER21> I don't think you know much about Oracle. Aggressively defending their assets through the courts is something Oracle has a long, long history of. Sometimes they win. Sometimes they lose. But they almost never just let things slide.

Pretty sure Larry is wearing his kimono with swords by his side when he's making the decision to "go to war".</comment></comment></comment>


The Libertarian Who Accidentally Helped Make the Case for Regulation - <AUTHOR> https://washingtonmonthly.com/magazine/april-may-june-2018/null-hypothesis/ <comment><USER2> Curious, I found the economist's (Alex Tabarrok) response to the article about himself:

[https://marginalrevolution.com/marginalrevolution/2018/04/ec...](https://marginalrevolution.com/marginalrevolution/2018/04/economic- research-biased-partisanship.html)

The concluding paragraph is important:

\----

"Let me conclude on a lighter note. There are many reasons why regulation could be costly outside of its effects on dynamism. Thus, for my friends who think that I have gone all-squishy, n.b.: 'Not that Tabarrok himself has become a booster for regulation. He doesn't think much of government's ability to spark innovation through setting standards; the first thing he did when he last bought a new shower head, he said, was remove its federally mandated flow restrictor.'"

<comment><USER3> Tabarrok's response even makes for better reading than the Washington Monthly article he replies to.

</comment></comment><comment><USER4> The dilemma is that heavy regulation tends to lend itself to monopolies and more government control which even the article admits hampers dynamism. The consequences of not following regulatory practice can be burdensome to new ideas, newcomers, and most importantly -- speed. Corporations know that federal regulations can be a tool to make it harder on its competitors. So I still think its better to err on the side of less regulation.</comment>


How We Broke Thanksgiving... and How to Fix it - <AUTHOR> http://blog.twogrand.com/2013/11/26/how-we-broke-thanksgiving-and-how-to-fix-it/

<comment><USER2> Nice.</comment>


One Idea, Zero Partners: Why Being A Solo Founder Sucks - <AUTHOR> http://founderdating.com/one-idea-zero-partners/

<comment><USER2> I'm obsessed with being the sole founder at my future company. Granted, I'm looking to create a lifestyle business, but hopefully it will all work out.

</comment><comment><USER3> There's definitely an argument for both sides. Having a cofounder to balance out the work is key but maybe it depends on the person/type of company?

</comment><comment><USER4> ITS A DECENT IF SOMEWHAT FLUFFY ARTICLE WITH AN UNFORTUNATELY ANTAGONISTIC HEADLINE. </ironic-caps>

</comment><comment><USER5> DUDE, BEING A FOUNDER SUCKS.

WHY ARE WE YELLING?</comment>


The Purity Paradox: How Tolerance and Intolerance Increase at the Same Time - <AUTHOR> https://quillette.com/2020/06/19/the-purity-paradox-how-tolerance-and-intolerance-increase-at-the-same-time/ <comment><USER2> Many years ago, as a high school sophomore, I took an elective called International Relations, taught by the social studies department chairman, a man who had a Ph.D. in political theory. I remember his hero was Hans J. Morgenthau. I did well in the class, despite the fact that I was competing mostly with seniors.

The next year I was in honors US History. The teacher of that class was good friends with the chairman of the department. The chairman told my teacher: Give Paul (my name) a C on his interim report card -- that will inspire him to work harder.

The fact is, I thought I was doing very well in that class. When I saw that C on my interim report card I was totally demotivated. When the teacher explained to me how the C was just ploy I came to an important realization: I would work much harder to maintain an A than I would to try to improve a C.

That is what I feel about the current environment. If you are white you are led to believe that you are a racist no matter what you do. Psychologically it is a bust. Black America, here is what you should do: Tell us that we've come a long way, we've given it a good faith effort -- but there are still some areas where things could be better.

<comment><USER3> In the now flagged HN post you asked about non-left example of "unilaterally remov[ing] a cultural artifact that belongs to all of society". [https://en.wikipedia.org/wiki/Emmett_Till#Historical_markers](https://en.wikipedia.org/wiki/Emmett_Till#Historical_markers) is pretty famous. Related examples are [https://www.kshb.com/news/local- news/slavery-opponent-john-b...](https://www.kshb.com/news/local-news/slavery- opponent-john-browns-statue-hit-again-by-vandals), [https://en.wikipedia.org/wiki/Levi_Harrington#Vandalism](https://en.wikipedia.org/wiki/Levi_Harrington#Vandalism) , and [https://en.wikipedia.org/wiki/Ashburn_Colored_School#Vandali...](https://en.wikipedia.org/wiki/Ashburn_Colored_School#Vandalism_incident) .

As examples matching your Margaret Sanger example, there are plenty of requests to tear down MLK, Malcom X, and Mandela statues .

For a right-wing example concerning the Troubles in Ireland, [https://en.wikipedia.org/wiki/Se%C3%A1n_Russell#Attacks_on_m...](https://en.wikipedia.org/wiki/Se%C3%A1n_Russell#Attacks_on_memorial_to_Se%C3%A1n_Russell) .</comment></comment>


Awesome Python - <AUTHOR> https://github.com/vinta/awesome-python <comment><USER2> There's lots of great stuff in the Python community, lots of very mature, high quality packages.

As with all ecosystems, there's also rubbish, and there's certainly some rubbish on this list. It would be wrong to name packages, but it makes me question "Awesome X" lists, their intentions, the skill in curation behind them, and their usefulness to newcomers.

I would personally not use inclusion on an "Awesome X" list as a signal of quality. The lists have assumed a purely discovery based role for me, which is a shame, because the idea of a curated set of packages or tools for newcomers to an ecosystem is a great one.

<comment><USER3> In my experience, Awesome lists are not often maintained and become out of date within months.

<comment><USER4> Which suggests that what we really need is a curated Awesome list of Awesome lists.

<comment><USER5> They exist. The easiest way to discover them is through a curated awesome list of awesome lists of awesome lists [0].

[0]: [https://github.com/jonatasbaldin/awesome-awesome- awesome](https://github.com/jonatasbaldin/awesome-awesome-awesome)

</comment></comment></comment></comment><comment><USER6> I'm not sure I'd call this list curated. It would be nice if it were a bit more opinionated. Where there are multiple libraries in a category it provides no guidance on how to choose one over another. Also, in some of the categories, clear winners exist today. For example in the testing category, just use pytest, and run it with tox.

I was going to submit a PR, but the repo has hundreds of PRs and 60 issues already open.

So yeah, it's more a Python smörgåsbord than a curated list. In the end, I'm not sure it's much better than using a search engine.

<comment><USER7> I think it's still a great starting point, especially, for someone who has no place to start when looking for specific libraries. It would be good to annotate with perhaps a Pros/Cons for each item in that list (pull requests, maybe?). So that you can choose whatever fits your needs.

</comment></comment><comment><USER8> 'pip' needs a download counter to feed stats necessary to generate this list automatically.

<comment><USER9> pip has a download counter.

I don't think downloads is a direct measure of good/"awesomeness"; low-level libraries that get linked in often, for example, get a higher download count for that, but might not be something often needed by an end user. (In Rust, I see the library for Aho-Corasick all the time, for example.)

In Python, I believe pyasn1 is in the top 10; but parsing raw ASN.1 is probably not something a dev should be doing that often; a higher-level library like cryptography would probably be more appropriate.

</comment></comment><comment><USER10> Looks useful but isn't 62k stars a lot?

<comment><USER11> I use Github stars to bookmark a repo I might need later. 62k is not a very big number that way I'd think.

<comment><USER10> I think the scale on which to measure the number of github stars is what quantile it lies at in the distribution of github stars across projects. I'm not sure what quantile exactly 62k is, but it's very high.</comment></comment></comment>


Ask HN: Twilio Spam Control - <AUTHOR>

I would like to hear from anyone who has experience using Twilio for a service which has high SPAM potential.
For example: Let's say I want to create an application which lets an event staff manager upload his list of available part-time employees, and then for a given event, will auto-call those folks, sequentially until he has enough people signed up for an upcoming event.
Great idea, right? But the potential for some unscrupulous person to turn this into a voice SPAM machine, violating Twilio's TOS and the law, is very high.
Maybe the issue could be solved by connecting to a no-call database API, but really Twilio says "no unsolicited calls", so that's not enough. Perhaps the only solution left is to make the price per call high enough to dissuade spammers.
I'd love to hear from anyone with direct experience in this area.
Thanks! <comment><USER2> Let's chat. We can discuss some methods to help with this email@example.com</comment>


HP weighing sale of webOS unit - <AUTHOR> http://www.reuters.com/article/2011/11/07/us-hewlettpackard-webos-idUSTRE7A66UM20111107 <comment><AUTHOR> "Oracle Corp might be among the likely technology firms interested in the asset, one of the sources said."

<comment><USER2> Christ alive, I thought HP would struggle to offload to a more stale and boring company than themselves but they might just manage to pull it off.</comment></comment>


How I automate reaching out to 1500 GitHubbers who star my web automation tool - <AUTHOR> https://medium.com/tebelorg/how-i-automate-reaching-out-to-1500-githubbers-who-starred-my-web-automation-tool-ta-gui-f2e581f7a7d3 <comment><USER2> This is not something you should be bragging about.

</comment><comment><AUTHOR> How else to reach out to users without using a 3rd-party mailing list? I wouldn't trust a 3rd-party with users' details.

I would do it manually if I could, really. But it is not humanly possible without stopping work for a couple of days on the repo.

<comment><USER3> I think you still don't understand. When people star a repository in github they don't expect to get subscribed to a mailing list. If you want to send them emails, ask them explicitly to subscribe to a mailing list.

I think you don't have bad intentions. A "thank you" email looks like a nice detail, but I would consider it borderline spam. I'd probably ignore the first one, but if I ever get a second one I'd hit the "mark as spam" button in gmail.

<comment><AUTHOR> Thanks gus_massa! I was still figuring it out. This is actually my first open- source project, and first time using GitHub.

I wasn't sure of the correct social etiquette there. Yep I made it clear that it was a one-time thank you email, and do think that it borderlines as spam.

</comment></comment></comment><comment><AUTHOR> UPDATE — since then, I have not used the flows or manually send thank you notes anymore. Better err on side of caution than risk being spammy.

</comment><comment><USER4> Spamming is really not something I'd write a proud blogpost about.</comment>


Object Oriented Programming is Inherently Harmful - <AUTHOR> http://harmful.cat-v.org/software/OO_programming/ <comment><USER2> At some point I realized I don't really need OOP itself, but I like a couple of bits it provides. Mostly:

\- The syntax. I like to be able to say thing.doSomething(). It doesn't always make sense, but sometimes subject-verb syntax is more natural than a function call.

\- Polymorphic dispatch (is that the term?) to replace if blocks. Instead of `if (thing is Car) thing.drive() else if (thing is Boat) thing.swim()` its just thing.move(). Pattern matching in functional languages solves this in a different way.

\- Interfaces are nice.

I guess I could be happy in a language that just has structs and functions, and some help in form of pattern matching, multimethods and so on.

<comment><USER3> Regarding your second point, what would be the functional equivalent?

<comment><USER4> He means pattern matching functions, which are idiomatic in Erlang but "dirty" in Haskell (where you would want to solve it better with a type class, or something else more general).

 _Erlang_

        myfun({duck, "My Duck's Name"}) ->
            dosomething;
        myfun({dog,  "My Dog's Name"})  ->
            dosomething;
        myfun({cat,  "My Cat's Name"})  ->
            dosomething.

Erlang also has arity matching (this function is different than the one above it):

        myfun({cat,  "My Cat's Name"}, cage) ->
            dosomething.

Case statements are one way of doing that but those are considered a messy style in Erlang because they end up nesting so deeply - keeping it all out in small little functions and using pattern and arity matching is the "right" way.

You can do the same (except for arity matching) in Haskell with function arg pattern matching and Haskell also has some very nice _projection_ tools for it too:

 _Haskell_

        newtype Name = Name { unwrapName :: String }
        data Animal = Cat | Dog | Duck deriving (Eq, Show, Ord)

        myfun :: Maybe Animal -> Name -> String
        myfun (Just a) (unwrapName -> name) = (show a) ++ "'s name is: " ++ name
        myfun Nothing _                     = "No animal given!"

        > let n = Name "Fido"
        > myfun (Maybe Cat) n
        > "Cat's name is: Fido"
        >
        > myfun Nothing n
        > "No animal given!"

There are many problems with that function and I could probably eliminate the multiple function clauses and reduce it to one clause by getting rid of the pattern matching and using the _maybe_ function:

        myfun :: Maybe Animal -> Name -> String
        myfun a (unwrapName -> n) = maybe default formatAnimal a
          where
            default = "No animal given!"
            formatAnimal t = printf "%s's name is: %s" (show t) n

That would be the more idiomatic way I would do it - pattern matching isn't "bad" in Haskell and you'll see it used quite often in utilities and libraries. It's considered good form to move stuff like that into a utility and give it a clear name (like the _maybe_ function above that takes our _formatAnimal_ function) then use that in your application code so it becomes obvious what's going on.

Pattern matching, deeply nested ifs and cases, etc... are somewhat hard to parse for the eye.

<comment><USER5> What is concept is the:

        newtype Name = Name { unwrapName :: String }
       (unwrapName -> name)

I'm not familiar with this, are you pattern matching on a function type?

<comment><USER6> It's the View Patterns extension: [https://ghc.haskell.org/trac/ghc/wiki/ViewPatterns](https://ghc.haskell.org/trac/ghc/wiki/ViewPatterns)

</comment></comment></comment></comment></comment><comment><USER7> I'm a Java programmer so work with OOP every day. I think it has it's pro's and con's like everything else.

My pet hate is how dogmatic some people get to the point where they get angry over the use of if/switch statements. "It's not good OOP, use polymorphism", well the goal isn't to pass an OOP exam, but rather to write clean maintainable code where possible. If an if/switch saves me writing 6 classes with 3 lines in each of them, then that's what I'll do.

<comment><USER8> My pet peeve is how these brilliant architects end up writing so much code that does nothing. These 1 line functions just end up calling another 1 line function. At some point someone actually has to write the code. You know, that thing that actually does the work.

I always figured OOP programmers actually hate coding because they try so hard to avoid actually writing code that does work.

<comment><USER9> I would consider myself lucky that someone with the word 'architect' in their job title on my team wrote code that did nothing. Careful what you wish for.

<comment><USER10> There are Marchitects, Tarchitects, and Farchitects (Market-oriented, Technology-oriented, and umm... "freaking" architects).

Sounds like you have a team of Farchitects.

I have the title "architect", and I write code. It's usually code that lets the other thirty programmers write one or two lines of code instead of 200 lines, 30 times, in 17 different ways.

Because it is framework code, I'm often providing them the Lego blocks to build the rest of their system in... With unit tests... and examples... and at least one real implementation... and a Wiki page explaining it... and a Powerpoint session teaching them how I expect them to use it.

I do get the occasional grumble ("Uhh... Can't I just use Doohickey V directly?" "Sure, take a look at the interface, and don't forget the externalized configuration." "Oh.")

Just sayin'. There are architects and there are Architects.

</comment></comment></comment></comment><comment><USER11> Guest post from the future - here's a quote from a similar page on cat-v.org in 2024:

"FO is the "structured programming" snake oil of the 10s. Useful at times, but hardly the "end all" programing paradigm some like to make out of it.

And, at least in it's most popular forms, it's can be extremely harmful and dramatically increase complexity."

<comment><USER12> Indeed.

It's much easier to be a web contrarian than to build widely-used solutions that don't have limitations, drawbacks, inconsistencies, or other issues.

<comment><USER13> It is a list of quotes from people who have in fact built such "widely-used solutions". How is that being a "web contrarian"? Do you really think Rob Pike has never written any code? How did go happen then? You don't think Carmack has maybe a little bit of experience with large, complex software projects?

</comment></comment></comment><comment><USER14> I was briefly part of the "OOP is overrated, functional programming is in" camp. OOP is enterprise, functional programming is "simple" because it's just functions and data, you know, all the usual party lines.

Well, turns out CLOS is so good it's hard to stay away from it. You don't struggle to force something into an inappropriate object-oriented paradigm, rather, object-oriented solutions just flow naturally from the problem. And it's a pleasure to use.

<comment><USER15> I'm reasonably convinced that inheritance is a bad default/privileged operator for a language. Composition is a better default.

I often find myself suspecting that the hate OO gets is primarily a result of this early error.

The remainder is of course the way OO was promised to be the end-all of programming paradigms, which has not happened. Backlash is fully justified for that.

</comment></comment><comment><USER16> I really find Carmack and Armstrong's quotes very appropriate. The root problem seems to be trying to do _eveything_ the OO way when all you need is a function. Java for e.g. is plagued by this problem. Why would I want to write a class/object when all i need is print "Hello World". That being said there are problem where it fits really nicely e.g. Implementing user roles.

<comment><USER17> > Why would I want to write a class/object when all i need is print "Hello > World".

There is a huge gap between what OO could/was meant to be and how it is seen nowadays. I prefer thinking of OO as it's implemented in Smalltalk or Io instead of in C++ or Java.

To be more specific, in Smalltalk your hello world would look like this:

        Transcript show: 'Hello world'

and in Io:

        "Hello world" println

No class/object declaration in sight, right?

And then this:

> The root problem seems to be trying to do eveything the OO way when all you > need is a function

is a wrong question altogether - there is nothing stopping you from writing a function in OO (other than broken and dumbed down implementations in major languages, that is). In Smalltalk:

        my_func := [ 'Look, I'm a function!' ].
        "There's this slightly unusual way of calling the function though:"
        my_func value. "returns 'Look, I'm a function!'"

similarly in Io:

        my_func := block( "Look, I'm a function!" )
        my_func call # same as above

So, to make my point clear: there is NOTHING in OOP itself which REQUIRES verbosity and over-abstraction. On the contrary: going "full OO" makes it easier to write short, readable, to-the-point code. It also makes it easy to use FP patterns should you want it.

What you're arguing against are the currently popular implementations of OO, which are just bad. And before I forget: Erlang (and I program in it quite a bit) is one of the best Object Oriented languages I worked with.

<comment><USER18> I'm not sure if you are trolling or not but erlang is not an object oriented language. Joe Armstrong said it quite clearly in the article where his quote was taken

> As Erlang became popular we were often asked "Is Erlang OO" - well, of > course the true answer was "No of course not" - but we didn't to say this > out loud - so we invented a serious of ingenious ways of answering the > question that were designed to give the impression that Erlang was (sort of) > OO (If you waved your hands a lot) but not really (If you listened to what > we actually said, and read the small print carefully).

[http://harmful.cat-v.org/software/OO_programming/why_oo_suck...](http://harmful.cat-v.org/software/OO_programming/why_oo_sucks)

<comment><USER17> I'm not trolling; of course whether Erlang is OOP depends on a definition of OOP you consider "real". If you think of OOP as Java-style programming, then of course, Erlang has very little in common with it.

On the other hand, if you go back to what Alan Kay had in mind when he invented OO, namely objects as "black boxes, similar to computers in miniature" and "message passing as the only way of doing something" then Erlang is very, very much OO. Its processes are objects, and sending (asynchronous!) messages is built into the language. Then you get encapsulation, data hiding and interfaces with module exports and behaviours. That doesn't stop Erlang from being FP, too.

Really, there are many different paradigms and many implementations of each one, it benefits no one to only consider one particular implementation as representative for a whole paradigm.

Footnote: Alan Kay post on a similar topic: [http://lists.squeakfoundation.org/pipermail/squeak- dev/1998-...](http://lists.squeakfoundation.org/pipermail/squeak- dev/1998-October/017019.html)

</comment></comment></comment></comment><comment><USER19> Complaints agains oop often arrive from the fact that the programmer starts with an idea of the instance method "do()" and tries to build a class hierarchy under this idea. When the programmer fails, obviously the paradigm is wrong because the idea can't be, right?

As for functional vs oop, I am on the opinion that just because the haskell type system is awesome, and the java typesystem is traditionally unflexible, it doesn't mean functional > OOP. Language features like objects, static checking, first class functions are typically very orthogonal, hence you should be combining the features, so they match your domain.

I figure as code evolves, it generally takes 3-4 rewrites to get class hierarchies to a point where it matches your domain and more often than not the solution involves shallow trees and the use of traits or mixins which is something traditional oop languages don't all support well.

The only harmful paradigm is "write only programming", everything else is negotiable.

<comment><USER20> Functional vs OOP isn't really about the type system - Clojure is a functional language and it's dynamically typed.

The main value of functional programming is working with values and isolating mutation. When you deal with just immutable values your code maps to distributed systems naturally which is why functional programming is becoming more popular with the advent of cloud and distributed computing.

<comment><USER21> > When you deal with just immutable values your code maps to distributed > systems naturally which is why functional programming is becoming more > popular with the advent of cloud and distributed computing.

I work with hardcore distributed systems people (the ones that attend SOSP and OSDI). And the penetration of functional programming in distributed systems is about 0%. Sure, immutable state is easy to not share, but sharing of mutable state is inevitable, and you gotta deal with it, not try to wish it away.

The only people who seem to think functional programming is great for distributed systems seems to be people who don't really do distributed systems, or at least ones where scalability, performance, and fault tolerance are critical.

<comment><USER22> Shared mutable state tends to be only in a core data store or scheduler/thread manager, a small part of a distributed system.

<comment><USER21> Ya...no. Maybe toy distributed systems, but not the larger ones industry works with. Let's put it this way: if you have no shared distributed mutable state to worry about, it's not really a distributed system, it's probably doing parallel computation or something similar (like via map reduce).

</comment></comment></comment></comment></comment><comment><USER23> "Inherently harmful" is a bit vitriolic. If not a majority then a huge percentage of the world's systems are based around OOP and for the most part they function just fine. When people say these things I wonder what bubble they are living in where something is either the best thing ever or shit. The world doesn't work like that.

That said, I prefer a hybrid approach which is why I use Scala. It's not an either/or (or, if you prefer, an Option monad :-)

<comment><USER24> Sure, but sometimes strong opinions are necessary to make progress. If Dijkstra hadn't written "Go To Statement Considered Harmful", would we still be using them today? Probably not, but it probably helped bring quicker progress.

Just because you can build a house with a rock doesn't make it the best tool for the job, and it's in the interest of the carpenters to figure out what is the best tool for the job.

</comment></comment><comment><USER25> I often dislike C++ and Java (note: did not say object oriented programming), because the logic tends to be distributed in so many different files and locations. The abstractions, which should be beneficial, to decrease mental load, have the opposite effect over a longer time. To understand what just one overloaded method call does, I have to often read through a dozen of different files. Context sensitive IDEs don't make it much easier. Simply grepping files at command line is often the fastest way!

Combine that with object mutable state. And that with multi-threading (surprise state changes). Add exceptions on top (surprise hidden gotos, especially annoying in C++). The end result is often nearly impossible to fully understand.

However, this is not anti-OOP rant really. I recognize OOP has its uses.

The bigger issue is almost always when there's a discussion whether X is better than Y, some people seem to forget often both X and Y have their place in the toolbox. They're often complementary. When you like technology X, technology Y is not a threat to you, but an opportunity to learn something new. In the same way, criticism against X can be an opportunity to learn and improve. Not hostility against people who like or are used to technology X. No matter how much you like hammer doesn't make a saw a bad tool.

<comment><USER26> >To understand what just one overloaded method call does, I have to often read through a dozen of different files. Context sensitive IDEs don't make it much easier. Simply grepping files at command line is often the fastest way!

Right click -> Find all references / go to definition don't do that faster than typing out the grep command?

You said mutable state makes it harder to understand, and you said exceptions make it harder to understand because they're hidden gotos (which if statements and while loops are too), but didn't explain either. In my experience, exceptions have been a very simple, helpful, intuitive component of control flow.

<comment><USER25> > Right click -> Find all references doesn't do that faster than typing out > the grep command?

Yes, IDE is not generally faster. Find all references is not faster for me in most real life scenarios. Typing grep command is just arrow up, ctrl-something to get the cursor to right position, type something, hit enter. Piped to less, I hit / to search within the results. Done right, results from grep appear pretty much instantly, no waiting. Some operating systems are much better for this technique than others, due to cost of dealing with small files.

> You said mutable state makes it harder to understand, and you said > exceptions make it harder to understand because they're hidden gotos (which > if statements and while loops are too), but didn't explain either. In my > experience, exceptions have been a very simple, helpful, intuitive component > of control flow.

Whenever you call some method (or overloaded operator), it can throw. The fact is completely hidden from the context in front of you in C++.

In Java, you do know what might throw, because you have to declare it. On the other hand, the cost is high when anything you call changes the exceptions it throws. Or more like, it's set in stone.

<comment><USER26> That still sounds like more work than the way I do the same process in Visual Studio, which uses the AST or something around that level to search the code instead of just a text search, so it doesn't find irrelevant results. I guess it depends on your environment.

It is better when it's specified exactly what exceptions can be thrown by a method, yes. One of the only things I prefer in Java over C#.

<comment><USER25> If only Visual Studio/C++ used AST! At least in Visual Studio 2012/C++, context sensitive search doesn't often work at all. Try to get context for something common like ".create". You get a lot of non-context hits, even thousands. Maybe I'm doing something wrong? Maybe this doesn't happen in VS2013? In most other IDEs context sensitivity is better, but I still fall back to command line in Linux. It's just so much faster (for me). I get what I want in about 0.1 to 3 seconds and can _easily_ search near (grep -A and -B switches) these context hits with '/' in "less".

Git grep is great too.

Regardless, if it works for you, great. We should all use what works and disregard needless debate and politics.

<comment><USER26> I haven't used it for C++, only C# and VB.NET. It's integrated more with those, probably not with C++

</comment></comment></comment></comment></comment></comment><comment><USER9> OOP and FP are not in opposition to each other. FP considers objects to be at different granularity than your typical OO language does. So the real problem stems from the fixed granularity of the objectionable (heh) of typical OO languages leads to mutable state, which leads to unnecessary complexity.

In the end, typical OO leads to type systems which lead to noun discrimination which are ontologies, which reflect world-views. You don't want to get any of that on you. The more successful type systems stop at grouping aggregatable functions. Look at Go. Or Clojure. Those type systems are as good as it gets to me but I've never written a line of Smalltalk or Haskel, so someone set me straight on that.

<comment><USER27> > OOP and FP are not in opposition to each other. FP considers objects to be > at different granularity than your typical OO language does.

well FP purists would argue that objects(a unit that has properties and methods, and can pass messages to collaborators)have states.AFAIK "pure FP" is about getting rid of states,using immutable datastructures, and describing operations on stateless units,rather than writing imperative code.

I personally believe that being a FP purist or OOP purist doesnt make sense.Both paradigms can work together thus be orthogonal and not in opposition.

<comment><USER17> > AFAIK "pure FP" is about getting rid of states

Of course not. It's about making state be always explicit and about carefully controlling side-effects. Some state is going to be there always.

</comment></comment></comment><comment><USER28> In the quixotic hope of heading off a pointless argument: the opposite of OOP is not functional programming.

<comment><USER29> "... a computer model should be structured along three dimensions: data, functionality and events":

[https://news.ycombinator.com/item?id=475241](https://news.ycombinator.com/item?id=475241)

<comment><USER30> Y'know, I spent half a day today thinking about it, and your post gave me a nice, fresh angle at the problem. Thanks for that. So here's what I came up with (still work-in-progress):

The most simple program is easily done in assembly- or basic-style program - straight sequence of control instructions. The program starts with a set of data, constructs an intermediate data structure, a state graph, iterates on that graph in a simple sequence of commands, mutating it, collects output from the graph and then terminates.

When a program gets more complicated, we break sequence of commands into subsequences (subroutines/functions/etc). Each subroutine can be understood in isolation from others, which is a great win, but it still interacts directly with various pieces of the state graph, which limits our ability to reason about its effects.

Next we carve out individual pieces of the application state graph, and proclaim that each such piece can only be directly accessed by a small amount of code married to that piece of data. Such code and data married together are called an "object", and the entire approach is "object-oriented". Thus to reason about a subroutine we only need to look at its code in terms of its interaction with the "object" abstractions, rather than with the raw state graph data. Since abstractions are simpler than their implementations, it gives us extra ability to understand and thus create larger programs.

Implicit in the last two approaches is mutability - as the graph state changes, the same pieces of code continue to have access to it, and thus are expected to accomodate the drifting state. That is, the same chunks of code are expected to operate with a number of different states of the graph, corresponding to different stages in the lifecycle of the data.

An alternative way to cut down on complexity is "pure functional". In this approach each piece of code operates directly on the entire data graph, but only at a single stage of the lifecycle - it would iterate over an input readonly graph, then produce a new output readonly graph as a result, to be fed into the next stage of the pipeline.

So we have two dimensions - data and time. If we narrow down the data dimension, we end up with object-oriented approach. If we squish the time dimensions to a single point, we end up with pure-functional approach. The third dimensions - sequence of commands, is split up into smaller chunks in either of the two approaches.

<comment><USER29> Interesting thoughts. Now you set me off for at least half a day of thinking further. By the way, your sibling question already set me off studying reactive programming which I didn't know much about. It seems like reactive programming is lifting the time aspect of programming to a more prominent position. So functional-reactive coordinates functionality with timing. Will be interesting to see how the data dimension fits in then...

</comment></comment></comment></comment><comment><USER31> You are using "object oriented programming" by definition, the moment you formulate an "object" in code with interactions on that object (regardless of what language you're using)!

I completely agree with the arguments showing how harmful OOP abuse is (especially branching inheritance trees!), just like abusing pointers, or structs, or error codes, or _abusing_ <insert_language_feature_here> is harmful. But what does that have to do with OOP inherently?

Let's look at historical crashes, glitches, and hopelessly messy code and try to count their actual source. I bet you'll find sloppy programmers as the #1 root cause (maybe null-able pointers and/or weak typing as #2). OOP isn't bad because it's OOP, it's bad because hordes of bad programmers use it at big companies who don't care about code quality.

Beautiful functional code is beautiful.

Beautiful procedural code is beautiful.

Beautiful object oriented code is beautiful.

...

Spend more time writing beautiful code that draws its elegance from the rich set of paradigms and tools we have; spend less time participating in fad paradigm-ocide movements :)

<comment><USER32> Containers are a particular case. almost nobody re implements a container. and you're talking and template, not OOP.

> How would you do this without some kind of "object orientation"?

Variables. Variables are not "objects". What is an "object" anyway ? It's a shallow abstract concept which is impractical.

> The moment you formulate an "object" in code with interactions on that > object

No that's not what the article is trying to talk about.

What people argue against OOP is how it's applied to anything for any case. Creating new classes/type/abstract concept each time you want to realize something can often lead to code bloat. How many classes named "XXX_manager" can one encounter ?

> Sorry for shattering everyone's hopes and dreams of coding pure OOPless.

OOP tends to have state, which doesn't bode well will multithreading, which tend to favor functional programming. I don't know if the future is going to be massively multithreaded, but I just think that OOP is just another way to structure a program, nothing more. Processes and threads already are objects. Functions too. So why tell students to create new types all the time ?

</comment></comment><comment> guard-of-terra I wonder if there are GUI widget systems not based on deep inheritance trees.

It seems to me that GUI and OO are deeply synergetic.

<comment><USER33> It's only slightly oversimplifying to say that OO was invented for a GUI, namely Ivan Sutherland's _Sketchpad_ in the early '60s, and then developed with direct correspondence to physical objects in mind ( _Simula 67_ )

\- [http://en.wikipedia.org/wiki/Sketchpad](http://en.wikipedia.org/wiki/Sketchpad)

\- [https://www.youtube.com/watch?v=USyoT_Ha_bA](https://www.youtube.com/watch?v=USyoT_Ha_bA)

\- [http://en.wikipedia.org/wiki/Simula](http://en.wikipedia.org/wiki/Simula)

\- _The Development of the Simula Languages_ in HOPL I if you can get it, else [http://phobos.ramapo.edu/~ldant/datascope/simula%20history.p...](http://phobos.ramapo.edu/~ldant/datascope/simula%20history.pdf)

<comment><USER21> Sketchpad was prototype based, simula was early class based (though they didn't use those terms yet). It's likely they were developed mostly independently; OO just arises naturally when design is based on linguistic concepts like subjects, nouns, and things they can do.

What we know of UI today is more an artifact of smalltalk (both the first GUIs and smaltalk came out of parc and were related).

</comment></comment></comment><comment><USER34> OO just helps me understand the code (assuming that it is well-written, which isn't always the case). I don't understand the hate.

I have always imagined that it was just a natural progression from procedural code:

1\. Put a bunch of functions in a file.

2\. Ok, now we have too many functions to keep track of, so let's put functions in separate files.

3\. That worked for a while, but now too much repeated code, let's put some functions into modules.

4\. Now, we have all of these variables to keep track of, so let's hide some of them to lessen any confusion.

5\. Etc. Etc. Etc.

6\. Wow, now we have a complex language with all sorts of patterns that perhaps confuses things more than intended.

That's why I like languages that are lean and have pragmatic features. OO, functions, whatever works to make my life easier.

</comment><comment><USER35> One thing in that article stands out:

"OO is the "structured programming" snake oil of the 90' Useful at times, but hardly the "end all" programing paradigm some like to make out of it."

In 2014, I think it's important to remember that "structured programming" was, basically, "hey let's use FOR and WHILE loops, and subroutines, instead of a big pile of GOTOs", and think about what that says about any author who describes it as "useful at times" and "snake oil."

</comment><comment><USER36> Catchy and content-free soundbites that do nothing to further a discussion.

One of the big problems with discussions around OOP is that people have wildly different opinions on what OOP is. Whatever it turns out to be, it'll be a tool like any else that can be used efficiently or poorly.

<comment><USER37> Click the first link: [http://harmful.cat-v.org/software/OO_programming/why_oo_suck...](http://harmful.cat-v.org/software/OO_programming/why_oo_sucks)

<comment><USER36> I've read it before. It's a fluff piece for Erlang. You can tell that it's not a serious argument since he doesn't acknowledge _why_ things are done a certain way in OOP and what the advantages are. He obviously things the cons outweigh the pros, but Armstrong doesn't have to feign ignorance on the matter.

</comment></comment></comment><comment><USER38> I think inheritance is a really good idea, and that most problems with it result from people forcing inheritance onto problems not benefiting from it.

Can we all just make a resolution not to use any technique (no matter how fashionable, not even FP) on a problem unless it is a natural fit?

</comment><comment><USER39> In this CppCon keynote, Mike Acton explains some of the problems with OOP and the benefits of data driven design. Really worth a watch: [https://www.youtube.com/watch?v=rX0ItVEVjHc](https://www.youtube.com/watch?v=rX0ItVEVjHc)

</comment><comment><USER24> I am a big proponent of functional programming, but there are situations where it would be veeerrryy convenient to have open types and inheritance, which is forbidden in a language like Haskell.

Modelling something like a GUI toolkit is very difficult in Haskell, because each widget has a different clump of data associated with it. Functional programming works well when the data is uniform, or at least known ahead of time. It's very difficult to add new data structures into the system in a dependent module, like if you want to add a custom widget type. In OO, this is trivial.

I'm not sure what the best solution is. People are researching alternative solutions (namely FRP), but it's too bad it's necessary in the first place.

<comment><USER5> > like if you want to add a custom widget type

Add a custom widget from a gui program itself? So it's a gui program that has a widget builder then? Why not have an abstract data type which lets you encode the properties of both of those?

<comment><USER24> I'm talking about supplementing a toolkit. Like, in iOS or gtk or QT or whatever, there are stock widgets (buttons, sliders, text boxes), but you can also add your own widgets, like a date picker. A date picker would be modeled completely differently from those other widgets, and so it needs a completely different data structure. This requires supplementing the existing types, which isn't possible in Haskell.

<comment><USER5> That date picker inherits from something though right?

<comment><USER24> Right. In OO, you can inherit, but in Haskell, you can't.

<comment><USER5> Also, I'm not sure why you'd need to inherit to provide this functionality. The user could just provide a monadic type the function to run the gui is expecting and extend it however they wish.

<comment><USER24> I won't claim to be an expert on this stuff-- I've only recently been studying this. But, from my understanding, if you have a tree of GUI elements, each of those elements needs to have the same type, and that type needs to be known ahead of time. It's possible I don't understand your comment. Would you mind pointing me to some sample code or blog post or something?

</comment></comment></comment></comment></comment></comment></comment><comment><USER40> I've been working on leaving OO recently. This is my current API. No deep nested hierarchies of classes anymore!

      self.player.addComponent(Controller())
      self.player.addComponent(Shooter())
      self.player.addComponent(Jumper())
      self.player.addComponent(Life())
      self.player.addComponent(CharacterPhysics())

People who generally code applications could learn a lot from game developers and game engines. I took inspiration from Stencil and HaXe (but using Swift and SpriteKit) [http://www.stencyl.com](http://www.stencyl.com)

<comment><USER41> That's an excellent use of Composition. Most people think inheritance hierarchies are necessary for OO, but composition/aggregation is a much better way to do things.

A lot of the complaints I've read about OO center around people doing stuff that they later determine they didn't need to do, and then being stuck with it because it's in the middle of an inheritance hierarchy. Modern OO design would center around decomposing each class in the inheritance hierarchy such that the decomposition produces small subsets of shared behavior, and then composing those together to create the actual object. As a bonus you can still produce run-time polymorphism without crawling an inheritance hierarchy.

Composition in an OO system is very much like composition in mathematics. Two objects are combined to produce the desired behavior.

A lot of people crap on the GOF book because the patterns in it are either obvious or useless, but reading it does teach you some useful concepts, and for many people it will be their first direct exposure to something other than inheritance. Composition/Aggregation are great takeaways from that text.

As an example of a crappy inheritance hierarchy, a developer 20 years my senior had this four-layer inheritance hierarchy to represent 3 different data types. After he gave it to me I spent 15% of my time convincing him to let me eliminate half the classes he wrote. The worst part was that he was inheriting and then in the subclass he was writing functions that were semantically identical to superclass or cousin-class functions, but with different names. After I eliminated all that I was able to use templates to hide a lot of the mess.

OO design should be done according to the YAGNI principle--You Aren't Going To Need It--and its corrolary--do it as soon as you need it.

<comment><USER40> Hey, thanks!

Yeah, that's the impression I get. The ability to add functionality to an object in small modules (Components/Behaviours)

However this only works if there is a inherent structure and ability to use components. Most frameworks and libraries I have worked with don't really have that structure.

For instance, SpriteKit (Apples 2d framework) lacks a structure for building components. So most SpriteKit examples tend to have deep hierarchies of class inheritance.

If you'd want to take a look I wrote this [https://github.com/seivan/SpriteKitComposition](https://github.com/seivan/SpriteKitComposition)

Documentation is still lacking as I am playing around with function names but it has a test suites that demonstrates usage.

</comment></comment></comment><comment><USER42> These are some great quotes. Caveat: I am old. Programming methodology debates wear me out as quickly as language or commenting convention debates :)

I certainly remember many of the quotes when they first came about. I'm a product of the object-oriented wave. At the time I felt I had all the arguments as to why things were so much better with (or so much worse without) OO. In many cases, looking back I realized I was basically arguing for better tools and/or slightly better adherence to a few conventions.

My lessons from going through each "language" transition from debates over "assembler is the only way" through today's DSLs and more:

1\. OO wasn't good or bad intrinsically. The principles, however, can easily lead to more manageable or coherent code _over time_. By and large, inheritance, polymorphism, encapsulation, abstraction all form the foundation of large scale systems.

2\. Languages can do a great deal of harm, not concepts. Far too often, engineers dive into a new language or paradigm and assume all the code needs to exhibit all the properties of the new religion. In the early days of C++ programming, the saying we had on our projects was "a framework is not a compiler test suite". I think in all languages, especially today, the risk is that you more harm than benefit when you try to do everything in some fancy new way. Maybe there is a role of operator overloading or templates in C++ but I never really found it. But I am pretty certain nearly every framework employed these techniques. You can't blame the language because every language has stuff you can abuse. You can blame the zealots or evangelists which often cause the most challenges.

3\. Language and paradigm innovation benefits rarely scale in very large systems, but small systems early on exhibit amazing benefits. Most engineers are seduced by new languages and paradigms (OO was just the one that came after structured programming and before functional and others). In the beginning, the new language or approach is amazing. Always amazing. Over time the real world shows up and every new engineer feels that the code is bloated and needs a rewrite when they join a project. Efficiency declines. The magic fades as reality dominates. With more than a few engineers the complexity of interconnection between parts of the code base trumps the simplicity and elegance within one part of the architecture. Expressing those in paradigm or language elegant ways approaches a very high degree of difficulty over time. At one extreme we see competitions of "hello world" or the most basic app all being amazingly simple. At the other extreme we see a constant breakdown in even the most basic methodological approaches. Even "Goto" was hard to do without and certainly in OO maintaining a pure inheritance model, public/private data, or more become as close to impossible.

4\. In algorithmic complexity terms, a language or paradigm is at best a constant factor improvement over any other choice. The age-old rule of thumb is that programmer productivity is language independent. While I have no doubt that one could not spin up a new social network in assembler, one would be equally hard pressed to write a device driver or graphics runtime in Ruby or Python. Part of why methodologies gain attention is because the runtimes/libraries/frameworks that come with them do the things that need to be done the way that people want them to work _today_ \---that's what gives the appearance of improved productivity. The right libraries in C can serve a great purpose. We see this when a language gets a new library that seems to bring renewed interest to it.

5\. Tools are everything. What makes or breaks a paradigm/language are tools. You can take a simple language or paradigm and have great tools and become much more productive than a "better" paradigm with poor or ill-suited tools. One way that this surfaced over time was with tools that generated the right code—interface builders for example. Then using complex, archaic, or intensely manual approaches lacking formal foundations would become much easier. Plus the bonus of transparency of code generation really helped because other tools could easily integrate (having access to a whole tool system is also more productive than any one methodology+tool).

Ultimately, I think OO is perfectly good and most all modern systems make use of the 4 basic pillars of the paradigm. I don't think it ever became the answer to code reuse or code quality that proponents claimed. Ultimately the methodology is going to be trumped by scale and age of code and system. Any success means your ability to start over is reduced and so the best bet is to focus on knowing what principles your project is being created and run with.

<comment><USER43> > The principles, however, can easily lead to more manageable or coherent code > over time.

This. 1000 times over. This is why well factored code bases can often seem to have lots of redundant classes and interfaces to inexperienced developers. It's all about maintainability over time, building bulkheads around change.

> tools that generated the right code—interface builders for example

The irony is that these tools often fail when the benefit is considered over time. This comes through a lack of tools - their code works badly with SCM (no domain-specific diff tools). They throw away everything we've learnt about software engineering just to win the marketing demo's.

<comment><USER5> How do redundant classes and interfaces improve maintainability over time?

<comment><USER44> Because they improve maintainability, they are not redundant.

<comment><USER5> I asked _how_ redundant classes and interfaces improve maintainability over time.

I'll narrow down my question some more:

How does duplicated code improve maintainability over time?

<comment><USER45> Author stated that classes and interfaces _seem_ redundant, not actually redundant. Repeated code could improve maintainability because it may actually have different reasons to change, and only look similar on the surface. I've seen this often missed by inexperienced devs who get overzealous trying to DRY up everything.

</comment></comment></comment></comment></comment></comment><comment><USER32> I'm in some programming class in france. The teacher argued that OOP and encapsulation makes programs more secure. It really felt like a political statement.

The day I understood that class and struct are merely the same thing, I questionned the purpose of private: and public:.

To be honest, I think the sole purpose of those construct is just to hide proprietary code when you sell libraries and deliver a set of binaries and headers, to force the compiler to forbid you from writing to, or using protected member. It's really moot. It's just a coding practice, it's not some grand way to think and construct applications.

OOP is nice if you want to create some non standard simple type, like Vec3, or when you want to use an interface for something quite complex. Templates are a good extension of OOP, but it's not used that much, even while the STL justifies the existence of templates. But other than that, when you want to make an end-user application which is not a library, I think OOP is not that much useful. Too few programmers write libraries, most just write applications, and applications don't need OOP.

If you use OOP to pretend that your code is reusable, please, first check if what you're making really is worth reusing, chances are it's not.

TL;DR: OOP is good to design bricks. Most coders are not brick designers, thus most programmers should not touch OOP that much.

<comment><USER46> Public and private has nothing at all to do with hiding proprietary code. Encapsulation is important regardless of whether you use OOP or not. Even if you program something alone that will never be derived/re-used, you should strive to have clean boundaries between subsystems. You also want to make things read-only unless they should change (most things should not)

If you make everything public and writable you have to spend a lot of thought on things that a compiler could help you with so you can focus on solving the problem. Much like using a type system.

</comment></comment><comment><USER47> Object Oriented paradigm started when procedural was the most popular way to code. There were problems with procedural approach that made understanding and working in large applications very tough. Before OOPs came around, coders tried encapsulating their code by separating them into separate files. This however solved only one problem and that too only partially.

Coders also tried revolving their procedures (casually called functions) around their objects - get_student_name(struct student _), calculate_ranks(struct student_list_ ) and so on.

It was necessary to have a paradigm that represented code very close to how we see this world. OOPs just had to happen.. it was not avoidable.

Now, the challenge lies in the fact that with everything powerful, one can go ahead and use it incorrectly. There comes the harm. But then there are better ways to learn the concept. I wrote a blog about OOPs recently. Read it here [http://wp.me/p5jxzK-1b](http://wp.me/p5jxzK-1b)

Go ahead and use it, OOPs isnt going anywhere soon and it aint that harmful :)

[http://kossip.ameyo.com/2014/11/25/the-unusual-approach- to-o...](http://kossip.ameyo.com/2014/11/25/the-unusual-approach-to-object- oriented-programming/)

</comment><comment><USER48> I am using _object-oriented_ programming (OOP) and like it! I'm using OOP via Microsoft's Visual Basic .NET, the .NET Framework, ASP.NET, ADO.NET, etc.

For inheritance, I've never tried to understand it or use it. Yes, the .NET Framework apparently uses inheritance, but there as far as I can see mostly the _inheritance_ is mostly just imaginary, mostly just a means of documentation. E.g., I can have a variable X of type byte, integer, float, GUID, etc. and write X.ToString, that is, pass (it really is essentially call- return semantics) the _method_ ToString _inherited_ from somewhere, some _abstract class_ or some such, but I don't believe that there is actually any real _inheriting_ going on. Maybe there is some _overloading_ , but then the spelling 'ToString' is just a convenience for documentation and usage. Or, just as easily it could be that in case the type of X was integer, then I could write X.ToStringInt where the method ToStringInt was for converting integers to strings. Fine with me. I know; I know: If I can write X.ToString when the type of X is an integer, then where X is declared I can change its type to, say, GUID and keep the code X.ToString and, thus, get _code rewuse_ , but I'd nearly never do that! Instead I'd want to check over my code to be sure the code still did what I wanted it to do.

Mostly I look at instances of classes much like in PL/I where there were data structures like

         Declare
            n_points   Integer,
            1 A        Based,
              2 Coordinates( n_points ),
                2 X  Float,
                2 Y  Float,
              2 Lengths (n_points) Float;

So, in Visual Basic .NET could write

</comment><comment><USER49> OO has been tremendously successful, it has allowed us to build systems that we wouldn't have dreamed of before. The Web was invented on a NeXT in Objective-C.

Reuse in UI frameworks has been great, and I've had similar success with custom frameworks.

However, success invariably contains the seeds of failure, because success means that we are taken to the limits of applicability. To me, those limits were visible in the 90ies when I wrote my Master Thesis[1], issues like the non-composability of frameworks, the runtime/compile-time, composition/inheritance dichotomies, architectural mismatch etc.

Alas, nothing really happened, and IMHO, things actually got worse. At the time, I had two candidates for "the future", one being AOP and the other software architecture. AOP was a dud, but I am very hopeful about better linguistic support for software architecture, so much that I am creating a programming language that has software architecture as its organizing principle, deriving other paradigms such as OO from this base [2].

Having been exposed to FP early on, I have to admit I don't understand the current hype, because it seems to primarily address issues of "programming in the small" (tight coupling), although some of the lessons (communicate using simple data) are applicable elsewhere, and have been discovered elsewhere. I don't see a large-scale distributed system like the WWW built in the FP- paradigm, but happy to be corrected!

[1] [http://www.metaobject.com/papers/Diplomarbeit.pdf](http://www.metaobject.com/papers/Diplomarbeit.pdf)

[2] [http://objective.st/](http://objective.st/)

<comment><USER22> AOP isn't a dud. Google Guice is AOP.

<comment><USER49> Really?

Taking the definitions from "Software Architecture: Perspectives on an Emerging Discipline" [1], you have the following:

\- components

\- connectors

\- configurations (systems)

Guice (and other dependency injection frameworks) clearly address the third part: configurations. AOP is, at best, an implementation technique.

[1] [http://www.amazon.com/Software-Architecture-Perspectives- Eme...](http://www.amazon.com/Software-Architecture-Perspectives-Emerging- Discipline/dp/0131829572)

</comment></comment></comment><comment><USER50> According to these guys, everything complex is harmful and everything simple is great. I want to start learning Assembly to finally understand the whys of programming on a hardware level. Is Assembly harmful? Any simpler and thus better alts? Or is Assembly a simpler version of some other ugly, threatening monster? Oh, btw, where's the best place to learn it?

<comment><USER51> Congratulations, you just discovered the great RISC vs CISC debate.

</comment></comment><comment><USER52> Separation of concerns, reuse, and modularity are the key principles here.

I'm a fan of hybrid OO/functional approaches, use classes but minimize side effects. Return new objects when relevant, etc.

It's a mistake to misjudge OO based on some over-bloated java-design _or_ some underdesigned implication.

The phrase "everything in moderation" largely applies.

Given, if you are doing things in C, and passing a structure as a first argument, you are getting _most_ of the way there.

I think inheritance is frequently over-applied, interfaces are a great idea (or even just duck typing), but not everything is an inheritance hierachy.

Rather, encapsulation is the most powerful concept.

Much of what gives OO a good or bad name is in the hands of who is doing the architecture - abstracting things too early leads people to occasionally go to the extreme other side of the fence.

There's a balance to be had, and advantage to learning from multiple schools of thought.

</comment><comment><USER53> I really liked this link: [http://harmful.cat-v.org/software/OO_programming/_pdf/Pitfal...](http://harmful.cat-v.org/software/OO_programming/_pdf/Pitfalls_of_Object_Oriented_Programming_GCAP_09.pdf) from the server. It is from 2009 so a bit dated, but it shows something which is prevalent today, objects obscure what they are doing, and they mix code and data, but data access is a lot slower than it used to be so data optimization is more important than ever.

That has only gotten more true with DDR3 and DDR4 memory and giant caches. It is significant enough that it would behoove compiler optimizers to pause trying to do things with fewer instructions and start looking at better data organization.

</comment><comment><USER54> I love the banana analogy :).

"The problem with object-oriented languages is they've got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle." – Joe Armstrong

</comment><comment><USER55> OOP has the same relationship to programming that formalist literary critique does to writing: the willful denial of connection to reality. When you're solving a problem that's connected to the real world--perhaps you have a deadline, or a live human being will use your program at some point--it's often better to just go ahead and build something that works and can be easily explained to the person who will maintain it in the future.

As with formalism you should know how OOP works and how seriously others take it, so you don't get into fights with your relatives at Thanskgiving.

<comment><USER56> And first of all, learn (in general, not you) that OOP doesn't mean the same to all programming languages, before complaining about OOP in general.

</comment></comment><comment><USER57> The thing that I learned from SICP isn't that functional is greater than OO, but that functional and OO are both design strategies that can assist you in designing a solution to a problem.

</comment><comment><USER58> The problem with OO - and this applies to Smalltalk too - is that class hierarchies are a bad fit for a changing business environment, being hard to refactor when previous assumptions change: inevitably some new case will come along which requires changes to the structures that were originally defined, and OO is harder to deal with in that context.

That said, I do think OO is good for problem areas that actually have fairly static interfaces, like GUI libraries, for instance

</comment><comment><USER59> Object-oriented programming is a product of personal computing systems like Smalltalk and Self.

This approach begins to suffer when application state is mixed between a remote server and a local client. Further, the physical metaphors of OOP suffer when removed from Smalltalk-like systems.

The rise of functional programming has as much to do with the rise of networked computing and shared data than anything else.

</comment><comment><USER60> Err... OOP isn't better/worse than any other approach, but there are some criticisms that I can't disagree with... but I like having objects when work requires some book-keeping

Programming is like kung-fu. You gotta pick and choose the best of each style, when they are relevant.

</comment><comment><USER35> Who is this "cat -v" guy anyway, they have a lot of badly written bad opinions on a lot of stuff.

( [http://harmful.cat-v.org/society/gay_marriage](http://harmful.cat-v.org/society/gay_marriage) [http://harmful.cat-v.org/political-correctness/girls-in- CS](http://harmful.cat-v.org/political-correctness/girls-in-CS) [http://harmful.cat-v.org/economics/fair_trade](http://harmful.cat-v.org/economics/fair_trade) )

<comment><USER5> "I treat my female coworkers with respect, I politely discuss technical stuff with them if they feel like. I do make sexist jokes if I was able to get to know them sufficiently before, like any healthy male."[0]

Wow. Any health male makes sexist jokes to women if he gets to know them? I guess I'm just not very healthy then.

"My wife's male coworkers behave the same way and I have no problem with that."[0]

Easy to say you don't have a problem with something that doesn't affect you!

0: [http://harmful.cat-v.org/political-correctness/girls-in- CS](http://harmful.cat-v.org/political-correctness/girls-in-CS)

</comment></comment><comment><USER48> I'm using _object-oriented programming_ (OOP) and like it. For the problems described in the OP, I'm not encountering those!

I want to write relatively simple code, thus, want to avoid tricky features of the software tools I use, and so far have been successful. But this desire means that I don't have deep experience with tricky aspects of OOP. So, YMMV.

So far mostly my code looks just like it would have before OOP; I've created only a few OOP _classes_ ; and all of those are simple. I write a lot of functions but not many classes.

Some things I do like:

(1) Can have an array of classes and, then, can sort the array with whatever class _properties_ want to use as the sorting keys.

(2) Can _serialize_ an instance of a class to a byte array, send the byte array via TCP/IP, and deserialize the result.

Well, the OP notes some of the dangers of _inheritance_. I agree and saw the danger right away and, thus, in the code I write try not to use inheritance and so far have been fully successful.

But, I can think of situations where inheritance could be useful and keep the work better organized than not using inheritance.

But, I'd say: The main issue is just having humans understand the code, and for that, using inheritance or not, the main solution is just to document what is going on.

Or, if the way around using inheritance is just having multiple copies of the same source code, then just document this fact so that when want to change one of the copies, likely change all the others, also. And, of course, generally should know all the places in the _code base_ where that code, or some modification of it, is being used. Can solve such an issue with just documentation.

Or we don't want to look to programming language syntax and features to solve all problems of _meaning_ in that software, meaning better communicated with documentation.

Gee, so far this is a _polymorphic_ post since I didn't way what OOP language I'm using! So, I'm writing in Microsoft's Visual Basic .NET with their .NET Framework, ASP.NET (for Web pages), and ADO.NET (for using SQL Server). That Microsoft software is awash in classes, and that _architecture_ seems to be working well.

Yes, that Microsoft code is awash in inheritance, but mostly I just ignore that fact and regard it as more just documentation than actual software. I get by mostly ignoring inheritance because I don't use it directly in my code.

In my project, the hard technical work was the applied math; it turns out, given the math, the corresponding code is simple.

</comment><comment><USER61> OOP is still good for gaming and simulations in general.

</comment><comment><USER62> This old bag again.

</comment><comment><USER63> I've always had a problem with object orientation and have never embraced it.

But none of these quotes (and most dev thinking) seems to share my reasoning.

My problem: almost every argument for or against object orientation is about _us_ , the developers. I rarely hear any arguments that consider our users or customers. Oh sure the usual (and lame), "It helps us serve them better."

I long ago lost track of all the lame bullshit (far too many to mention, but you know the culprits) that was supposed to revolutionize the way we build things without ever taking our users into consideration. Most of it was to make developers who couldn't build what was really needed appear as if they could. This has helped consulting firms and enterprise I.T. departments justify their rates and schedules, but has added little to the customers' benefit.

If the people who dream this shit up would stop focusing on what _we_ need for 5 minutes and consider what _they_ need, we'd all be way better off.

How has object orientation helped my customers? Frankly, I can't think of a thing. Add that quote to this list.

<comment><USER64> I feel that OO imposes some semblance of structure using an intuitive semantics most "average" developers can grok (Not crazy stuff like Monads) , thereby allowing Pointy Haired Bosses to treat devs as commodities to be replaced at will.

Java is a language right at the sweet spot on that continuum. Just advanced enough to prevent most stupid bugs but also mediocre enough that most devs can grok it.

In the words of one of its creators :

"We managed to drag them half way to Lisp"

And how would you program an enterprise Java App without object orientation ?

<comment><USER5> > (Not crazy stuff like Monads)

Read this and tell me that "crazy stuff like Monads" is an accurate statement:

[http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/ba...](http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf)</comment></comment></comment>


Ask HN: Blind programmers, what can I do to make my code easier for you? - <AUTHOR> I've often wondered what things we have in style guides which make it difficult for visually impaired programmers. I would like to know how to make my code easier for you to read and write. Please help me to improve my code for you. <comment><USER2> I used a screen reader for a few years due to sight issues, these days I use a screen again with magnification. When you work without a screen you end up having to build up a mental model of the code, which you keep inside your head. When you navigate the code, you are doing it mentally, inside this cathedral you maintain in your mind.

So given that, the main challenge for me was code navigation. I used Visual Studio at the time and it allowed me to jump to method definitions, call references, jump to the start/end of a method etc. So the worst thing was long methods as 1) I had no efficient way of navigating them except to read each line 2) it was hard to keep track of all the things the method did. Breaking up code into smaller pieces with good naming of each method helped speed up my understanding and navigation of the code a lot. It also simplified the mental model in my mind.

<comment><USER3> As a person who can visually see, I want to emphasize that these goals: short methods (max 40 LOCs) and speaking names for all code entities are equally important to me. I want to spend as few time as possible reading the code. I want to spend most time on modifying and transforming the code. I do so by building up a mental model which I can change freely before typing the changes down. Sometimes it helps to write down the ideas to see how they "look like", however everything you say applies equally well to me as a non-blind programmer.

Another important trait of easy to read code is the rule of "Big picture" first. I.e. if you have a `main()` method you will find it first in my files, only then followed by sub methods which are called by main(). Same holds for types: first comes the class and then it's followed by any type which might be required for a class attribute. So, when opening a file you immediately get the big picture and depending on the granularity you want to build for your mental model you can continue reading by scrolling down. When the model is good enough, you can skip the rest of the file.

I find this pattern to the contrary of how others design their files. There are people who list all details and sub methods first before telling me only further down the road how these details are put together. This forces me to read a lot of code to build a blown up mental model which might not be necessary for the current task at hand.

<comment> loup-vaillant I've just written a little parser I OCaml, and the file goes like this:

      Module declarations                         ( 3 lines)
      Parser type declaration                     ( 1 line )
      Implementation details you don't care about (47 lines)
      Actual grammar                              (20 lines)

In that order. In Haskell, I would probably have put the grammar at the top of the file, so you can get the big picture right away. But the language reads stuff from top to bottom, so I have to put the big picture at the bottom.

An alternative would be separate the details from the grammar, but then I would expose those implementation details in an interface, while in fact the rest of the program is only interested in one function that parses everything.

Or, you could write from bottom to top. It's OCaml, so you _know_ the big picture cannot be at the top. Now a case could be made for a language that reads toplevel statements from bottom to top…

<comment><USER4> To be fair, C is kind of like that, too. You could move the declarations of static functions to the top, but then you'd still have declarations that prevent you from getting to the real meat.

</comment></comment></comment></comment><comment><USER5> A visually impaired software engineer at Yelp recently published a blog post titled, "A Guide to Software Engineering for the Visually Impaired"[1]. He also gave talks at PyOhio[2] and North Bay Python[3].

[1] [https://engineeringblog.yelp.com/2018/10/a-guide-to- software...](https://engineeringblog.yelp.com/2018/10/a-guide-to-software- engineering-for-the-visually-impaired.html)

[2] [https://www.youtube.com/watch?v=L3WpnG49XLc](https://www.youtube.com/watch?v=L3WpnG49XLc)

[3] [https://www.youtube.com/watch?v=FvlzaOrLBNw](https://www.youtube.com/watch?v=FvlzaOrLBNw)

</comment><comment><USER6> There has been a very interesting discussion, that is not 100% equal but where you can get comments about similar problems, including some from blind programmer. I hope they may be helpful.

" _Ask HN: How should a programming language accommodate disabled programmers?_ " [https://news.ycombinator.com/item?id=18414562](https://news.ycombinator.com/item?id=18414562) (164 points | 8 days ago | 116 comments)

<comment><AUTHOR> Thanks! That's really helpful :)

</comment></comment><comment><USER7> This thread touched off an idea for a journalism piece that I think could work in something like The Atlantic.

I bounced it off of my new writing partner[0] and she's interested in collaborating on it. If you're in software and you know a blind person that's working on something difficult, high impact, or otherwise noteworthy please reach out to me. It would be great to chat with them. The more that society appreciates the blind and understands their day-to-day the better it will be accommodated.

[0] She's the former Sr Editor of The Walrus (essentially Canada's The New Yorker), so she's quite good.

<comment><USER8> If you're using a smart phone, and it works, you're using code blind people wrote. I worked with many very excellent software engineers back in my days of writing network infrastructure code. Some just happened to be blind.

Code is plain text, and development environments can be navigated with keyboards. If I were to suggest that a blind developer needed my help, I would have something thrown at me. Luckily, the aim is not so good.

</comment></comment><comment><USER9> Sorry for highjacking your thread, but since the subject of reverse engineering is very close, writing it here. Radare2 project is famous to be blind users friendly, but we want the same thing for Cutter also [1]. If you know how to improve radare2 expierence too, don't hesitate to open an issue on our GitHub [2].

[1] [https://github.com/radareorg/cutter/issues/889](https://github.com/radareorg/cutter/issues/889)

[2] [https://github.com/radare/radare2/issues](https://github.com/radare/radare2/issues)

<comment><USER10> To pile on here on a (vaugely) related tangent, Common Voice (from Mozilla) needs our help to build a public speech corpus for training speech recognition software and Text to Speech: [https://voice.mozilla.org/](https://voice.mozilla.org/)

Mozilla is currently hard at work on DeepSpeech for transcription and Text to Speech, which could be huge for accessibility. I hope it continues to improve :P

</comment></comment><comment><USER11> One very specific thing I remember from discussions I had with a blind programmer was to use of multi-line comments (/* __/ ) in favour of line- comments (//), especially for comments that do span multiple lines.

That helps a lot because with a screen reader "slash star <comment text> star slash" is significantly more listenable to when compared to "slash slash <one line> slash slash <another line> slash slash <third line>…"

Surprisingly this is the only thing I cannot seem to find around my IRC logs… Digging through the logs other things that were called out to make comprehension harder for blind people are:

* Unicode identifiers;

* Boilerplate you cannot easily skip past without losing context (common in e.g. Java);

* Typos (esp. if done on purpose, inconsistently);

All this comes from their preferred interface being a screen reader which, I believe, is true for most blind programmers.

<comment> V-2 Who does inconsistent typos on purpose? And what's the purpose?

<comment><USER12> Some people use the archaic spelling "shew" but only the senses "to prove or demonstrate". Or again in mathematics "rng" to mean a ring that does not necessarily have an identity. Or "iff" to mean "if and only if". These would look like inconsistent typos to nonmathematicians.

Or "referer" in HTTP because that's what the standard uses. Or "creat" when discussing the UNIX system call or a function with the same purpose on another platform.

<comment><USER13> I've also worked on codebases where the first developer misspelled a function's name and everyone else just kept using it instead of fixing it. When I see stuff like that, I admit that I judge them probably harsher than they deserve. Sloppy!

<comment><USER14> [https://blogs.msdn.microsoft.com/oldnewthing/20080519-00/?p=...](https://blogs.msdn.microsoft.com/oldnewthing/20080519-00/?p=22273)

<comment><USER13> Ahhh Raymond Chen. For anyone who hasn't read his work before, it's an absolute goldmine of interesting quirks and "why things are the way they are".

To the point of the article, I try really hard to make sure that things like this don't happen, ideally before a typo like that gets merged.

</comment></comment></comment></comment></comment></comment><comment><USER15> I am not blind but I have shitty sight and I wish web browsers do the same thing they are doing now with http sites an deny access to web pages with light grey text over nuclear white background.

<comment><USER16> I do not think you need to deny access (although I think that if the webpage doesn't need colours, it shouldn't set any at all, instead using the user's preferences), but (as defanor mentioned) you can apply CSS (although it doesn't have to be global; I generally apply user CSS individually instead, since each webpage needs a different CSS to be fixed; usually webpages that don't already have CSS don't need any CSS to fix them, I find, though)

</comment></comment><comment><USER17> I'm not blind, but I have a blind PhD student.

One useful thing seems to be using an auto code formatter and requiring the code is always autoformatted. Manually ensuring indentation is right is very awkward, just running clang-format, or whatever, is simple.

<comment><USER18> I think this is my favorite trend in programming languages. It seemed controversial when Go shipped with a canonical auto-formatter, but now I consider it table stakes.

</comment></comment><comment><USER19> I think, as many seem to be picking up, that tooling is critical for blind programmers and is secondary to how the language is designed. No matter how the language is represented in text, it can be made accessible with the right tooling. Often, however, this doesn't exist. This is why Python is quite polarizing for blind programmers, some love its simplicity and readability and others find the whitespace trips them up. But I think this is a function of what tools blind programmers land on to use Python...and probably also how much residual vision the programmer has. Remember that only 10% or so of blind people are totally blind.

</comment><comment><USER20> GopherCon 2018: Julia Ferraioli - Writing Accessible Go

[https://www.youtube.com/watch?v=cVaDY0ChvOQ](https://www.youtube.com/watch?v=cVaDY0ChvOQ)

</comment><comment><USER21> Maybe this helps you giving you some insight: [https://medium.freecodecamp.org/looking-back-to-what- started...](https://medium.freecodecamp.org/looking-back-to-what-started-it- all-731ef5424aec)

also fun to listen. This is his screenreader: [https://soundcloud.com/freecodecamp/zersiaxs-screen- reader](https://soundcloud.com/freecodecamp/zersiaxs-screen-reader)

</comment><comment><USER22> I think the coding is never easier for all. One of the most dangerous things I've seen happen to people who are just starting to code is being told that it's easy. But when you done any task and project goal day by day you sharp your expertise.

</comment><comment><USER23> I often wonder how blind people deal with PDF's in general, and scientific articles (sometimes scanned, or pixel rendered) in specific? Or are they effectively locked out from reading scientific papers?

<comment><USER8> Ask for the tex file.

<comment><USER23> of course not every paper has an associated tex file, ... some of them were supposedly even written before Donald Knuth was born...

</comment></comment></comment><comment><AUTHOR> If you know any visually impaired programmers, please share this with them!

</comment><comment><USER24> Can I just say, kudos for being considerate, compassionate and inclusive?</comment>