Hacker News new | ask | show | jobs
by woah 4567 days ago
I look at this from the other side as well. I've worked with brilliant people with ivy league CS degrees who wrote much messier and less maintainable code than me, an autodidact designer/js dev with 1.5 years of experience. Maybe I'm wrong, and there was something in their code that I wasn't seeing, but I don't think so.

There can also be a bit of an attitude, like the person is thinking "of course this is good, I went to Stanford". But maybe that's my imagination. Another explanation is that these people are just so good that they are able to read messy and convoluted code no problem, and us mortals need to step up our game.

On the other hand, these people would easily be able to reason about complex performance and security issues beyond me. I think that the hardcore CS issues are a science, while writing clean code in a web framework, browser, and API design is more of a craft.

If you hire too many computer scientists, your code base could be full of fascinating technical tricks, but creaky and hard to work with. Too many craftsmen, and you'll get stuck on simple problems. It's a balance.

EDIT: Downvotes? Please explain. Perhaps I am not able to fully comprehend the issues at hand.

12 comments

People in academia simply don't care about the quality of one particular implementation of their ideas. There's no value judgement here, it's just not their job to write and maintain good software. Just as it's not a mathematician's job to maintain a cryptographic protocol or a physicist's job to keep a satellite in orbit. The people who went to schools with strong research programs are trained by people in that mindset.

It's a simple question of motivation. If they're brilliant and they have motivation, then of course they could write great software. They just don't.

Make no mistake, people from schools like Cal Poly SLO (a state school, and my alma mater) who excelled in their CS programs can software engineer circles around most. Why? Because Cal Poly has no research program, three quarters of their faculty come from industry, and their faculty have no job requirements outside of teaching. They literally had us managing five to ten thousand line software projects with teams of students in year two.

While I'm following you ideologically, I'm not sure that this idea bears fruit in evidence. The computer science community still uses large numbers of algorithms (via libraries) that were written by academics, in peer-reviewed journals, in Fortran, in the 1970s.

Even currently, a tremendous amount of the cutting-edge work in optimization and others is done at the university level: METIS for graph partitioning, and convex optimization work being done by Stephen Boyd et al. They care deeply about the implementation because quality and speed of solution are of utmost importance. A number (like Geoffrey Hinton and Sebastian Thrun) have moved into the private sector, but after contributing a lot via academia.

I thing the problem here is you're comparing apples to oranges - the people writing code in the 70's are not the same type of people teaching students to code now.

In the 70's it would have been physicists, mathematicians or engineers writing code to solve a problem for them and their colleagues. Their code needed to be maintainable so they could share it in their academic community, and get things done with it.

Today, the people teaching computer science view code as the proof of concept. Much of the work is in the idea behind the code, and the code is just proof that it can be implemented in practice - and most importantly, isn't designed to be actually used.

The idea that the code is just the proof of concept then carries over to the students, and the mindset becomes not, "let's build this thing to do X', but "can we build a thing, in way Y to do X".

Have you ever seen Hinton's code before? It's all Matlab :) And when you are designing/prototyping algorithms, that is quite good enough.
That last bit sounds amazing and highly valuable. I go to a well regarded top CS school and I regret that we don't have something like that in our curriculum that forces people to write multi-thousand-lines of code with a team and maintain it.

Our EE program has something like that where you choose a team and build something with them over the course of a semester while having an "advisor". At the end you make a report and present it to the advisor and the rest of the committee. It's a requirement for graduation. I think that's awesome and CS definitely needs something akin to that.

Science != engineering.

Engineers take what scientists discover and create and design solutions based on that. Computer science is not about engineering a large software solution. Rather it's about discovering and creating algorithms and techniques that engineers can use to design solutions.

Much of the comments to this article seem to be happy to mix the roles of "technician", "engineer", and "scientist" when they are in fact very, very different.

Your definition of engineering may have been appropriate around the time of the industrial revolution when an engineer was literally one who built steam engines, but modern engineering in the academic sense under discussion here is absolutely a science.
Wikipedia describes "computer science" as an umbrella term covering everything pertaining to software development and algorithmic thought. Academic computer science programs generally offer courses in both the theoretical and the applied.

Even the very term itself has often been described as a misnomer, not necessarily having anything to do with "computers" or with "science".

I think the reason people mix such things around so much is because what "computer science" is has been ambiguously defined all along.

The truth is, CS is not a "science" like biology or physics.

It is an education in understanding computation and software development.

I'd also argue it is not an engineering discipline either. It's unfortunate the terms "Computer Science" and "Software Engineering" were ever accepted. They're holding us back; we're stuck in an outdated view of the subject.

I kindof disagree. For example while studying UML, it became more and more apparent to me how legitimate it is to have the word "science" in "Computer Science". Being able to create a high-level framework that is general enough to apply pervasively to IT systems is not a trivial matter, and requires considerable academic effort and creativity. The domain may be different from biology or physics, but the methods of obtaining that"understanding" you mention are strikingly similar (which accounts for the reliability of the results that are delivered).
There are certain aspects of engineering which are definitely science. Science really is just the production of new knowledge with hard facts.
Engineers are Scientists with thumbs was what I was told when I worked for a RnD organization on CIT's campus.

The corollary to that is "but the technician is the one who really understands it :-) "

My job as a software engineer involves a mix of all these things. Not a lot of heavy algorithm development, but definitely some.
Engineering utilizes science. But not many engineers need to know as much as Knuth.
Hm that's a fair point.
Depends on the course.

I studied a bachelors in molecular biology, took a few years out (realised I didn't like the subject much) and studied a one years masters in IT a few years later. It was taught by the Computer Science department (Glasgow University in Scotland), but the focus was on writing good quality software - readable, maintainable, usable code.

There was an optional data structures and algorithms course which I assume is more geared towards traditional comp science. I took it, but in ten years of work, I rarely use this stuff (though its good to have a background so you know which library is a better choice).

One thing they didn't teach us was networkinq, which I am completely self taught. I can get stuff working, but I think having a formal education in things (like I do in OOP) can teach you where to focus to get things done in a professional manner.

Also maybe some other reasons for downvotes:

- 1.5 years experience isn't very much to base an opinion like this on

- Finding other people's code hard to read is pretty common, no matter how good those coder's are. Your own code generally makes perfect sense to you, same as your writing. But communicating so that all can understand it is hard. That's why flame wars occur. You probably think your comment is a reasonably argued piece of writing, just like you think your code is nicely refactored and understandable. The fact that people disagree and downvote proves the point I think.

And when you've been writing code for decades, it becomes quite evident that "those other people" can easily be your past selves.
> I look at this from the other side as well. I've worked with brilliant people with ivy league CS degrees who wrote much messier and less maintainable code than me, an autodidact designer/js dev with 1.5 years of experience. Maybe I'm wrong, and there was something in their code that I wasn't seeing, but I don't think so.

I would have ignored your comment were it not for you mentioning that you write javascript. I started learning it on and off a few weeks ago, and yesterday I installed spidermonkey as a standalone shell. What I have noticed is that a lot of the syntax that controls flow is very similar to C, which is notorious for being gibberish. I'm guessing the same will apply to js. I do not have a CS degree, but would you say that this is readable? This is a function for extraction of nodes in a double linked list that I am currently kicking into shape.

  /*
  *	extract *p__ from p__.
  *	but original *p__ is shifted left or right \
  *	    if there is still space.
  *	extracted ndi* is returned, but the remainder of the list \
  *	    is sewn back up.
   */
  
  ndi *extract_ndi(ndi **p__, const int dec) {
      ndi *q_=*p__;
      if(dec>=_PREV_) {
	  *p__=*(q_->lnk+dec); /* the shift */
	  if(*((*p__)->lnk+!dec)=*(q_->lnk+!dec)) { /* sew up */
	      *((*(q_->lnk+!dec))->lnk+dec)=*p__;
	      *(q_->lnk+!dec)=NULL; /* burn ends of extraction */
	  }
	  *(q_->lnk+dec)=NULL;
      } else if(dec==_LONE_) /* final possibility is that *p__==NULL */
	  *p__=NULL; /* ie. dec==_DEAD_, no which ain't it not worth man */
      return q_;
  }
What the hell was I smoking when I wrote this? I can't even read it myself.

Writing convoluted code is more to do with a certain state of mind. You should ask your coworkers where they obtain LSD, not where they got their degree. I haven't come across any acid for about a dozen years, I think it has gone out of fashion.

Of course if this was Perl it would be even worse.

> What the hell was I smoking when I wrote this? I can't even read it myself.

It's what you get for being lazy (non judging here, I'm guilty of it too) and not naming your variables accordingly. When you write the code you probably know what ndi, q, p, lnk, etc. are supposed to mean. But then you leave the code for some time and when you return you are lost. Just write out variable and function names so that your code reads like english - programming Obj-C for some time really helped me there :)

And with pointer-heavy code I tend to create aliases for offsets so I don't have to write out things like *(q->lnk+!dec) every time I reference that specific address.

Yes, maybe it will cost me wizard points with colleagues because they start to understand my code but my sanity is it worth to me ;)

(Also trailing/leading underscores are the devil!)

I'll confess, it is deliberately obfuscated. *(q->lnk+!dec) and the like were originally written in macro.
> Of course if this was Perl it would be even worse.

Sigh. Sadly, it has become fashionable to bring up Perl only to ridicule it even when there is absolutely no context or need.

Take a look at this implementation [1] of doubly linked list in Perl. Tell me how that is worse [2].

Now, I will go back to my corner to being productive using Perl or whatever language I need.

[1] https://metacpan.org/source/LEONT/List-DoubleLinked-0.003/li...

[2] Of course, I have no way of knowing if it is an exact or even close translation of your code, but it does implement doubly linked lists.

> Sigh. Sadly, it has become fashionable to bring up Perl only to ridicule it even when there is absolutely no context or need.

A lot of people ridicule C, I just laugh my head off.

Apologies, I assure you that I am not ridiculing it. The elegance of a language is not my concern. In fact, your comment has made me decide to put some effort into learning a bit more Perl, but I will have to find some time.

What I find when I work with "pointy" data structures is that it really, really helps to draw diagrams to clarify your thinking. I can write a doubly-linked list extraction with my eyes closed (and it'd probably help to do it with closed eyes, since I can more easily picture what's going on) but it very likely won't look anything like yours... what's dec for? And all the extraneous underscores in the variable names, I don't see why you need them. What's wrong with p and p?
Drawing diagrams is one of the most useful teaching strategies I've found when people are just starting to learn pointers. I've TA'd a course that introduces students to C++, pointers, and basic data structures, and after five semesters, I'd say that it's the single most helpful thing I've found when they are first trying to wrestle with pointers. (They get to implement a doubly linked list.)
One underscore indicates a pointer, two indicates a pointer to pointer.
The code was a little convoluted, but those comments totally cleared things up.
Sure, "/* ie. dec==_DEAD_, no which ain't it not worth man */" really cleared things up.
If you think that snippet was bad, you should see the rest of it. It covers nine files and around 500 odd lines.

Good practise though.

A little whitespace goes a long way. Were the list elements also stored in sequence in some array, or is ->lnk a two-element array with the forward and backward pointers?
The latter applies here, this is the node:

  typedef struct dll__ {
      struct dll__ *lnk[2];
      void *dat;
  }ndi;
I've seen some examples on the web, but I haven't seen it done this way. I have a suspicion it might be slower than the traditional technique, but I'll have to check that. What is not evident from the code snippet is that I'm trying to make the code handle both fixed end and looped lists.
So you never told us what you were smoking.
I cannot remember, but it was damn good stuff.
"If you hire too many computer scientists, your code base could be full of fascinating technical tricks, but creaky and hard to work with. Too many craftsmen, and you'll get stuck on simple problems. It's a balance."

Your whole post is full over hand waving and overgeneralization. You've never met a CS major who wrote clean code without resorting to fascinating technical tricks? You haven't met a non-CS major who did his or her due diligence to learn the mathematical fundamentals?

Please cut the hyperbole.

What do you expect? We're talking about someone sharing their personal experience, not their 5 year double blind statistically rigorous study. Take it for what it is. I expect HN to be full of people who can take information in, with a critical eye, without wasting time quibbling over quality. We know the quality of the information source (he states it at the head of the comment!), we don't have to rehash the basics, science, and sources of evidence for every comment do we?
Just my opinion, and I don't have much experience. I'm sorry if it offended you for any reason.
> I look at this from the other side as well. I've worked with brilliant people with ivy league CS degrees who wrote much messier and less maintainable code than me, an autodidact designer/js dev with 1.5 years of experience.

Be careful, everybody writes worse code than you, because you wrote the code. And these is a difference in writing nice simple code, and rewriting the same function to work on a bunch of different machines that does the core of the application, and you have until the end of the week until it goes live.

I think people are falsely equating computer science with software engineering. You can get a very strong theoretical basis for programming at a place like Stanford, and the work you can do may have nothing to do with best practices but rather a lot to do with more abstract concepts like algorithmic efficiency or graph analysis or what not. As a Stanford student personally Ive learned a lot more about best practices in software systems outside of the university; in fact you get very little of that from classes. What you do get is in depth coverage of topics that most are unlikely to get a formal treatment of on their own, depending on your concentration, whether that means cutting edge operating systems and compilers research, or rigorous discussion of the psychology behind ux design. Hope that clarifies a bit!
Plus, there are some things that I don't believe can be taught effectively in college. Stanford told me tests were good, but I didn't really believe it until I had to work on a legacy codebase without tests.

Best practices are easier to digest when you've experienced the problem they're meant to solve.

The more you get exposed to other people's code, the less likely you are to dismiss it as bad immediately. Your first impressions are built upon what styles of coding you're already familiar with, and aren't to be trusted as an objective measure of whether the code is maintainable. In many cases, what you might think is a good practice is really just a fashionable one, and holds little engineering value when examined carefully.

After enough projects, you get used to navigating codebases that are layered with multiple styles and grungy bits from years of effort. At that point, you have some hope of knowing what can and can't be maintained.

I'm guessing the downvotes are there (not that I downvoted) because there's absolutely no reason that someone with a CS background can't also be a craftsperson.

There's a difference in approach between academic CS and practical software engineering, yes, but a decent CS grad should be able to pick up both.

Sounds like you worked with people who just weren't as good as they thought they were at that part of it :)

This is totally true. I am honestly blown away by how little focus Universities have on coding as compared to Computer Science. I understand that the degree is called "Computer Science" and not "Coding/Programming".... But it would be immensely useful career-wise if they focused on at least some Coding aspects (style, readability, code-reviews, etc.).
It also makes you more successful in life if you learn to delegate work to other people, it clears your mind for a moment of brilliance and you can take all the credit when they are done with their labor. If life were fair our jobs would let us grow like in academia and but this is not the case in industry.
I'm a mechanical engineer, when I worked for a small manufacturing shop many of the best machine and fixture designs came from the machinists in the tool room. We tried to achieved the balance that you're talking about by having the machinists and engineers collaborate closely.
I think coding is neither science nor engineering. I like the term "craft" much better.