Hacker News new | ask | show | jobs
by dkarapetyan 3943 days ago
Here are some heretical thoughts. The language is irrelevant. The text editor is irrelevant. The OS is irrelevant. The size of your monitor is irrelevant. All your productivity hacks are irrelevant. The only relevant thing is your ability to formulate and solve problems.

You might say the language can help with both the formulation and the solution but I'd say that just comes down to what language you're most comfortable with and how good of a problem solver you are. So you can use lisp and I'll use ruby and at the end it'll all be a wash because the fundamental bottleneck will always be the speed at which you can formulate and solve problems and how quickly you can respond to market dynamics. All other choices are accidents of history.

Graham and his buddy were just good problem solvers.

10 comments

Irrelevant might be too strong of a word. Yes, it might not be as significant as your own problem solving skills but they are still important. You have to remember that tools chosen by you to solve problems.

You wouldn't say what tools you use to build a house is irrelevant only carpenter's skills.

Picking the right tool for the right problem is part of problem solving. Sometimes picking the right tool might boil down to what you are most comfortable with, or sometimes it might be learning a tool that you are not familiar with.

(Of course, you shouldn't flock to a particular tool just because someone else said so.)

Anyways, picking the right tools are important part of your problem solving skills.

Graham and his buddy were good problem solvers who picked the right tool for the problem that they were solving.

> but I'd say that just comes down to what language you're most comfortable with and how good of a problem solver you are.

Techniques and concepts influence your ability to reason about problems.

If you don't understand dictionaries (hashes), or trees, or macros, or reflection, or first class functions etc, then you will think about a problem very differently.

If you understand the concepts then you can usually get away with not having those features readily available in your language.

For example if your language doesn't have strong macro support you can get away with using code-gen instead.

Likewise if your language doesn't have built in dictionary support, you can get away with rolling your own, or finding a library that adds it.

Or if your language doesn't support first class functions you can often get away with patterns like the command pattern instead.

But if you don't understand the concepts then your ability to think about the problem becomes much more limited.

But why would you want to use a language that didn't have such things? Not having lexical scope, first-class functions, and macros is a huge hinderance to me. Sure, I can work around it, but it's a terribly inefficient and unsatisfying way to work.
That's why CS matters.

Anyone with a good CS background can think abstractly in terms of algorithms and data structures, instead of focusing in language X with feature list Y.

But languages differ in how much of that they abstract away from you. If the language already does a lot of those algorithms and data structures with minimal syntax, the CS guy can think on an even higher level of abstraction.
There is not much more level abstraction than lambda calculus, logic, denotational semantics and similar though processes.

But I get your point of not having to deal with low level details.

You'd be surprised - there is an infinite hierarchy of abstractions above the primitive level you're talking about.
Algorithms and data structures are on a too low level of abstraction in order to be useful in solving real world problems. Most problem domains are not expressed in terms of algorithms and data structures, they're rather formalised as languages.
Heretical or not you are dead wrong. Don't think so? Go program in Forth or Assembler instead of your current main language for a while and get back to me. There would have been no reason to invent any HLL or even assembler if you were correct. Put aside your ruby and try to do the same work in vanilla C and get back to me.
I think you're taking his point too literally. Yes, you can find a pathological interpretation of his words and beat that up. But his point is that most of the arguments people have here over language choice are irrelevant, because whether you're using PHP or Python or Ruby or Scala or Go is not the bottleneck in the system.

Personally, I agree. I've never seen a bad team succeed because of a good language, and I've never seen a good team fail because of a bad one. We argue over languages not because it makes or breaks companies, but because that's the most obvious feature of our days. We form tribes around languages the way non-programmers do around sports teams, and as with sports teams, minor differences get blown up into major social divisions. It's our own version of the streetlight effect: https://en.wikipedia.org/wiki/Streetlight_effect

I'm all for people arguing about language features when they are actually designing languages. But as far as building businesses around software, I think "Language X is a secret weapon" is absurd. If a good team picks something they're happy working in, then the biggest problem with a project will almost never be the language they picked.

I think that's wrong for at least some contexts, because - for example - Python is so slow that it can literally become the bottleneck on any non-toy server. So unless you're running a one-person blog or don't carDjango should probably not be your first choice for a scalable production server.

People argue about languages because they all have different trade-offs for performance/efficiency, initial development time, developer cost, developer availability, and maintenance.

The differences are real, and they have real effects on the profitability and the prospects of success/failure of any project.

Management quality and culture do too, obviously. But you can assume that for a given level of management competence, different languages will still create different business outcomes.

Can you give an example of a company that failed because somebody chose Python? Or even one with materially worse business results, say a 20% reduction in revenue?

My guess is no, because people make fine businesses out of nominally unscalable technologies all the time. Rails is a notorious performance pig, for example, but there are plenty of successful businesses built in it. When server bottlenecks become an issue, modest performance tricks and ops magic are applied, and suddenly per-server performance is no longer the problem. And still, despite being a pig, Rails is a great place to start, because its real power is not CPU efficiency, but ease with which you can get something workable up and then iterate.

There is no language that is so fast that it's infinitely scalable out of the box. Every software company that grows hits performance problems with naive uses of the tools at hand. Every successful one figures out how to make things work. And making technologies serve the human purpose at hand isn't a characteristic of good languages; it's a characteristic of good teams.

Forth is as high-level as you'd like it to be.

http://www.colorforth.com/POL.htm

Indeed, a strange one to pick. I'd even say that if portability isn't a concern, working with x86_64 assembly is quite pleasant. If you avoid the lure of premature optimization, and stick with either function oriented, or at least procedure oriented programming, without too many long jumps -- I think you could get on quite fine in assembly.

The biggest issue, might be one that (sadly too) many low-level languages share: with the move to UTF-8 as the only sane choice for text, there are no string/char datatypes any more. No reason one can't use procedures/functions to deal with strings in assembly, but it would require a bit more planning than in a language that have "native" UTF-8 support.

[ed: I think Kollibri OS proves both points: it's a working OS, but they've yet to port from 32bit to 64bit even though they upstream they forked from (Menuet OS) has a 64 bit version (that's not Free software/open source).

http://kolibrios.org/en/

Another "big" asm OS project is: https://github.com/ReturnInfinity/Pure64 ]

Forth should not be in this list, it is a meta-language. It can be quickly turned into something equally or more powerful than you current Blub (pick any, does not matter).
"Quickly" without writing tons of Forth code, not. And it still wouldn't match 200.000 npm packages or a million or so for Java.
5-6kloc is not "tons", it's just several days worth of work. And then I can build a compliant JavaScript implementation on top of this, in order to be able to parasite on 200k npm packages (actually, did this already).
>5-6kloc is not "tons", it's just several days worth of work.

To buy you what? Not even what the Java SDK has as built-in libs. And 5 kloc in "several days"? I doubt it.

>And then I can build a compliant JavaScript implementation on top of this, in order to be able to parasite on 200k npm packages (actually, did this already).

Link or it didn't happen.

Besides, there's no point in using Forth if you're gonna end up running your stuff in a "compliant JavaScript implementation" (which takes much more than "several days" anyway).

> To buy you what?

To get a powerful core language on top of which I can build anything in just a couple of hundreds of lines (e.g., a complete JavaScript - in order to get the rest of the libraries for free). Or a JVM. Or .NET CLR. Or whatever else.

> And 5 kloc in "several days"? I doubt it.

I did this as an experiment once. From bare machine code on a new architecture, via a very basic Forth, to Lisp and then C and everything else. Did not take much time to do.

> Link or it didn't happen.

Did not publish it yet for a variety of reasons, but may include this JavaScript compiler in my next code drop soon, stay tuned (see my github).

> Besides, there's no point in using Forth if you're gonna end up running your stuff in a "compliant JavaScript implementation"

The question was that having only Forth would not leave me crippled - I'll get all the power I want in just few days. And this kind of JavaScript implementation is more than just JavaScript. It allows me to use anything coded in JavaScript seamlessly from any other language built on top of the same meta-language.

" I think Lisp still has an edge for larger projects and for applications where the speed of the compiled code is important. But Python has the edge (with a large number of students) when the main goal is communication, not programming per se. In terms of programming-in-the-large, at Google and elsewhere, I think that language choice is not as important as all the other choices: if you have the right overall architecture, the right team of programmers, the right development process that allows for rapid development with continuous improvement, then many languages will work for you; if you don't have those things you're in trouble regardless of your language choice."

- Peter Norvig

https://news.ycombinator.com/item?id=1803815

I doubt this. Looking at some stuff done in C - a ton of time is simply wasted shuffling bytes around and fixing the resulting memory issues.

If your point is that language alone isn't gonna decide much, that's probably mostly right. FB used/uses PHP. Harry Potter was written on pen and paper. I don't think either is much of an argument about tools.

You are absolutely right. However, if you use a cluttered language with a dozen choices for a data structure or concurrency (as far as I know Ruby is not one of them), you'll run into many accidental problems before you even get to solving your business domain problem.
It goes hand in hand. Back in the days people said lisp in newbies hands will be backfire, but handled by those with abstraction skills it will give you ability to express things you cannot with other systems.

Many here agree that technology should not matter, but it does at one point. Some trait of the culture behind and around languages are very very important. Lisp tree recursion, "lexicality" and ad-hoc genericity is not present in other languages. Immutability in the ml land (even though side effects are permitted in some) is also something few people have to live in and understand.

Both these things give you new idioms, hints, point of view about how to solve problems. It also sheds light on the other ones.

I'm not really a programmer. All my training is in abstract math so whenever I see people arguing over language X and Y it always seems weird to me. I don't write code until I've sketched things out with pencil and paper and by necessity I have to disentagle the syntax of the language from the essence of the problem. Turns out when I do things that way translating the solution back into a language X ends up being the easy part and it really doesn't matter what the target language ends up being. Adding macros and types just shifts how I encode the solution and in no way affects its abstract formulation.

So I don't think it goes hand in hand. The fundamental bottleneck is always what's in your head.

> just shifts how I encode the solution

And this is actually the most important thing in industry software development.

It affects:

1. how easy it is to modify an existing codebase: eg., can you add feature X before your competitor even after you app grew to 1M LOC?

2. how easy it is for a new developer to start working productively on you codebase

3. how stable your software is: do modifications introduce subtle bugs that make the whole thing more and more unstable until it becomes unusable?

4. how secure your software is: how easy (read "cost effective") is it to write secure code without having to take 10x longer to do this?

From a business perspective, the "fundamental bottleneck is always what's in your head" problem can always be solved by temporarily hiring a few super-smart consultants with "bigger heads" that can get over this bottleneck, the rare times when you have the problem...

The rest of the time, the "shape of your code" is 100x times more important than the abstract formulation of an elegant solution. Because what you do 99% of the time is "re-shaping" existing code to do slightly different versions of what it already does, not solving interesting problems...

So yeah, at this level, languages can make all the difference!

This is approach is great for greenfield development, but when it comes to software maintenance I find myself having to think in terms of the target language so that I can formulate the right long-term solution for the codebase in question.
Yes, this is true. For maintenance projects I've noticed that before I can sketch things out I have to translate the existing codebase into the proper abstract domain but in my experience this is just an extra step and does not negate the general approach of thinking in a domain that is completely free of programming language related issues.
But depending on the language you intend to use, you may approach the problem from a different angle. A Lisp solution may look very different from a Python or C solution.
The same is true in maths as well.
A way from your formal specification of a solution down to a particular language set of features can be enormously long.

A trivial example can be translating a formal grammar - codified as just few lines of BNF - into a low level language (say, C, or Java). Good if your grammar can be expressed as recursive descent directly, and even in this case you'll end up spitting out hundreds of lines of code, most likely making a lot stupid mistakes.

So, language does matter a lot. BNF is a right language for this task. C or Java are not right, period. Programmers should not waste their precious time translating abstract concepts down to the boring languages minutiae - they must always use the same level of abstraction as their problem domain requires.

> I'm not really a programmer. All my training is in abstract math

Back in mainframe days, that training would've been the easiest way to get work as a programmer. Nowadays, much "programming" is gluing together pre-written open source stuff using glue languages like Bash, Javascript or Groovy by staff who entered programming as business people transferring from other departments then left a big mess for someone else to clean up when they used their embellished experience to get another job, probably with "architect" in its job title, somewhere else. If you've done any hobbyist stuff using something like Lisp or Haskell, then think twice before saying you're "not really" a programmer.

> and by necessity I have to disentangle the syntax of the language from the essence of the problem.

Doing that is why programmers prefer different languages, some language allow that to be easier than others do. Some language allow a much more direct expression of the essence of the problem.

> Adding macros and types just shifts how I encode the solution and in no way affects its abstract formulation.

Sure it does, it allows you express the abstract formulation more directly with less syntactic fluff. Ideally you wind up with a DSL that allows the problem to be solved as tersely yet readably as possible.

In my experience, the more interesting reasons to choose languages come from the "platform and ecosystem" categories rather than syntax.

Lua: It has clean, clear syntax but its real value is the implementation, which is geared towards use as an embedded language.

Javascript: The language isn't bad but were it not for being the browser scripting language it never would have gotten so popular and tools like node.js probably wouldn't even exist.

Java: Native language on the powerful JVM.

C/C++: Direct access to various operating system and hardware libraries not available anywhere else.

Perl: Deployed widely on unix systems making it very useful for scripting and system administration.

SQL: For querying relational databases.

Granted, within each category, you might have syntax preferences. I would never use Ruby or Perl if I could use Python, for example. I prefer JSON for serialization(robust and simple) but for manually encoding a complex data structure, YAML is far more comfortable. That's all syntax. But picking the right language for a job usually requires going beyond the syntax.

> In my experience, the more interesting reasons to choose languages come from the "platform and ecosystem" categories rather than syntax.

I agree, but that doesn't have anything to do with what I said. I didn't say anything about choosing a language for a particular job, I said what makes programmers prefer a language which is very much syntax.

> Javascript: The language isn't bad but were it not for being the browser scripting language it never would have gotten so popular and tools like node.js probably wouldn't even exist.

If it were not for being the browser scripting language, it would not exist, so any reasoning beyond what it might have been otherwise is fallacious as it would not have been at all.

> Java: Native language on the powerful JVM.

Nope, portability across platforms made it popular.

> But picking the right language for a job usually requires going beyond the syntax.

Not disputed, but still unrelated to my point which is about syntax. I'm discussing syntax, it's off topic to and rude to tell me not to discuss syntax which is basically what you're doing.

I was not attacking you. I just used your comments about syntax to make a point more relevant to the thread started here: https://news.ycombinator.com/item?id=10183420
> I'm not really a programmer.

The real question is do you understand how a computer works. There's mapping a solution into a programming language, but programming language is just a tool to help with the real goal which is to map the solution to the computer itself.

> The fundamental bottleneck is always what's in your head.

Expressing a correct solution in a programming language is just the first step. It also has to be performant, usable, and accessible. Language choice usually has implications in those categories.

This works for small programs you write on your own. Even then, the kind of problems you even try to solve in Matlab are different from the ones you try to solve in JavaScript.

But in business, you often program within some framework (which makes some things easy, other things hard), glue together tons of open source libraries (what's available in different languages differs a lot), and you work on huge codebases in teams (and different languages get in your way in different ways).

I have a good CS background and follow a similar approach.

We were lucky that back they excel in throwing all the paradigms at the students and have enough lectures about pure algorithms and data structures regardless of the language.

I wonder if Graham was presented with the same problem today, will he pick a lisp and write everything from scratch or pick up a less "expressive" language because it has a strong and mature ecosystem of libs.
The reason Paul Graham used Lisp is it was the only reasonable way at the time to implement RTML, which was the HTML macro language with online editor that Viaweb was built out of. RTML was how every website in Viaweb was constructed, it is what allowed them to move quickly and customers to customize with unequaled flexibility.

It was their key competitive advantage and Lisp was critical to its creation and function. It would be foolish to attempt to implement RTML in something else. Perhaps slightly less foolish in 2015 but not by much.

You can have your cake and eat it. It's possible for Lisps to use library code in less expressive languages, such as C, via a variety of mechanisms (foreign function interface, extending the virtual machine, ...). If you want access to Java libraries, you can use Kawa, Clojure, or Armed Bear Common Lisp.
There's a solid trend to do that, Norvig wrote a lot of recent articles in python, colleges are replacing Java with it too. Lisp genes have spread so it's not as alternative as it used to be. That said, SBCL seems to have possibilities and performance unmatched by all the tiny trendy languages of the day (except for v8 maybe and lua maybe).
At the time when PG was solving a web development problem, web development problems were "new and interesting", so it made sense to use a Lisp.

Nowadays it probably doesn't make sense to use Lisps for web, but it would absolutely make sense if you are solving something that is actually a new and interesting problem nowadays...

If your startup is dependent on solving chicken and egg marketing problems the choice of Lisp vs. something else is fairly irrelevant as you said. This is the case in most startups that take a traditional business (e.g. Taxi) and modernise it (e.g. uber). The level of tech required to do that is not going to be cutting edge. It is quite rote to solve these things in RoR or PHP.

On the other hand there may be some startups where the choice of language really matters. One thing I can think of is how a lot of Enterprise software is a big feature fest with massive complicatedness coming from a mixture of the real-world muckiness of the problem, and poor architectural choices. Such shops require armies of programmers to maintain their bloated wares. Maybe a startup with a much more thoughtful approach, using a Lisp/Haskell/etc. type language and a small number of developers can have a big competitive advantage.

Customer "we need a new feature". Startup "sure we'll add a rule and you'll have that tomorrow". Old business "that will take 3 months and cost $1m"

I think you're making the case for language irrelevance even more. The reason big corp. can't move fast isn't because of their technology choices. It is because of all the bloatware and bureaucracy. You can be bureaucratic and bloated in any language.
But in some languages bloat is a best practice.
It's all about how many adjectives you can get into your class name. e.g.

   SingletonFactoryAdaptorFacadeProviderEnumerator<BridgeAbstractFactory2_Hack> myClass;
With Haskell it is about how big your monad stack is

    StateT ReaderT WriterT LensifierT MaybeT BeerT (IO Int).
Monad stacks are so last decade.
So this is why the golang community prefers:

    for c := range(ns) {
        // some blah
    }
The golang community likes being safe:

  a, err := doFirstThing()
  if err != nil {
    return err
  }

  b, err := doSecondThing(a)
  if err != nil {
    return err
  }

  c, err := doThirdThing(b)
  if err != nil {
    return err
  }
until your keyboard keys go off.

(and I'm a happy gopher myself)

Oh, small typo (I think): no parens around (IO Int).
I'm not sure that matters either.

Let's say you're talking about Java. A "bad" team will have mountains of code. A "good" team will apply Greenspun's Tenth Rule and use a lisp to compress down the mountain to the extent that "lisp" can compress it over Java.

You may protest that the lisp has angle brackets and that it's inferior to say Clojure, but the machine does not care.

Yes because the causation goes the other way.

The kind of org that cares about how it writes software will choose the right tool for the job, which may be Lisp. However they may be able to achieve their aims in Java. Whatever they choose it would have been carefully considered.

The kind of org that doesn't care how it writes software is unlikely to choose an outlier language and will use C#, PHP, Java etc. because it is easier to hire devs and you won't get fired for choosing it.

> The only relevant thing is your ability to formulate and solve problems.

The maximum level of abstraction available for your language is indeed a hard upper limit on how you formulate and solve problems. Solving a complex problem on a high level of abstraction can be trivial, and the same problem may be nearly impossible on lower levels.