Hacker News new | ask | show | jobs
by gersonaya 4507 days ago
When you're building a skyscraper, you are not going to design every brick.

The basis of teaching children how to code is making them learn how to use code as a problem-solving tool. Like this, the sorting will not be important by itself, but as means to an end. As a way to achieve greater objectives.

And besides this reasoning, we have another: in CS, something is generally built on top of others. If you write a heapsort algorithm in C, you don't need to understand it's implementation in assembly. When I write my HTTP Applications I don't need to understand all the Network Layers beneath it. As I write this, I don't really understand the intricacies of Google Chrome and MacOS that make it possible. Am I ignorant? No. There is much thinking and learning to high level coding too. It's all about how complex your problem is and how you learn to apply logic to solve it.

3 comments

While it may be perfectly acceptable to ignore the lower-level details when first learning some new technology, or even when using it for personal use only, that sort of ignorance is not acceptable when working on systems that are meant to be used seriously.

At that point, you need to have at least a high-level understanding of each and every layer that you're building upon. If you don't, then it will come back to haunt you, whoever uses your software, and whoever has to maintain it after you're long gone.

We've all encountered, or at least heard of, the Java and Ruby programmers who use ORMs, but who refuse to learn SQL, and refuse to learn how relational databases actually work. They write their software while understanding only the highest levels of the abstractions that they're working with, and then the system ends up performing horribly. Then somebody more experienced and knowledgeable gets called in, and gets to see how the ORM is generating abysmal SQL queries, or indexes aren't being used.

It's better to know and understand than to not, especially in the long term.

I have built many systems that were meant to be used seriously. Never once has my lack of understanding of graphics cards, for example, come back to bite me.

Every system is built on abstractions. You can argue about the value of understanding particular systems, but we are well past the point when any one person can or should understand them all. No one is arguing that it's acceptable to learn only the highest-level abstractions. But it is acceptable to let somebody else worry about some of the lower-level ones.

People who don't focus on understanding engineering systems often focus on understanding other systems––team dynamics, for example, or business needs. I've met a lot of developers who only cared about learning the technical side, and were happy to look down on developers who didn't feel the same. Is that wiser, somehow?

What kind of systems were you working on?

No, you probably don't need to know much about how graphics cards work if you're working with databases or other software that doesn't really involve graphics in any serious way. But if you're working on graphics card drivers, high-end video games, visualization systems, or simulations, then you'd probably should have such knowledge.

The point is not to fully understand every single layer that exists, including those that your software never interacts with, or only just makes very light usage of. But you should have at least a basic understanding all the way down through the code and hardware you do use, directly or indirectly.

It's perfectly acceptable to not understand the low level details of seriously used systems. Isn't that what teams are for? You can trust the engineers developing infrastructure so that you don't have to worry about it. Sure, understanding the high level concepts can't hurt, but it isn't going to make a front-end developer any more productive.
> It's perfectly acceptable to not understand the low level details of seriously used systems.

Yes, that's what my colleagues thought a few months ago, too, when they churned up a web UI for an embedded device. My teamwork was, apparently, insufficient to make them realize that a configuration interface that takes half the available flash space is rather large (the other half was taken by a goddamn kernel, a web server, a proxy server, a bunch of other networking tools, a logging service and all the tools that communicated with the web ui!). Lack of understanding regarding how routing works in TCP/IP networks also meant that their first attempt had a pretty fatal flaw which resulted in the configuration interface becoming inaccessible, which became apparent in the first ten minutes of testing and required a significant amount of redesign because the entire workflow of the interface depended on that.

Their Bootstrap wizardry was remarkable, but ignoring how the underlying system worked resulted in them having to start from scratch.

It works the other way 'round, too. Not understanding how web tools work would also make my systems programming entirely useless when it has to provide the infrastructure on which such tools rely.

No one likes all this complexity. I hate it, too. I sometimes truly, really wish my job was as simple as taking this thing from here and putting it over there. Ignoring this complexity doesn't make it go away though; building tools that can isolate some of it behind a comprehensive and consistent interface is ok, but relying on those tools to do it for you without understanding what they do is technical suicide. It's this kind of thinking that makes people think it's ok for a rudimentary word processor to take six fucking seconds to load, after asking you for a password, in 2014, on a quad-core system.

Edit: it's also worth pointing out that this is really beyond the scope of the article's argument. What the article insists is that this:

    var numbers = [7, 8, 1, 3, 2, 7, 6];
    numbers.sort();
hardly helps anyone learn coding as a problem solving tool. This exercise taught the reader exactly nothing about how to solve the problem of sorting numbers. I could ask someone who works for me to sort me those numbers, and my understanding about algorithmic thinking would be as rudimentary as before.

Teaching children how to use calculators does not increase their problem-solving ability, not by an iota. Teaching them mathematics does that, and their ability is further advanced when they learn about theorems and structuring proofs, about induction and, yes, about using a calculator.

It's the same here. I'm not arguing that computer science should be purist to the extent that you shouldn't use anything but a Number 2 pencil to program. That's stupid. I am arguing, though, that teaching people "to code", as if programming consisted in nothing but translating from English to Codese, is pretty much as retarded as teaching mathematics as if it were a language, consisting of nothing other than translating the English "Two apples and three apples make how many apples?" into the far more cryptic "2 + 3 = ?".

Teaching kids to use calculators DOES increase their problem solving ability. They can produce the same result as someone using paper. If the problem's really advanced, they may have to use brackets correctly too. You teach the same logic whether it's on paper or not, just instead of shuffling numbers in your head, a system that's BETTER at it is doing it instead.

But the issue is, you've added the Calculator dependency to the Kid program. Whether or not that's an issue depends on whether Calculator is a well maintained and dependable project.

On the other hand, there are downsides to NOT using the easier Calculator library, and writing all the code from scratch (i.e. Memorising Mathematics systems and practicing them enough to use them at any reasonable speed) — 1) storage space and using up brainpower / focus storing micro numbers, when you could be focusing on the bigger picture algorithm, 2) speed, the Calculator library is optimised and written by experts, 3) bugs, the Calculator library is well tested, whereas it's easy for anyone to make simple arithmetic mistakes.

I disagree with the last point. Understanding the low level details of a system definitely makes a developer more productive.

When I am working on an iOS app and I get stuck on a bug, I can open a disassembler and immediately figure out the cause of the bug. The same goes for a ruby developer who wonders why their queries are taking forever or a front end developer who doesn't know why their interface is dropping frames.

Any serious engineer should be able to fix these problems on the spot if tasked with it.

The engineers can't really do that for all cases [1]. Understanding abstractly what's going on at least a few layers up and down your stack will definitely make a front-end developer more productive, if by productive you mean able to complete a finished product rather than just a buggy first draft.

[1] http://www.joelonsoftware.com/articles/LeakyAbstractions.htm...

> While it may be perfectly acceptable to ignore the lower-level details when first learning some new technology, or even when using it for personal use only, that sort of ignorance is not acceptable when working on systems that are meant to be used seriously.

I'm a self-taught web developer. While I have probably picked up some programming fundamentals/best practices through experience I have very little interest in computer science or learning the low-level details of every technology I use.

I probably couldn't get a job at most SV/SF startups, but I run several WordPress sites that have millions of monthly visitors and that have traffic spikes of 100,000+ visits in 2-3 hours at least a few times each month. I'm paid very well and I don't need to apply rocket science to do a good job.

Meanwhile I have friends with CS degrees at hot VC backed startups using all sorts of crazy technologies and advanced programming techniques for sites that get maybe 100,000 visits a month.

If you ask me, ignorance is premature optimization, overengineering and hiring expensive people to apply skills you're nowhere close to needing.

I think you've benefited very heavily (a lot more than you may realize) from the work of people who did have more formal training, and who used that knowledge to build the systems that you in turn have built upon.

You're right, it does take much less effort and skill to run moderately high-traffic WordPress-based web site these days. That wasn't always true, though. In the 1990s and even into the early 2000s, it did take skill to get the most out of web servers with clockrates below 200 MHz, maybe 16 MB of RAM if lucky, very limited storage, and limited network connectivity. Specialists were needed in cases like that.

What you seem to consider "ignorance" is usually just considered "forethought" and "planning ahead" by those involved. It's easy to rail against so-called "premature optimization" until you've seen that kind of prudence prevent unexpected scalability disasters from happening. For a young company, like the kind your friends apparently work at, a little bit of foresight and effort at the start can significantly mitigate the harm that can come from unexpectedly large demand. In some cases this is what will determine whether or not that company survives and thrives.

> I think you've benefited very heavily (a lot more than you may realize) from the work of people who did have more formal training, and who used that knowledge to build the systems that you in turn have built upon.

And your point is? Am I supposed to create a shrine to the people who built the first microprocessor?

> You're right, it does take much less effort and skill to run moderately high-traffic WordPress-based web site these days. That wasn't always true, though. In the 1990s and even into the early 2000s, it did take skill to get the most out of web servers with clockrates below 200 MHz, maybe 16 MB of RAM if lucky, very limited storage, and limited network connectivity. Specialists were needed in cases like that.

I'm sorry but it's not 1999. I can't imagine anyone winning a potential client over today by saying "You couldn't do in 1999 what you're doing without someone like me" or "I will architect your website so that it can run smoothly on a server with 32MB of RAM."

> What you seem to consider "ignorance" is usually just considered "forethought" and "planning ahead" by those involved.

So struggling to hire (because you're looking for overqualified candidates a lot of whom don't want to work on a simple website with less than 100,000 visits per month) and increasing your burn rate by paying $140,000/year fully loaded for web developers you can call "engineers" is "forethought" and "planning ahead"?

I know enough people who have worked at typical VC backed startups to know that most of them never grow big enough to have the kind of scalability and performance challenges they'd all like to believe they're going to have. And as a practical matter, if you look at the great companies that have emerged in the past decade (think Facebook, Twitter, etc.) and how their systems have evolved as they scaled, it's pretty clear that if you become a massive success, you're going to need to substantially rewrite your code base anyway and by that time you won't have to hunt for the highly technical engineers you need. They will be knocking on your door.

The biggest risk to just about every new startup is not having a developer who is a little too friendly with an ORM and who might have to turn to StackOverflow for help with a complex SQL query. It's getting a good enough product launched before you miss your market window and/or run out of cash.

"When I write my HTTP Applications I don't need to understand all the Network Layers beneath it."

If you want your HTTP application to perform well, be secure, be scalable, work with a multitude of browsers in unusual conditions, and be able to troubleshoot weird errors, then yes, you will at some point need to know something about TLS and TCP and IP (v4 and v6) and even Ethernet and Wifi.

Similarly, architects and engineers have to understand how the materials they're planning to use are made, what their capabilities and limits are, and how they can best be used to implement their vision for a building or a bridge. They can ignore how the bricks are made and how they perform, but their structure will not last.

Did you ever consider that a lot of the work being done by developers today makes them more like plumbers and electricians than architects and engineers?
> Similarly, architects and engineers have to understand how the materials they're planning to use are made, what their capabilities and limits are, and how they can best be used to implement their vision for a building or a bridge. They can ignore how the bricks are made and how they perform, but their structure will not last.

Np, they don't. At least not to the degree that some people here think programmers and software engineers should know computer science topics and various levels of abstraction. As an electrical engineer, if I had a custom transformer I needed the spec sheet and evidence that the parts met said spec sheet. The spec sheet had basic electrical and physical parameters along with relevant composition information. I didn't care what exactly the core was made of unless it was specified; I certainly didn't care how the core was cast and milled, how the coils were wound, how the casing was added[1], or what the casing was made of[2]. I didn't care about the details of how out custom or off-the-shelf ASICs were made, only that they met the stated specs. I needed to know how they functioned in the circuit, how they interacted with each other, how the spec tolerance on different parts affected the overall operation. If I had a problem that looked like a lower-level issue, say an ASIC that may have switched manufacturing processes without the manufacturer telling us, I worked the issue at our system level and let an ASIC specialist handle the nitty-gritty details as necessary; the ASIC specialist similarly relied on me to handle the board-level issues.

I was going to give a civil engineering example with concrete, but I'll cut right to the chase. Computer science, misnomer that it is, is a very broad subject area. As it matures, it continues to get broader. At some point, we as an industry, and to some degree the academic community, need to realize that the subject area is too broad for everyone to know everything and that people need to specialize. If I want to build a radar system I need as a minimum: an RF engineer who understands the gory details of RF transmission and RF semiconductors; a power engineer who understands the gory details of DC power conversion and distribution; an electronics engineer who understands the gory details of mixed-signal board design; another electronics engineer who understands the gory details of high-speed digital board design; a firmware engineer who understands the gory details of FPGA and CPLD design; and an ASIC engineer who understands the gory details of analog and mixed-signal chip design.

Everyone I just mentioned will have one or more degrees that say "electrical engineering", and many may only have a bachelors. Each engineer certainly understands the basics of what the others are doing, but each is still a specialized engineer. They are NOT interchangeable. You cannot hire people for their generic "electrical engineering chops" the way Google and its cargo culters hire software engineers, even straight out degree programs. Every electrical engineer cannot know everything equally well, and once you start working and specializing through experience it just gets worse. The sooner this industry realizes that software engineering is not different and that complex software projects need specialist teams coordinated with proper systems engineering[3], the better. I firmly believe that most of the "talent shortage" right now is an artifact of companies looking for people like you describe, people who know everything and can move freely up and down the stack. That is increasingly impractical and not nearly as efficient as getting people to specialize and work together effectively in multidisciplinary teams.

[1] These were fully-encased transformers.

[2] Again, unless we specified something specific.

[3] http://www.incose.org/

This! This is the first comment I've read in this thread that's dealt with the core issue.

We, the world, don't need millions of people who can write a good sorting algorithm. A few thousand will do. We need millions of people who can use the sorting algorithm that those thousand people wrote, to build things higher up the stack, and billions of people who can use the things those millions of people wrote to do their work.

As you go deeper in the stack, fewer people ever need to understand it, and they will be paid more and more. We don't need more computer scientists and sorting algorithms. One good solid sorting algorithm is fine. The whole idea of evolution is we build on the successful developments of previous generations. We don't need to know how a lightbulb works, we just use it to illuminate the desk while we write a paper on genetics.

I don't think we should train kids to be computer scientists — the really talented ones will do it anyway, and the number of people entering this field will continue to grow for the foreseeable future — I think we should train them to be lawyers and doctors who understand code. To a level where can throw together a solid working solution to a problem they have, without having to go to a programmer who may not have the deep subject knowledge that allows a novel solution. If the doctor can code, they can iterate on their idea in a way that just isn't possible if someone else is developing it for them.

Excel and macros etc are the beginnings of this, but it'll go further — at some point JavaScript or Python will hopefully be prevalent.

Excel and macros etc are the beginnings of this

One of the startups I'm CTOing is working on exactly that problem, or rather, has worked on it and is commercializing the solution.

Logo[0] (the language for children) is actually more complex and abstract than what we've got, which isn't a language at all, but closer to a spreadsheet for code, except...people don't even know they are coding, much less using what everyone here would call a debugger. They're just doing stuff that, if you were a computer scientist, you would recognize as coding.

I'm pretty excited about it, we're beta testing with an 800 person company in Australia at the moment, and hope to go into a general release over the summer. I think it's similar in significance to the business world as the spreadsheet, which allowed non-programmers to do number crunching. Our stuff allows non-programmers to do the vast majority of business automation and back office coding being done today.

[0] http://en.wikipedia.org/wiki/Logo_(programming_language)

When you build a skyscraper you don't need to design ever brick, but that is the wrong analogy. You do need to understand the properties of the different bricks so you pick the right ones, and use them properly, otherwise the building will crumble under its own weight.

If you write a heap sort algorithm you don't need to understand it in assembly... Except if you need to optimize performance. If you ignore the network stack while you write an HTTP app, you might not know how to protect from a man in the middle attack, your particular app would not need it... But maybe the next one does. You might not understand how chrome and Mac OS works... But then if pop ups start to appear you will not know what to do.

While some levels of abstractions make things easier to deal with, programming is more about process building than specific tools, and I feel that the original article got right