Ask PG: Lisp vs Python (2010) - kung-fu-master It seems that a lot of old school Lispers switching to Python (for example: Peter Norvig). What do you think on Lisp vs Python today? <comment><USER3> Peter Norvig here. I came to Python not because I thought it was a better/acceptable/pragmatic Lisp, but because it was better pseudocode. Several students claimed that they had a hard time mapping from the pseudocode in my AI textbook to the Lisp code that Russell and I had online. So I looked for the language that was most like our pseudocode, and found that Python was the best match. Then I had to teach myself enough Python to implement the examples from the textbook. I found that Python was very nice for certain types of small problems, and had the libraries I needed to integrate with lots of other stuff, at Google and elsewhere on the net.

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.

<comment><USER4> _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._

Thank you, Peter. This is how I have felt for years, but could never find words that describe it as well as you just did.

Someone should write a program that automatically posts this paragraph at the top of every language war thread. I think they should write that program in php :-)

<comment><USER5> OTOH, it's not completely irrelevant. If you can launch 10% faster, that's a big advantage.

<comment><USER6> What makes it possible to launch 10% faster? Is it familiarity with the language, tools, libraries, and frameworks? Is it that the language is more dynamic and requires less to accomplish task X? I would say yes to both questions.

Now with the first question, familiarity with the language, lets discuss Python. Python is my language of choice. I know it, I use it, I pay attention to what is happening with the language, the community, etc. I organize a Python User Group. If I were to work on a new project, I would choose Python. I believe I could launch 10% if not 50% faster with Python than with Ruby. Does that make Python a better language? No. Just that I don't know Ruby, Rails, Sinatra, etc.

I think the second question about how dynamic the language is plays into this as well. Java is not very dynamic. Some tasks in Java are downright ugly to work with. If you want to prototype fast and spit out a product fast, you might not want to use Java. At that point, there are several great languages to choose from like Python, Ruby, Groovy, Scala, Lisp, Smalltalk, Javascript, Closure, etc. The list just goes on. You could also argue that .net is more dynamic. But Java has some good points to it as well. You have less risk of bugs due to it being statically and strictly typed. You can build off some great libraries. You get the benefit of the JVM and JIT, which are amazing. Maybe you can't launch faster with Java, but maybe you can launch with a more robust stable product. First doesn't mean best; remember the article about Wasabi and Mint?

The way I read Peter's comment was you don't want to spend you time finding the _best_ language. Instead you want to just grab the most convenient language and spend your time creating the best product. Think through your architecture, work on your design, test the hell product, study the market, your competitors, work on your marketing, and on and on. The list of things to do never end, and if you were still debating about which language to choose, you won't launch.

<comment><USER5> I agree. Language choice is definitely not the most important factor in success, but it's not as unimportant as some think it is.

Some languages make it easier to become familiar with the libraries. Compare the standard libraries of Ruby and Python with PHP. Even though I programmed in PHP for several years I always had to look up argument order, or whether the names of functions contained underscores between words or not.

</comment></comment></comment></comment></comment><comment><USER7> I'm a Clojure guy that just wrote my first Pylons app. Here's my impression:

1\. Python doesn't suck. I was able to mix FP & OOP approaches to get to my goal fairly quickly.

2\. iPython was fun to use, helped out a lot, but it's not SLIME.

3\. Guido has an excellent goal with making code readable, and significant white space is not a bad choice. However, I find being able to analyze active data structures in a Clojure namespace to be a superior way to learn about a system.

4\. Python's libraries are pretty good, and it's already been written. As a first impression, Python libs are much better to use than Clojure wrapped java libs. I'm going to look into porting SQLAlachemy to Clojure, it rocks.

5\. Paster has a ton of functionality. I'd like to see a similar Clojure tool, maybe Lien can evolve into that.

6\. I would like to see more FP constructs natively available in Python.

7\. __method__ is an interesting convention. You can have an object implement the right method, and your object works with Python syntax. However, I find it to be a poor man's version of Clojure's protocols (Full Disclojure, I have a conflict of interests here).

8\. Decorators are an interesting way to do functional composition, but I prefer comp and monads. Way more versatile.

9\. INSERT MACRO RANT HERE

That's all I've got for now. I'm sure I forgot something.

SFD

edit: grammar & spelling

<comment><USER8> It's funny, but the thing I miss most from Common Lisp when I write in other languages is the LOOP macro. It's ugly, and non-lispy, but most loops I have to write can be expressed clearly and concisely using LOOP, and writing the equivalent code in another language is annoying.

I'm tempted to create a LOOP clone for Clojure, then laugh villainously as I unleash it upon the world.

<comment><USER9> Loop, like structured editing (Paredit), is one of those Interlisp things that's very controversial and divisive.

There's tons of really wild ideas in Interlisp that seemed to be the half- baked acid trip ideas of West Coast hippies at the time, that are just starting to become rediscovered in the past couple of years (pervasive undo -> reversible debugging, DWIM-like autosuggestions in more places), and even the implementation techniques used are still innovative (for example the error- trapping implementation of Conversational Lisp ([http://docs.google.com/viewer?a=v&q=cache:4GnEnGS2XXkJ:c...](http://docs.google.com/viewer?a=v&q=cache:4GnEnGS2XXkJ:citeseerx.ist.psu.edu/viewdoc/download%3Fdoi%3D10.1.1.99.5401%26rep%3Drep1%26type%3Dpdf+%22conversational+lisp%22&hl=en&gl=ca&pid=bl&srcid=ADGEEShXWxn- mRgD0X-rMQN8IFezuWx7CRduPKQjuZWX2Qo1-BneEpeKTwpl5mMBxygVHRFiPkx37Sq3sY-hZN- GusSJAlZAXqxpSwjgF4uK0sXwFAb_zoygkiNO9MinjQxudj8C0nF5&sig=AHIEtbQiXOK77aVM2PKV9gYI- ek1oG1q1A)) is quite similar to how Geoff Wozniak approached auto-defining functions ([http://exploring-lisp.blogspot.com/2008/01/auto-defining- fun...](http://exploring-lisp.blogspot.com/2008/01/auto-defining- functions.html\)))

<comment><USER10> LOOP is not from Interlisp. It comes straight from Maclisp.

'LOOPS' from Interlisp is something entirely different: an object-oriented extension to Interlisp.

<comment><USER9> I'm going by the Hyperspec and what I remember from reading Kaisler's Interlisp. From the former:

"One of the Interlisp ideas that influenced Common Lisp was an iteration construct implemented by Warren Teitelman that inspired the loop macro used both on the Lisp Machines and in MacLisp, and now in Common Lisp."

[http://www.lispworks.com/documentation/HyperSpec/Body/01_ab....](http://www.lispworks.com/documentation/HyperSpec/Body/01_ab.htm)

<comment><USER10> It influenced it the Maclisp LOOP. The idea. That's all. The CL LOOP macro OTOH is a straight version of the Maclisp version. The MIT version of LOOP came from the same sources, even.

The Interlisp iteration facility looks slightly different. There are Interlisp manuals as PDF at bitsavers...

</comment></comment></comment></comment></comment></comment><comment><USER11> This question sounds like it's from 2005 rather than 2010. Lisp seems to have become fashionable again now, thanks to Clojure.

I'm sure Python has very good libraries, but I would find it constraining to program in a language without proper macros.

<comment><USER12> The problem with the Blub paradox is that there's no total ordering.

I do Common Lisp and C++ at my day job (ITA), and I do much of my personal hacking in Python. In Python and C++ I miss macros; in Lisp and Python I miss RAII and strong typing; in Lisp and C++ I miss dictionary literals.

And, in all of them, I miss algebraic datatypes.

<comment><USER11> I did mention in the original essay that it was only a partial order, in footnote [4].

<comment><USER13> Ah, but metageek's point is that it's not an order at all. It contains cycles.

</comment></comment></comment></comment><comment><USER14> An approximation of some of Norvig's recent thoughts (Feb 2010):

"(1) It just turned out that when Google was started, the core programmers were C++ programmers and they were very effective. Part of it is a little bit of culture. (2) Early Lisp programmers (Erann Gat) at Google actually noticed that other programmers were equally or more productive. It has more to do with the programmer; we're getting to the point where language choice is less important (as opposed to 20 years ago). (3) Lisp is optimized for a single programmer or a small group of programmers doing exploratory work... If I want to make a change in a weekend I'd rather do it in Lisp than anything else, but by the time you get up to hundreds of programers making changes are not a language problem but a social one. (4) Libraries."

Paraphrased from: <http://www.youtube.com/watch?v=hE7k0_9k0VA#t=03m20s>.

<comment><USER15> That reminds me of a cool story, in Norvig's talk about Python...

 _When he finished Peter [Norvig] took questions and to my surprise called first on the rumpled old guy who had wandered in just before the talk began and eased himself into a chair just across the aisle from me and a few rows up.

This guy had wild white hair and a scraggly white beard and looked hopelessly lost as if he had gotten separated from the tour group and wandered in mostly to rest his feet and just a little to see what we were all up to. My first thought was that he would be terribly disappointed by our bizarre topic and my second thought was that he would be about the right age, Stanford is just down the road, I think he is still at Stanford -- could it be?

"Yes, John?" Peter said.

I won't pretend to remember Lisp inventor John McCarthy's exact words which is odd because there were only about ten but he simply asked if Python could gracefully manipulate Python code as data.

"No, John, it can't," said Peter and nothing more, graciously assenting to the professor's critique, and McCarthy said no more though Peter waited a moment to see if he would and in the silence a thousand words were said._

[http://smuglispweeny.blogspot.com/2008/02/ooh-ooh-my-turn- wh...](http://smuglispweeny.blogspot.com/2008/02/ooh-ooh-my-turn-why- lisp.html)

<comment><USER16> _"... My first thought was that he would be terribly disappointed by our bizarre topic and my second thought was that he would be about the right age, Stanford is just down the road, I think he is still at Stanford -- could it be? ..."_

I've often wondered why McCarthy has never been asked to Startup school to talk about developing and using Lisp and the advantages?

<comment><USER17> He is probably not interested in talking about stuff when he could be doing stuff.

</comment></comment></comment></comment><comment><USER18> The Lisp vs. Python story really hasn't changed terribly much in the past five years or so. Both are still great languages once you learn to speak the idioms of the language. Both languages have persistent problems with people refusing to do so and then bitching that it's not $SOME_OTHER_LANGUAGE. Both languages have places where I'd suggest one of them over the other. Neither language is even close to a replacement for the other, and programming Lisp in Python is as big a mistake as programming Python in Lisp.

(Of the two though, Python seems to have more problems with people refusing to speak the native idioms and insisting on writing $LANGUAGE in Python instead. Python Is Not A Functional Language. It is a multiparadigm language where the functional is definitely the foreign and borrowed paradigm on top of an imperative/OO core. Ignoring that will bring you grief, but it won't be Python's fault.)

Later edit: In fact, refusing to speak Python's native idioms has been getting noticeably worse in the last six months. If you want a solid OO language with some decent functional borrowing, learn Python. If you want a pure functional language for whatever reason, do us all a favor and don't learn Python. Or at least don't add to the chorus of people complaining Python isn't Haskell, just _go learn Haskell_. Or Clojure, or whatever.

<comment><USER19> > The Lisp vs. Python story really hasn't changed terribly much in the past > five years or so.

Actually there have been three significant developments in the last five years that IMO tilt the scales back over to the Lisp side:

1\. Clojure

2\. Clozure Common Lisp a.k.a. CCL (a very unfortunate confluence of names -- the fact that Clojure and Clozure differ by only one letter but otherwise bear almost no resemblance to each other causes no end of confusion).

3\. The state of Common Lisp libraries has gotten a LOT better in the last five years.

<comment><USER18> Fair about Clojure, I was assuming Common Lisp. Point 3 I consider not much net change, though, as the same is true of Python, and pretty much every other competitive language.

<comment><USER19> Before, Lisp had the edge in native code compilation and functional programming, Python had the edge in libraries. In the modern landscape, that made Python win IMO. Now CL has caught up to Python (mostly -- it's 90% of the way there) in libraries and retains its edge in the other two areas, so in my book CL has pulled back into the lead. YMMV.

</comment></comment></comment></comment><comment><USER20> I tried writing an extensive Common Lisp vs. Python paper (yes, I have seen all of the existing ones), but it got too big and out of hand. One of interesting developments in Python recently are decorators, which allow some interesting metaprogramming. This can do some things that Lisp macros are used for. It's still not Lisp macros, but it;s picking off the low-hanging fruit, which helps Python coders a lot.

<comment><USER21> Any chance we might see the draft? :-)

<comment><USER20> Oh, it's so ugly, and it hasn't been checked for mistakes, etc. I'd be embarrassed to have my name associated with it.

<comment><USER22> I read you comment quickly and only now realized it's from you (Dan Weinreb, über lisp guru of ITA fame). I understand your felling (to put an early draft out). But, there is any chance you could send a copy to interested people who know the quality of your work (the man worked on the Common Lisp specification for god's sake!) and will read it as an early draft (no citations allowed ;-) and will promise not to send the draft to anyone? ;-)

<comment><USER23> You would probably entangle him in a two-hundred thousand dollar bet with Scott Aaronson.

</comment></comment></comment></comment></comment><comment><USER24> I think most people switching from Lisp to Python do so for practical reasons. I suspect Peter Norvig probably wouldn't use as much Python if he didn't have to adapt to the Google culture.

I think Python is a surprisingly nice language in many ways. It falls into the category of being an "acceptable Lisp". But I think most Lispers still prefer the real thing and only use Python when they need to be pragmatic.

<comment><USER14> I don't know of any Lisp programmer who thinks Python in an acceptable Lisp. In fact, there are some things about Python that are completely unacceptable as far as a Lisp goes: (1) crippled lambda, (2) no easy way to pass chunks of code around, etc.... Obviously not having macros is a given in anything but Lisp. Ruby (because of blocks) is far more of an acceptable Lisp.

<comment><USER25> > _Obviously not having macros is a given in anything but Lisp_

At least these languages (that I know of) have macros:

        http://boo.codehaus.org
        http://nemerle.org
        http://www.perl6.org

<comment><USER24> True, but the syntax for all three of these is pretty hairy.

Lisps might not be the only languages with macros, but they're the only ones with elegant and easy to use macro systems.

You could argue of course this is a moot point, since even Lispers only write macros infrequently. So who cares if it's hard to write one on the rare occasion you need to?

<comment><USER26> I am amazed that people say Lisp is about macros. I think it's about being homoiconic. You can make some ugly form of macros in ANY language. _Homoiconic_ -ness is what makes you want to make macros with Lisp. But it is much more than just about macros. Language REBOL is for example fully homoiconic.

      >> a: [ 300 3 ]
      >> insert a 'add
      >> probe a
      [ add 1 2 ]
      >> print first a
      add
      >> do first a 100 1
      == 101
      >> do a
      == 303
      >> f: func [] a
      >> f
      == 3
      >> change second :f 'subtract
      >> f
      == 297

all code is data (blocks of words and values).

From * Io * example below I would say it's a little different. It's more like it has a runtime api to change/generate it's runtime. I think SmallTalk has something similar to this.

* Factor * has compile time macros. At runtime it has quotations, which are blocks of code (separate from it's other data strucures I think, but don't shoot me if I'm wrong) that can be modified and executed by your code with few specific words like _curry_ and _compose_. This means you have a little less freedom than in rebol where block of code is in no way different than a block of data. What is awesome about factor is that it also compiles quotations at runtime.

Otherwise Factor is very very cool, and I envy some runtime features of Io a lot.

And Python has as little to do with lisp as Visual Basic. Python is the world's best dynamic _Imperative_ lang IMHO :)

<comment><USER27> _From Io example below I would say it's a little different. It's more like it has a runtime api to change/generate it's runtime. I think SmallTalk has something similar to this._

In Io, _all code is data_. Below is an example of changing a _functions_ behaviour (from addition to subtraction):

        Io> plus := block (a, b, a + b)
        ==> method(a, b,
            a + b
        )
        Io> plus call (1, 2)
        ==> 3
        Io> plus message next setName ("-")
        ==> -(b)
        Io> plus
        ==> method(a, b,
            a - <AUTHOR>
        )
        Io> plus call (1, 2)
        ==> -1

ref: _Io Has A Very Clean Mirror_ (WayBackMachine copy) - [http://web.archive.org/web/20080212010904/http://hackety.org...](http://web.archive.org/web/20080212010904/http://hackety.org/2008/01/05/ioHasAVeryCleanMirror.html)

<comment><USER26> Very cool!

There are few properties about concurrency, coroutines, embed-ability, and I suppose nice process of making bindings that I value really a lot and Io HAS. Looking at your example, I will definitely look again at Io. Thanks!

</comment></comment></comment></comment></comment></comment></comment><comment><USER28> I've used Python for about 4 years and am just starting to use Clojure, so I'll just add a few comments that others haven't mentioned. I'm not trying to offer a definitive comparison.

Clojure's data structures seem a lot like Python's but are a bit more elegant and avoid many of the little python headaches that come up often like d['k'] vs d.k vs d('k'). In clojure it would be (d :k) or (:k d) and both work. If you need memoization there are functions to help you. In clojure there definitely seems to be an attempt to make all the core data structures as compatible as possible (even having a formal abstraction (iSeq) for all of them)

Culturally, Python seems to care more about a minimal core language. Clojure.core has probably 3-4 times as many built-ins as Python. Many of the clojure functions are supporting features Python doesn't have or handles with syntax, like macros and conditional expressions, but there are also clojure functions like even?, that probably won't ever be a Python built-in.

Especially for predicates, functions like even?, every?, ffirst,

<comment><USER29> > and avoid many of the little python headaches that come up often like d['k'] > vs d.k vs d('k').

When does that come up? d['k'] is a key access (to a collection), d.k is an attribute access (to an object) and d('k') is a method call. I'm not sure where the headache/confusion would be here, unless you're trying to do very weird things with Python (which you should not)

<comment><USER28> They are all mapping functions, though. You have a key 'k', which is accepted by d and will return a unique result. Why should I have to care whether d is a collection, object, or method? In fact in many cases it's pretty easy to implement all three.

        class months(object):
            def __init__(self):
                m='jan feb mar apr may jun jul aug sep oct nov dec'.split(' ')
                n=range(1,13)
                self.__dict__.update(dict(zip(m,n)))
            def __getitem__(self, key):
                return self.__dict__[key]
            def __call__(self, key):
                return self.__dict__[key]

        d=months()

        print d['jan']  # 1
        print d('jan')  # 1
        print d.jan     # 1

<comment><USER29> > I'm not sure where the headache/confusion would be here, unless you're > trying to do very weird things with Python (which you should not)

<comment><USER28> I never said there was confusion. The headache comes when you're trying decide whether to present an interface to a mapping function as a collection, an object, or a function.

</comment></comment></comment></comment></comment><comment><USER30> Quotes from PG's Essays: _If you look at these languages in order, Java, Perl, Python, you notice an interesting pattern. At least, you notice this pattern if you are a Lisp hacker. Each one is progressively more like Lisp. Python copies even features that many Lisp hackers consider to be mistakes. You could translate simple Lisp programs into Python line for line. It's 2002, and programming languages have almost caught up with 1958._ _Macros (in the Lisp sense) are still, as far as I know, unique to Lisp. This is partly because in order to have macros you probably have to make your language look as strange as Lisp. It may also be because if you do add that final increment of power, you can no longer claim to have invented a new language, but only a new dialect of Lisp._ I think it is true even today

</comment><comment><USER31> When I last tried Lisp (SBCL) i was surprised how hard it is to find standard, common sense 'batteries' as you would in python, and how hard it is to get things going if you're not experienced. I think the point where I jumped out of the boat was trying out 'Hunchentoot' or something like that (webserver).

I haven't seen that with Python, Ruby, C++, Java, even Haskell feels 'modern' in that way. Why must it be so hard to get simple stuff going ?

(Note: I like function programming concepts, but I would expect a programming language to be easier to bind into a context of reality.)

<comment><USER32> > standard, common sense 'batteries' ... even Haskell feels 'modern' in that > way

Glad you noticed! We've been working hard on this: <http://haskell.org/platform>

</comment></comment><comment><USER27> For the macro side of things you may find these two old HN posts of interest:

* _Why Lisp macros are cool, a Perl perspective (2005)_ <http://news.ycombinator.com/item?id=795344>

* _Can a language have Lisp's powerful macros without the parentheses?_ <http://news.ycombinator.com/item?id=9172>

</comment><comment><USER33> Python versus Lisp is not so much a dichotomy. Some bridges:

1.- Mathematica: you can use both infix and prefix form, Fullform[a+b] = [Plus,a,b]. Mathematica internally use prefix notation. Evaluation is more flexible than Lisp, you can define a function and decide whether it evaluates some, all or none of its arguments. 2.- Maxima: A layer over Lisp to define a infix language,in which you can define operators to resemble math notation, for example f(x):= x^2 similar to (defun f(x)(* x x)) 3.- Dylan. A lisp with infix notation. 4.- Willem Broekema cl-python, python in Lisp. 5.- Clojure. Clojure brings some nice syntax for getters and setters, function arguments and much more. 6.- comp.lang.lisp versus clojure. Clojure has a great community, lisp has some problems with lords. 7.- abcl is here, that is Lisp in java. abcl can run maxima without errors and that is great. 7.- Ruby, jruby, ioke, duby, those are efforts to achieve a very expressible language. 8.- javascript, the good parts. javascript with some anotations can be the next lisp. 9.- quick-lisp for a better installer than asdf.

</comment><comment><USER34> There is a language and there is an ecosystem surrounding it (libraries, community, etc). Ignoring the ecosystem, the question "to lisp or not to lisp" pretty much boils down to "syntax or macros" - if you want macros, you go with a lisp, if you want syntax, you go with Python or another modern language.

I used to think macros matter more than syntax, because you can freely define your own micro-languages. I didn't really practice it, because of the practical limitations of the available lisps [1]. Now I think the opposite, that syntax matters more. Syntax helps you parse the code visually and you use lower level parts of your cortex to understand the code [2]. You can build arbitrary DSLs in lisps, but they all have no syntax, so they are of limited cognitive help. I think the real win are modern languages with syntax, that is malleable enough to facilitate the cognitive apparatus of the programmer in most cases, or at least most cases that matter. For example, an obvious DSL is the mathematical notation - Python / Ruby handle it well enough with operator overloading, Lisp actually does worse because of the prefix notation.

It is important to understand that you can approximate the bottom-up style of building abstractions with libraries (instead of DSLs), parameterizing the proper things, with minimal syntax noise. The remaining difference between macros and using higher level functions is mostly in run time optimization.

I guess seasoned lispers learn to "see through" all the brackets and engage the lower-level part of the brain in parsing lisp code. Ironically, something similar happens to Java developers - after enough hours looking at the code they start to ignore the ugly try/catch clauses that can't be properly abstracted away because of language limitatons.

[1] with the exception of one big project in Common Lisp, but I did only a little programming in it, and this was before I fully appreciated macros - <USER2> the guy before me used them extensively to build two layers of domain specific languages

[2] L Peter Deutsch talks about this in Coders at Work and this is probably more valuable than what I have to say:

Deutsch: I can tell you why I don't want to work with Lisp syntax anymore. There are two reasons. Number one, and I alluded to this earlier, is that the older I've gotten, the more important it is to me that the density of information per square inch in front of my face is high. The density of information per square inch in infix languages is higher than in Lisp.

Seibel: But almost all languages are, in fact, prefix, except for a small handful of arithmetic operators.

Deutsch: That's not actually true. In Python, for example, it's not true for list, tuple, and dictionary construction. That's done with bracketing. String formatting is done infix.

Seibel: As it is in Common Lisp with FORMAT.

Deutsch: OK, right. But the things that aren't done infix; the common ones, being loops and conditionals, are not prefix. They're done by alternating keywords and what it is they apply to. In that respect they are actually more verbose than Lisp. But that brings me to the other half, the other reason why I like Python syntax better, which is that Lisp is lexically pretty monotonous.

Seibel: I think Larry Wall described it as a bowl of oatmeal with fingernail clippings in it.

Deutsch: Well, my description of Perl is something that looks like it came out of the wrong end of a dog. I think Larry Wall has a lot of nerve talking about language design—Perl is an abomination as a language. But let's not go there. If you look at a piece of Lisp code, in order to extract its meaning there are two things that you have to do that you don't have to do in a language like Python.

First you have to filter out all those damn parentheses. It's not intellectual work but your brain does understanding at multiple levels and I think the first thing it does is symbol recognition. So it's going to recognize all those parenthesis symbols and then you have to filter them out at a higher level.

So you're making the brain symbol-recognition mechanism do extra work. These days it may be that the arithmetic functions in Lisp are actually spelled with their common names, I mean, you write plus sign and multiply sign and so forth.

Seibel: Yes.

Deutsch: Alright, so the second thing I was going to say you have to do, you don't actually have to do anymore, which is understanding those things using token recognition rather than symbol recognition, which also happens at a higher level in your brain. Then there's a third thing, which may seem like a small thing but I don't think it is. Which is that in an infix world, every operator is next to both of its operands. In a prefix world it isn't. You have to do more work to see the other operand. You know, these all sound like small things. But to me the biggest one is the density of information per square inch.

Seibel: But the fact that Lisp's basic syntax, the lexical syntax, is pretty close to the abstract syntax tree of the program does permit the language to support macros. And macros allow you to create syntactic abstraction, which is the best way to compress what you're looking at.

Deutsch: Yes, it is.

Seibel: In my Lisp book I wrote a chapter about parsing binary files, using ID3 tags in MP3 files as an example. And the nice thing about that is you can use this style of programming where you take the specification—in this case the ID3 spec—put parentheses around it, and then make that be the code you want.

Deutsch: Right.

Seibel: So my description of how to parse an ID3 header is essentially exactly as many tokens as the specification for an ID3 header.

Deutsch: Well, the interesting thing is I did almost exactly the same thing in Python. I had a situation where I had to parse really quite a complex file format. It was one of the more complex music file formats. So in Python I wrote a set of classes that provided both parsing and pretty printing. The correspondence between the class construction and the method name is all done in a common superclass. So this is all done object-oriented; you don't need a macro facility. It doesn't look quite as nice as some other way you might do it, but what you get is something that is approximately as readable as the corresponding Lisp macros. There are some things that you can do in a cleaner and more general way in Lisp. I don't disagree with that. If you look at the code for Ghostscript, Ghostscript is all written in C. But it's C augmented with hundreds of preprocessor macros. So in effect, in order to write code that's going to become part of Ghostscript, you have to learn not only C, but you have to learn what amounts to an extended language. So you can do things like that in C; you do them when you have to. It happens in every language. In Python I have my own what amount to little extensions to Python. They're not syntactic extensions; they're classes, they're mixins—many of them are mixins that augment what most people think of as the semantics of the language. You get one set of facilities for doing that in Python, you get a different set in Lisp. Some people like one better, some people like the other better.

<comment><USER10> Lisp has a lot syntax. It is just a bit different and it looks different externally.

 _Lisp has a 2-stage syntax._

 _The first stage is the syntax of s-expressions_ , which is surprisingly complex. S-Expressions provide a textual syntax for data: symbols, lists, pairs, strings, various number formats, arrays, characters, pathnames, ...

The first stage is implemented by the 'reader' and can be reprogrammed by an ancient API to the reader via read tables.

 _The second stage is the syntax of the Lisp programming language._ This is defined on top of s-expressions and is really a syntax over data structures (not text). This Lisp syntax deals with: data items, function calls, special forms (thirty something) and macro forms.

This syntax stage is implemented as part of the interpreter/compiler (EVAL, COMPILE, COMPILE-FILE) and can be extended by writing macros, symbol macros and compiler macros. In earlier dialects it could also be extended by writing so-called FEXPRs, functions which get called with unevaluated source code (-> data in Lisp).

So, we get a lot of complex syntax due to special forms and macros. It just looks a bit different, since the data syntax is always underneath it (unless one uses a different reader).

For example a function definition would be:

       (defun foo (a b) (+ (sin a) (sin b)))

The syntax for that is:

        defun function-name lambda-list [[declaration* | documentation]] form*

With more complex syntax for 'function-name', 'lambda-list' and 'declaration'.

Lambda-list has this syntax:

        lambda-list::= (var*
                        [&optional {var | (var [init-form [supplied-p-parameter]])}*]
                        [&rest var]
                        [&key {var | ({var | (keyword-name var)}
                          [init-form [supplied-p-parameter]])}*
                          [&allow-other-keys]]
                        [&aux {var | (var [init-form])}*])

Not every valid Lisp program has an external representation as an s-expression - because it can be constructed internally and can contain objects which can't be read back.

Not every s-expression is a valid Lisp program. Actually most s-expressions are not valid Lisp programs.

For example

       (defun foo bar)

is not a valid Lisp program. It violates the syntax above.

<comment><USER9> "The first stage is implemented by the 'reader' and can be reprogrammed by an ancient API to the reader via read tables."

Readtables aren't any more ancient than the rest of ANSI INCITS 226-1994 (R2004) (the language standard formerly known as X3.226-1994 (R1999)), but the interface to them is very low-level and non-modular.

The current readtable is specified by a dynamic variable, so the readtable facility can be made modular with a nicer interface, in a portable manner. This is exactly what the library Named-Readtables does: <http://common- lisp.net/project/named-readtables/>

Now realize the significance of this: Common Lisp is the only language allowing total unrestricted syntactic extension and <i>modification</i> in a modular and (somewhat) composable way.

I've been using named-readtables for the past month, and between it and Quicklisp, I haven't been this excited about programming in CL since I started (which is 8 years ago, not that long, but I'm not a total noob either).

<comment><USER10> Read tables existed before CL. CLOS for example not, it was developed for ANSI CL (based on experience with LOOPS and Flavors). See for example READTABLE in Maclisp:

<http://maclisp.info/pitmanual/io.html#16.2.7>

Also note that I wrote that the API is ancient. It is. It is old and could be easier to use.

'Named readtables' are related to 'syntaxes' on the Lisp Machine. For example source files have a syntax attribute in the header, which switches between the various Lisp dialects (or other languages), including using different readers. This is for example used by the file compiler and Zmacs.

<comment><USER9> Cool, I didn't know readtables were in Maclisp, or about LM syntaxes.

"It is old and could be easier to use."

Aside from something like named-readtables, how would you design the lowest- level interface to readtables? Or you wouldn't do that, and just specify something like named-readtables to be the interface? I'm curious because this could be something for <http://www.cliki.net/Proposed%20Extensions%20To%20ANSI>

<comment><USER10> I haven't thought about it much, but the character level interface is very primitive. Second, what about things like symbols, numbers, etc.? There is no sane way to specify number syntax or symbol syntax. That might be useful. Currently the reader provides an interface on a character level, but not on the level of s-expressions components.

<comment><USER9> What I think you're saying is that the reader should be customizable in terms of some DSL for a grammar. It would be nice, but I'm not sure how composable it would be (in the general case, I think it would come down to having the behavior of READ dependent upon a black-box _current-parser_ procedure).

The nice thing about readtables is that it exposes what in essence are transition hooks for each character, so you really don't need to care about the grammar of stuff you're not interested in parsing.

OTOH like you said, extending the syntax for numbers or symbols becomes quite hairy. But even with a DSL grammar approach, you'd need to change major parts of the grammar (which means copying and modifying the normative grammar of CL syntax - not that different from grabbing a portable CL reader implementation today (<http://twitter.com/vsedach/status/26484049015)>).

The big downside is deciding on which class of grammars that will support, and how they will be represented.

</comment></comment></comment></comment></comment></comment></comment><comment><USER35> I find it hard to maintain large-ish python codebase - it tends to wire up itself into a mess (in my case). It's probably due to my inability to do so, but I don't have same problems with C code.

<comment><USER36> Is it possible you're comparing lines of code directly? The "size" of a code base is tricky to define, but many people accept a rough rule of thumb that a project of complexity X that might require, say, 10K LOC in competent/straightforward C would require say 2K LOC in competent/straightforward Python/Ruby/etc. The implication is that an average 10K LOC Python program _would in fact be a more complicated program_ than an average 10K LOC C program, and therefore "messier", all things being equal.

<comment><USER35> I can't really describe it. It's as if literal size grows, it's harder for me to wrap my head around what is where and why - I suspect it is due to the fact I don't write very pythonic code... more like I'm writing C code with Python syntax, if you know what I mean.

I am not particularly familiar with python too, I should educate myself properly, dwell more into it though. I only get by for what I need to do in Maya with it.

<comment><USER36> Ah, right, different problem. There's much to be said and disputed about what makes a 10K program Pythonic; my oversimplification would be something like: \- between half a dozen and two dozen files in 2-3 directory levels \- lots of small classes with short methods \- some short functions \- lots of dictionaries \- no God objects \- some comprehensions, generators, and decorators \- about 2-4 levels of abstraction between the problem statement and the core routines in inner loops \- pivot away from any of the above if the problem calls for it, but many problems don't

Even simpler: if you're writing short callables (functions/methods, mostly) and using them as the values in dictionaries, you're most of the way to writing intermediate Python.

</comment></comment></comment></comment><comment><USER37> Am I missing something, why does it have to be either Python or Lisp? After all I know, Peter Norvig has embraced Python in addition to Lisp, rather than switched completely as in "no more Lisp". Same goes for everyone else -- some tools are more fit for some tasks than others, especially with corprorate restrictions being a constraint.

</comment><comment><USER38> Paul, this would be a great opportunity for you to plug Arc, an increasingly active Anarki (<http://github.com/nex3/arc>), and the growing Arc community (<http://arclanguage.org/forum>).

<comment><USER39> I feel like the Arc project pivoted until it became YC.

</comment></comment><comment><USER40> I used to write a reasonable amount of Lisp at my first job, in an industrial research lab, in addition to a fond exposure to it at my institution of higher learning.

I really, really like Lisp. The syntax, as a result of it having been introduced to me fairly early, never was a hangup of any kind. SLIME is quite wonderful. I always yearn for quasiquotation.

However, I cannot justify using it for a small-scale project that has to ship relatively soon with limited resources. The reason: Python has useful projects with good release culture and documentation that are not seen in the Lisp world, if only for the lack of contributors. (Considering the number of authors, I found common lisp documentation to be quite good, in fact, but I still find them pretty hard pressed to compete with, say, the Django manual, or most of the Python standard library itself)

Software — especially at the small, early stage scale — is still loaded with problems that are not matters of extensive, inspired, and unique programming. Or, they could be, but did you really want to write your own whiz-bang form validation instead of building all the other features of your product?

Clojure I think represents a very interesting escape from this trap, and if I had a lot of Java dependencies (whether bequeathed or because of unique library advantages Java may have. WEKA comes to mind for some things) I would most certainly want to use it. But in a project I control from the beginning, Python wins, hands down, in a number of domains.

I will also expose one heretical opinion of mine about Lisp Macros: they're great, but easy to overuse, and seldom So Necessary if one makes good use of higher order functions. Some code, admittedly, comes out nicer using macros, but I can almost always get the expressive power I need with little contortion using higher order functions.

If I had the time to follow my heart, I'd want to do something to continue to vitalize Lisp. But not while I need to ship.

To round out this post, here are some minor peeves on the Python side though:

* No symbol data type. I don't like using strings for these. I use SymbolType for this, but it's still comparatively clunky compared to CL.

* Hyphens are the best intra-token-delimiter (see what I mean?)

* No macros

* No quasiquotation

* Slow

* Have to avoid stepping on myself because of the mutable environment frames you see a bit more frequently as opposed to say, Scheme or Erlang where tail recursion is the name of the game. I also make use of "labels" in cl.

* Did I mention tail recursion elimination? No? Well...sometimes this would be nice.

</comment><comment><USER41> Banana vs Oranges?

<comment><USER28> Bananas have much more starch than oranges, but oranges are easier to juice.

<comment><USER42> @Goldus - you seem like a old timer here. why post comments like these? Are you adding any value to the main conversation - python/lisp.

<comment><USER28> The point of the comment was to demonstrate that sometimes, it's worthwhile or at least interesting to compare (or actually, contrast) bananas and oranges, like Python and Lisp.

(Also, I had already posted my small contribution to the original topic)</comment></comment></comment></comment>


Show HN: Gita – a CLI tool to manage multiple Git repos - <AUTHOR> https://github.com/nosarthur/gita <comment><USER2> One thing this project does really well is to start the readme with a screenshot. I open the link, scroll down to the readme, and I immediately see what sort of user interface/experience I will get. Some commenters have noted that Gita is similar to other multi-repo tools, but both Repo and wstool are more effort to evaluate, because their readmes don't have pictures.

</comment><comment><USER3> Nice, but is there a way to just run any command? I.e. just `gita <optional repo names/paths> <pass entire command line git -C repodir>`. This has advantages in that you don't have to go round via a command file, don't have to keep it synced across machines, don't have to remember what you put in the file etc, and can just use the git syntax which already took long enough to learn by heart :P

I've used multiple multiple repository tools and in the end all I happen to use is one (usually versioned) file to store a list of repositories and then a command which just loops over all repos and applies anything to it. If I need custom commands I use git aliases so that works both for normal git and whatever tool used.

<comment><USER4>
        → cat ~/bin/git-all
        #!/bin/bash

        # Exit on error. Append "|| true" if you expect an error.
        set -o errexit
        # Exit on error inside any functions or subshells.
        set -o errtrace
        # Do not allow use of undefined vars. Use ${VAR:-} to use an undefined VAR
        set -o nounset
        # Catch the error in case command1 fails (but command2 succeeds) in `command1 |command2`
        set -o pipefail
        # Turn on traces, useful while debugging but commented out by default
        # set -o xtrace

        help() {
          cat <<EOF

        usage: git all <any-git-command>

        Runs the git command for all repositories in the current directory.

        Examples:

          What just happened?
            git all log -1 --oneline

          What am I doing now?
            git all status --short --branch

          What is everything I'm working on?
            git all branch -vv
        EOF
        }

        banner() {
          echo -e "\\033[1m=== $1 ===\\033[0m"
        }

        main() {
          if (( $# < 1 )); then
            help
            exit 1
          fi

          folders=$(find . -maxdepth 2 -name .git -print0 | xargs -0 -n1 dirname)
          for folder in $folders;
          do
            banner "$folder"
            git -C "$folder" "$@" || true
          done
        }

        main "$@"

<comment><USER3> Missed this reply, but yes, that's what I'm talking about!

</comment></comment></comment><comment><USER5> Another similar tool is myrepos (it supports other VCSen too). There are several other similar tools, see the related software section of the myrepos website:

[https://myrepos.branchable.com/](https://myrepos.branchable.com/)

<comment><USER6> I use myrepos and I like it a great deal.

mr register in the root of a git dir.

then `mr status` from home will show the state of all repo's registered, it's handy at the eod to see what repos you've touched but not committed.

</comment></comment><comment><USER7> I wrote a similar tool (along with some other git helpers) a while ago: [https://github.com/tkrajina/git-plus](https://github.com/tkrajina/git-plus). Note that there is another (more popular) git-plus repository used in Atom. My own has nothing to do with it (but it's older).

</comment><comment><USER8> Isn't this what "repo" [1] does?

[1] [https://source.android.com/setup/develop/repo](https://source.android.com/setup/develop/repo)

<comment><AUTHOR> didn't know this tool before. I will give it a try. Thanks!

</comment></comment><comment><USER9> Cool, new tooling!

I currently use a mix of mu-repo [1] and uncommitted [2]

[1]: [http://fabioz.github.io/mu-repo/](http://fabioz.github.io/mu-repo/)

[2]: [https://github.com/brandon- rhodes/uncommitted](https://github.com/brandon-rhodes/uncommitted)

</comment><comment><USER10> The biggest problem with multiple repositories is to manage consistent versions (commits).

For example, let's say that I have a release 1.0, which consists of a bunch of commit IDs of various repositories. How do I go back to that release without manually checking out the specific commit ID in each repo?

<comment><USER3> We use tags for that. Upon each release all repos get the same tag. Alternatively with tools like mr [1] you can for each release keep a .mrconfig somewhere which keeps the commit SHA for each repo (not 100% sure if mr can create such file by itself, but it's not really hard) so that if you do a fresh clone it checks out each repo at the correct commit.

[1] [https://linux.die.net/man/1/mr](https://linux.die.net/man/1/mr)

<comment><USER5> There is a mr/myrepos plugin that adds some automation for remembering the currently checked out commit:

[https://bitbucket.org/mforbes/mmfhg#rst-header-mr-un- freeze](https://bitbucket.org/mforbes/mmfhg#rst-header-mr-un-freeze)

</comment></comment></comment><comment><USER11> Great tool! It's nice we have one more tool to choose from. Each program has their own UX so I don't see a new contender as a bad thing.

</comment><comment><USER12> wstool ([https://github.com/vcstools/wstool](https://github.com/vcstools/wstool)) is a tool for managing a workspace of multiple heterogenous SCM repositories.

Very convenient. I have used it for ROS projects with multiples SCM

</comment><comment><USER13> Can you put up an asciinema demo pls

</comment><comment><USER14> Isn't this what repo does ?

</comment><comment><USER15> Or just have a monorepo :)

<comment><USER16> Operations on monorepos can be so slow that having multiple copies checked out (e.g. different branches) is a thing (ideally using worktrees).

<comment><USER17> I hate to say it but because I don't feel comfortable with git enough whenever I am about to do anything outside of my comfort zone I make a hard copy of my whole directory just to be sure if I get myself into a FUBAR state I can delete the FUBAR'd directory and copy it again. This has saved me many a headache. Also gives me a fresh state from which to ask for help from. Anytime the word rebase is mentioned my coworkers shriek.

<comment><USER16> Have you ever had a look at the combination of 'git reflog' and 'git reset --hard <ident>'? You can find the point before you did the uncomfortable operation and restore your state to exactly then. Saves having to make that backup copy (which, again, can be slow for a big repo).

<comment><USER18> Neither of those saves the working directory, though. So uncommitted work "feels" at risk while typing unfamiliar git commands.

(I now consider myself pretty good with git as a result of being forced to learn gerrit, but I also still remember the early painful days)

<comment><USER16> True, that's a good point.</comment></comment></comment></comment></comment></comment>


The Fatal Pinch - <AUTHOR> http://paulgraham.com/pinch.html <comment><USER4> I agree with this article. Founders overspend once they get their first initial investment, and rely on the next investment too much. Founders should be paying more attention to burn and churn rates.

I once saw one of my best friends fail his first startup. They had a kickass programming team, received investment and did a bunch of things wrong.

1) Spent the whole investment on Founders salaries. They had 4 tech programmers (top notch guys), and used the money to pay for their time whilst they were building the platform.

2) They had the wrong product market fit. They expected to sell their services to Universities for 50K. In my opinion, they should of targeted college students, and add a tutoring service and take a small commission.

3) They built a fully finished product. Their was no room to scale it or grow.

4) They expected that the product would just sell itself. We all know, that's not how it works in the real world.

5) They didn't do any market testing and validation = wrong product market fit.

The end result, they got an investment and spent it quickly, they didn't try to pivot, tried to get another investment and failed. The team broke up pretty quick, or as you referred to in your article, they got an unwelcoming 'pinch' on the backside.

I learnt a lot from seeing my friends fail, and their failure has helped me out a lot with my startups. When startups first get their investment, they should have a 1-2 year plan for that money (burn rate). Divide the investment by a specific time period and that's how you spend it.

Realistically, after you get through the TechCrunch 'trough of sorrow' as Andrew Chen puts it, you have to stay motivated and plan for the future. The future looks dim if your startup is heavily reliant on receiving additional investments to keep you alive.

More on the pinch, startups shouldn't be getting an investment to keep them going. They should have this already sorted out. A very wise person once told me, you should seek investments when you don't need them, as this means you have done your homework and can also find the best deals.

Great article, and I appreciate the awesome content.

<comment><USER5> Selling to big colleges is not too different than selling to large enterprises and/or to Uncle Sam. Product quality and features are much lower on the list, than lobying, networking, marketing, developing contacts. Learn to play golf (or whatever the CEOs and administrators of big institutions or companies are doing today to socialize). Or instead of hiring another programmer hire someone who was in charge of making buying decisions for the industry you are trying to sell to.

That is also the reason why many colleges, or governments, end up with crapy overpriced software. You look at it and say "I can do 10x better and sell for 10x cheaper". The problem is you are not aware of the size of the iceberg lying under the water.

<comment><USER4> I think they had the options to target Universities or college students. The product connects college students to other students to for help with problems. It's mostly suited for the mathematics, engineering and computing faculties.

The big issue is, they didn't have anyone to do marketing for it or test the market to see whether it wants their service or not. They should of done a pilot system. Focused on one university in Beta mode, and then expanded. They were too fixed on selling it for 50K a piece.

</comment></comment></comment><comment><USER6> That is so spot on. Put another way, the seed round is a peek to see if you can do what you say you can do, series A is a bet you can make it profitably, and series B is the gas to grow the market. As soon as you know your cash and your profitability cross below the 'zero' line you calk your investors that week and you ask them, call it or push forward. They say no, then you just roll it up. And I know, that is much much easier to say than to do.

<comment><USER7> Love this description!

</comment></comment><comment><USER8> This is why I hate investing in startups raising $500k or less. You won't be able to raise again unless you have significant upwards progress.

<comment><USER9> Several of my best investments have been from startups raising less than $500k. Justin.tv/Twitch returned 97x my original investment, and Weebly will likely be even more.

<comment><USER10> Presumably those were a while back?

Do you think the climate has changed since then to make it much harder?

<comment><USER9> The climate has changed in that it's easier for startups to raise more, but even those that do not can still be very successful. Justin.tv or Weebly would not require any more money to start today than they did six years ago -- if anything it's gotten cheaper.

<comment><USER11> I remember David from Weebly noting that they narrowly avoided the pinch by becoming profitable (circa 2009?) Now AFAIK they are kicking ass.

<comment><USER9> Yes, the Weebly story is amazing. He covered part of it at Startup School a few years ago: [https://www.youtube.com/watch?v=l_b228qEVi8](https://www.youtube.com/watch?v=l_b228qEVi8)

<comment><USER12> Weebles wobble, but they don't fall down.

</comment></comment></comment></comment></comment></comment></comment><comment><USER13> These days, the stakes are higher for everyone. Investors expect faster growth and want a "meaningful stake" (15%+) early on.

Meanwhile, entrepreneurs generally try to raise more too. Who doesn't want more cash if they can get it?

This is dangerous for those who don't understand these dynamics. The growth trajectory needs to align with the incoming cash. The second you raise a $3M seed round, you're on the roller coaster. You will need to show "hockey stick" growth in 12 months, and raise your A in 18. If not, you're dead.

<comment><USER14> The problem of course is that only a minority of companies can ever really meet this. This requirement seems to have driven a lot of startups to do things in a way that does not maximise the benefit to the founders [0] - investors can spread the risks over multiple investments while the founder are stuck with all their eggs in one basket [1].

0\. I don't blame the VCs for doing this as they are doing what is best for them and their partners, but as a founder you should look very carefully at what is on offer and if what you are expected to do is viable.

1\. Paul's point about the fatal pinch is correct, it is just that it is occurring much earlier (at the seed round) not 6 months from the money running out.

</comment></comment><comment><USER15> One way to avoid the fatal pinch is the Dickens approach:

 _Annual income twenty pounds, annual expenditure nineteen nineteen six, result happiness. Annual income twenty pounds, annual expenditure twenty pounds nought and six, result misery._

In a world with AWS and pay-as-you go services, it's more and more possible.

<comment><USER16> (Zero sarcasm) can you possibly explain, in different words, what this means?

<comment><USER17> The numbers refer to pre-decimalization British currency. To convert to modern currency:

      £19 19s 6d = £19.975
      £20  0s 6d = £20.025

<comment><USER18> Wikipedia has a few pages about the various systems of this kind: [http://en.wikipedia.org/wiki/Pre- decimal_currency](http://en.wikipedia.org/wiki/Pre-decimal_currency).

Difficult to fathom why the fashion for these passed, because such systems provide so many advantages. A good example is the Spanish system of division into 34, which permits straightforward further division into not only 2 but also 17 pieces - a case very difficult to handle with the modern restrictive, awkward and inconvenient decimal systems.

<comment><USER19> It saddens me in some ways that the UK currency decimalized before mass computerization of record-keeping took off. I think I would have liked to have lived in a world where database currency columns needed to support pounds, shillings and pence (keeping in mind that pence could be divided into quarters, of course).

<comment><USER20> Dealing with Olde English currency units (and other non-decimal currency units) may have been "a fun challenge" for programmers... but it does NOT sadden me that programmers have seldom had to deal with them! It would have led to a whole world of hellish pain. Have we not suffered enough pain as it is, what with character encoding, timezone handling, y2k-incompatible dates, spatial coordinate / projection systems, etc?

<comment><USER18> I'm not even sure there'd be much to do: just store everything in sixteenths a of a farthing and format on output, much as people do with tenths of a penny today. If anything the numbers are actually slightly more convenient for machines with no divide instruction.

</comment></comment></comment></comment></comment></comment></comment><comment><USER21> First time founder. My company is in a "fatal pinch."

Similar to a previous comment by @LukeFitzpatrick, we built something for our alma mater that we thought we could sell to colleges for 50k/year. We got investment, we built it, we sold it to a few more schools but the software is not feature-packed and mature enough to attract sales fast enough. Higher ed also moves super slow even when you're doing well.

We're starting to see some traction with parties that want the software custom-tailored for their need (the consulting PG speaks of). But we're stuck in spot where we haven't gotten a check from any of these parties yet and are reluctant to pull the trigger and focus on only on the consultative sale.

The team, product roadmap, and marketing strategy is all geared towards higher ed. But it's clear now we can't become profitable in 6 months in that industry. How do we operationally perform the "pivot" into consulting? Do you agree it's time to do so?

<comment><USER22> Please make sure it's something your team can actually get behind, and be very careful about how you put it. Because for experienced developers, any sign of pivoting to consulting is a sign to run for the exit. That's explicitly not what they signed up for when they took a chance on a start-up. Many will rather help out by cleaning the toilets than to fundamentally change the nature of their work.

It's kinda shocking that PG omitted that part, because I've seen it happen several times.

(Read michealochurch's comment further down on this page, he pretty much nails it.)

<comment><USER21> I think you make a good point. We need to make sure the whole company is on board. PG's comment on using consulting to find the product you want to build long term feels applicable here. Of course, the slippery slope remains. But if we can make money while finding those "narrow openings that have wide vistas beyond"

</comment></comment></comment><comment><USER23> I'd argue that the 'consultingish' part is as hard as the startup's main business itself, if you add the human factor.

On one hand, you have your ideas, your product or whatever you're working on – which, by definition, isn't working all that great. On the other hand, you have a client (or more than one), who's willing to pay _right now_ (usually you can negotiate something upfront) or at least just one invoice away. Plus you are able to charge a nice amount, certainly better than you'd make as an employee and better than going broke.

Somewhere down the line, you'll get more work. Maybe from the same client, maybe it's a referral. Do you turn them down now, that you've achieved the required runway? It's hard if you are a sole founder, it is much harder if you have more than one. Harder still if they are married, or with children or, god forbid, have a mortgage.

The consulting (there's no ish unless it is a somewhat minor customisation of an existing product or parts of it) path is a very slippery slope. It should not be taken unless the other option is death. And only after all founders are on the same page.

It's easier to set a goal when everyone is going broke, than when the money has started rolling in. There's nothing in the world that's more blinding than a bank deposit.

<comment><USER24> Yes, that is what you do when you've cleared the runway: you start saying no to consulting clients. That is, for example, what 37signals did. I'm not sure I see the problem here.

<comment><USER14> But 37signals bootstrapped. The problem is once the founders take VC money they are taking on what the VC expect them to do which is play a very high risk, potentially high reward game with a very low chance of success. This strategy is almost certainly not optimal for the founders.

<comment><USER24> So what? At this point in the story we're talking about a company on life support. That's why they're consulting and not continuing to put all their time into product. There's not a whole lot VC can do about it at this point.

<comment><USER14> >There's not a whole lot VC can do about it at this point.

Except ask for their money back :)

If you think you can get away with running a sane growth company (100% Y/Y) and don't have to worry about the VCs asking for their money back, then the most rational thing to do is take the seed money and run the business as a "slow growth" business with an enormous runway. Unfortunately most VC's are aware of this and will not be too happy if you try :(

<comment><USER25> VCs can't ask for their money back. It belongs to the company and is in the company bank account. They can refuse to give you more, and if they control the board they can try to put in a new management team, but except for cases of fraud or other malfeasance, they cannot get their money back.

<comment><USER26> Most seed fund investment is in the form of a convertible note these days ... it's a loan with the option to convert to equity later. Consequently VCs _can_ ask for the debt to be repaid (within the terms of the note). Obviously they'll only get back what's left in the bank and assets but the idea that they can't ask for it back isn't really true.

<comment><USER27> Right, and that would kill the company, but a VC is probably more likely to kill a company that's slowly running out of its runway than a company that's doing something out of the ordinary to survive and get back on track.

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER28> _There are a handful of companies that can 't reasonably expect to make money for the first year or two, because what they're building takes so long._

So if someone starts a company that is in this category, is it just dead in the water if the founders aren't already rich/connected?

<comment><USER29> I know of a company that thought they would be in this category. They ended up raising a very large seed round (1MM+) from a VC and pre-negotiating a follow- on of equal size, should they need it. That way the expectation was set from the beginning that this company might take some time to build out their product and see traction.

It's smart, because the discount for the follow-on was pre-negotiated, so investors get perhaps a more favorable discount if the company is a run-away success, and the entrepreneurs were able to buy peace of mind, and could count on the money regardless of macro-economic forces.

<comment><USER28> _They ended up raising a very large seed round (1MM+) from a VC and pre- negotiating a follow-on of equal size, should they need it._

So my guess is that these founders were either already successful previously, were well connected or had already bootstrapped quite a bit of the technology that would underlie the product (ie patents, team, etc...). Any or all of that the case?

<comment><USER14> Yes it would be nice to know what the background of the founder were here. I have a feeling they were not three 22 year olds on their first startup.

<comment><USER30> I would argue that three 22 year olds on their first startup shouldn't be building a product that can't be validated by the market in one or two years.

<comment><USER28> Define validate. That is kind of the crux of my question. If it means "profitability" then that is a different threshold than "users." I am trying to figure out what PG is trying to describe.

<comment><USER31> It's pretty obvious when it happens but it's most definitely not profitability. Rapidly growing usage (ie, traction) with an envisionable business model is usually sufficient. While the revenues themselves are not strictly necessary, it does help to demonstrate the ability to collect them.

</comment></comment></comment></comment></comment></comment></comment><comment><USER10> "Although your product may not be very appealing yet, if you're a startup your programmers will often be way better than the ones your customers have or can hire."

Is this really true? I'm very sceptical.

Does anyone have any evidence to back this up?

<comment><USER32> Actually, it's more like this.

There are good programmers in the enterprise (meaning, say, investment banks or large corporations or governments) but they generally fall, ambition-wise, into one of three categories:

(1) those who want to become managers or software architects (or, in finance, quants and traders) and will define and oversee work but delegate the dirty bits. This would be fixable (they could oversee a team of mediocrities, who'd be grateful just to be employed) but they generally don't have the patience for that.

(2) those who want to do highly-theoretical R&D work that doesn't necessarily solve any immediate problems of the business.

(3) those who have a specialty (say, deep neural networks) and want to be in the umbrella of a large organization that can protect it. Pull them out of their specialties and they'll try to leave.

In other words, these supposedly stodgy non-technology companies _do_ , contrary to stereotype, have good programmers (I've worked in a few) but the ones who are at all decent have career strategies that they expect to be able to implement in their full-time work. They won't work on "just anything" and if you stick them with the random muck that comes from the line of business or zealous "product people", they'll either leave or slack in order to learn new skills on the clock, and the project will be done poorly or even abandoned mid-flight.

The appeal of the $3000-per-day consultant is that he'll work on what he's told to do and he doesn't expect you to consider his career needs. He's not going to do a shitty job and leave after 6 months because the people allocating the work don't care about his career; that's what the money (4-6x typical salary) is for. He gets his education and career advancement on his own time and dime (but earns a premium to account for his unpaid work). And while he might not be a great (2.0+) programmer, he's better than anyone in- house who could actually be assigned a bad project without political friction or high departure risk.

The average Bay Area startup programmer, like the average software consultant, isn't great; but he's far better than the corporate serfs who get sloshed around on the worst projects. He might be 1.4-1.5; so Goldman's R&D engineers and it top quant-coders will be better, but he's a relative colossus compared to the in-house peons (0.7-1.2) in back-office IT who'd get assigned to grody projects based on internal processes.

(Of course, not all the work that consultants do is undesirable. You also have the specialists and those with elite levels of skill. My point is that a "mercenary" consultant will power through the ugly projects for the pot of gold, whereas in-house people expect investment in their careers.)

In other words: yes, Goldman can hire great people. But if you want to hire someone great to do a project where 99% of the work is mediocre (and the 1% is extremely careful and requires an expert) you want the $3000/day consultant because Goldman can't get anyone good who's in-house (and not getting a consulting salary) to do the work. One might ask: why don't they pay an internal person $3000 per day, as they would a consultant? The answer is that it'd have him out-earning his boss and they'd often end up promoting someone not on traditional definitions of readiness (increasing scope, leadership) but because he took on an icky project.

<comment><USER33> Can you please explain the numbers 2.0+, 1.4-1.5, etc. when referring to a programmer's skill. I have never seen this before.

<comment><USER32> Roughly speaking, it represents the transition from an adder to a multiplier. A 1.0 programmer is competent at "adder" tasks (scripts, bug fixes, features) but not yet ready for infrastructural work. A 2.0 programmer is highly competent as a multiplier. It goes from 0.0 (complete beginner) to 3.0 (global multiplier) but most (probably 99%) professional software engineers are between 0.8 and 2.2, with a median around 1.1-1.2.

This is more up to date than nostrademons's link:[http://michaelochurch.wordpress.com/2013/04/22/gervais- macle...](http://michaelochurch.wordpress.com/2013/04/22/gervais- macleod-23-the-shodan-programmer/)

Also, from Quora: [http://www.quora.com/What-do-the-top-1-of-software- engineers...](http://www.quora.com/What-do-the-top-1-of-software-engineers-do- that-the-other-99-do-not/answer/Michael-O-Church)

<comment><USER34> Reminds me of Landau's logarithmic rating of physicists by productivity from 5 to 0, with 0 being Newton, 0.5 Einstein, etc.

<comment><USER32> This isn't general enough to apply to computer scientists, nor do I intend it as an all-purpose ranking for software engineers. It's an approximate measure of a generalist's professional development. It's not really applicable to, say, machine learning experts.

</comment></comment></comment></comment></comment></comment><comment><USER35> Of course, all across the US, crossroads, villages, and towns up to the largest cities, millions of US entrepreneurs, often sole proprietors, have to make money enough to pay suppliers, the rent, taxes, insurance, the bookkeeper, the accountant, the lawyer, employees, and take money enough home to support the family, the cable bill, the wireless bill, for dear wife, a late model SUV for her work as family taxi, the groceries, the home furnishings, and the lawn service, for junior, running shoes, a bicycle, a computer, and school clothes, for dear perfect, precious daughter, violin strings, a new iPhone 6, new school clothes, new dress up clothes, white furniture for her bedroom, a new prom dress, and save for college, retirement, etc.

So, millions of sole proprietors do that.

So, maybe it's not too much to ask of venture funded entrepreneurs to do similar 'budgeting'.

Still, it can be easy for such entrepreneurs to be fooled by venture firm Web sites that emphasize that they have been in the shoes of entrepreneurs and know what they are going through, are committed to their entrepreneurs, through good times and bad, through thick and thin, etc.

Still, the the importance of planning is old: In early aviation too many smoking holes taught the possibilities of head winds, bad weather, and mechanical problems and, thus, the importance of flight planning reserve fuel, alternate destinations, at least two of radios, each of the fire wall instruments, etc.

</comment><comment><USER36> > I try to resist coining phrases

Is this because you feel it's pretentious to do so?

I feel like having a concise name for a concept is one of the most important steps to broad understanding of it and always try to come up with good names for concepts that I want to be able to talk to people about. You might be doing us a bit of a disservice by resisting this.

<comment><USER37> "Survival of the fittest" is an example of a coined phrase gone wrong, wherein a sound bite subsumes what it is supposed to only represent.

</comment></comment><comment><USER38> Without some revenue, every company is on a direct course for disaster - <USER2> default. I think that the first pitfall some make is to look at investment money as revenue, cash coming in. But its a big giant fallacy.. it is not money from normal operations. Until you sell a product and have money coming in from it you are on borrowed time. This can be intentional and calculated position of building a product and bringing it to market when it is ready, but I get the impression that many don't plan or execute their way out of this fast enough.

<comment><USER39> Having money 'around' tends to make people complacent...people on the outside can't tell the difference between earnings and investment...and this tends to play tricks with people (and their minds( on the inside as well.

</comment></comment><comment><USER40> _They 'll all lose their jobs eventually, along with all the time they expended on this doomed company_

They were getting paid, right? I'm not losing time I work at a company that will eventually fail.

<comment><USER41> I think it assumes you want to be a part of something which makes a long term impact. If you just want a pay check, you probably aren't at a startup (or at least not for the right reason).

</comment></comment><comment><USER42> How do you keep your employees in this market if you're lowering salaries across the board?

<comment><USER43> I'd suggest technology is a key attraction. People involved in startups are there not only because it might get big, but also because the technology they are using excites them.

</comment></comment><comment><USER44> This is the story of the first startup I was participating into, back in 2000. The boss (and main investor) ruined himself (selling his Porsche, mortgaging his home, selling stock he should have kept...) while trying to get investors interested in a 0.1% done prototype of a project 10 years too soon (basically we were busy inventing the Cloud and Big Data). Sad story.

</comment><comment><USER45> I've never been one to lean on investors as a solution to problems. Its far better to build your company on the basis of the immense amounts of help and good you are doing your customers. If you're not doing that, and its not a principle focus for how you're going to produce revenues, then its not business but rather an academic experiment.

Investment is very important, though, for various big-growth reasons, but mostly to extend reach beyond what the business-as-organism is capable of attaining independently. Better to grow strong by remembering who really pays the bills: true customers.

Too many startups conflate investor/customer in strange ways before they realize there is actually a relevance to how much of the company is your company.

</comment><comment><USER46> Is becoming ramen-profitable before you raise your first round a possible solution to this problem?

<comment><USER14> If you can become profitable without raising funds then why raise funds?

<comment><USER47> A very commonly heard refrain in the Valley is some variant of: "Would you rather own 100% of a company worth $1 million or 40% of a company worth $200 million?"

Money is used to purchase acceleration. It's not totally crazy, although it implies very different trade offs as compared to running one's own business without investors.

<comment><USER14> The problem here is risk is ignored. If I were to rephrase the question as "Would you rather own 100% of a company with a 50% chance of success or 40% of $200 million company with a 1% of success?" then the answer we get is very different.

<comment><USER48> This is true. One can draw their own conclusions about those who say such things, and why the risk element is elided when they say it...

</comment></comment></comment></comment></comment><comment><USER49> Does anyone have tips for quickly and responsibly finding a spot on the slippery slope of consulting? We have found our few distractions so far to be too distracting.

<comment><USER50> I do. Shoot me an email.

</comment></comment><comment><USER14> Isn't the problem that the founders have to spend like drunken sailors to show "traction" to have any chance of getting more funding while their investors give them so little money that the runway is then incredibly short? There is very little room for error here.

<comment><USER36> Why would you have to "spend like drunken sailors" to show traction? I think you make a much more compelling for having traction if you can continue to grow while spending like a sober sailor.

<comment><USER24> This is a meme about the evils of venture capitalists, that their expectations are so uncalibrated that it's more important to act the part than it is to play the part. It might even be true in a lot of cases, but that doesn't make the strategy any sounder, right? You should just write off those investors.

(My take on this is very secondhand, unless you count experience from 1999.)

<comment><USER14> It certainly doesn't make the strategy any sounder, but why are highly intellegent founders who have far more to lose than any investor getting caught in this pinch? This seems to be the missing question from Paul's post.

Edit. Changed how to who :)

<comment><USER24> Founders aren't entitled to investor money.

Investors are looking for a particular curve. The slow burn, 7-figure exit that founders want is almost useless to VCs. The model requires that the winners pay for the losers. The VC has a finite number of at-bats every year, and each one needs to potentially be an out-of-the-park home run. A company that deliberately bunts is costing the VC an opportunity to recoup their losses on failures, which is the majority of their portfolio.

Founders like to kid themselves about this, but if they raise from a big institutional VC and plan on sitting on the money or executing on a "safe" 1.5-2x model, they're the ones being deceptive.

Safe, conservative plans are awesome. That's why companies should bootstrap.

There's a difference though between swinging for the fences and throwing money away.

<comment><USER14> >Investors are looking for a particular curve. The slow burn, 7-figure exit that founders want is almost useless to VCs. The model requires that the winners pay for the losers. The VC has a finite number of at-bats every year, and each one needs to potentially be an out-of-the-park home run. A company that deliberately bunts is costing the VC an opportunity to recoup their losses on failures, which is the majority of their portfolio.

This is the problem isn't it. Investors are basically saying unless you can hit 30% month on month growth then we aren't interested in you, but if you do what is required to hit this target then we won't give you the funding to do this with a reasonable runway.

>Safe, conservative plans are awesome. That's why companies should bootstrap.

I agree 100%. Almost all founders should avoid taking VC money and just bootstrap. This of course is not the sort of meme that is popular with VCs.

<comment><USER24> No, _founders_ are accepting the amount of funding VCs give them. I don't love VCs, but it's weird to blame them for this phenomenon. The VC model can't work differently. Most companies fail, and the winners have to pay for the losers.

<comment><USER14> I am not blaming VCs, I am blaming founders for taking VC money when the model they are giving it to you under is fundamentally flawed.

It is debatable if VC model couldn't be made to work better, but if this is how they are going to play the game then you are better off not playing and get on with bootstrapping.

<comment><USER51> But the _model_ isn't fundamentally flawed. Many founders just want to apply it in situations where it doesn't work. VC money is useful when you have a scalable, winner-take-all market that requires a large amount of capital to build out a viable product that you can monetize. If any of those clauses don't apply - the market is not scalable, the market is not winner-take-all, or the capital requirements for monetization are not large - a founder should not take VC. (Strangely, VCs are much better at telling founders when the VC model doesn't apply: many will outright refuse to fund companies that don't meet these qualifications.)

But for founders who _are_ attacking markets with those characteristics - <USER3> existence of VC is a huge boon that can accelerate what would normally be a lifetime process (eg. Walmart, Microsoft) into a decade or less (Google, Facebook).

</comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER52> caveat left out: the author makes twice more money if a startup takes one round of funding instead of two :)

</comment><comment><USER53> Can someone tell pg that he should stop putting hard <br/> every forty characters?

One of the fundamental aspects of the web is that presentation is done by the client, not the publisher. Please let me reflow the text as I see fit.

<comment><USER54> Challenge accepted!!

After opening the article, copy & paste the following line into the URL field:

javascript:a=document.createNodeIterator(document.getElementsByTagName('table')[0],NodeFilter.SHOW_ELEMENT,{acceptNode:function(node){return(node.getAttribute('width')&&node.nodeName!=='IMG')?NodeFilter.FILTER_ACCEPT:undefined;}});while(b=a.nextNode()){b.setAttribute('width','100%')}

Make sure your browser doesn't strip the "javascript:" at the beginning automatically, there's a good chance that it might; in that case, you'll have to type that in yourself.

</comment></comment><comment><USER55> Disappointing how few startups focuses on organic growth, most startups nowadays prefer to clamber for the attention of investors instead.

</comment><comment><USER56> tl;dr :: nobody wants to board a sinking ship.

<comment><USER57> That is one key takeaway, but if you read the entire essay there are many other useful points.

tl;dr :: tl;drs suck

</comment></comment><comment><USER58> This is awesome. Fully agreed with the, "don't expect to raise money to figure it out." It's why we're consultants. :)</comment>


Mothership Down: Apple bug halts the production of development certificates. - <AUTHOR> https://discussions.apple.com/thread/3799289?tstart=0 <comment><USER2> Last year, over a period of a few days, the certificates generated on developer.apple.com suddenly had an expiration date set to the year 2079. Usually the certs only last for 6-12 months. Too bad the certs are also locked to a set of device IDs... or we could have had unlimited code signing ability forever ;) [or until a revoke push]

</comment><comment><USER3> Wow. This thread is bringing out the ABA trolls in full force.

For those that don't get it:

Guys. Code signing is a _good thing_. It prevents code being screwed with by a malicious third party or some form of malware before it ends up on your device. Apple's implementation on the generation side leaves a lot to be desired, admittedly, but the concept is sound.

You'd best get used to it now. You're only going to see it more and more as time goes on - and not just on "jailed platforms".

<comment><USER4> Obligatory rms "Can You Trust Your Computer?": <http://www.gnu.org/philosophy/can-you-trust.html>

<comment><USER5> RMS uses a laptop with a Chinese CPU right?

<comment><USER3> Indeed he does. Everything down to the BIOS is FOSS. Apparently worrying about hardware inbuilt backdoors is a level of paranoia too high even for Stallman.

</comment></comment></comment></comment><comment><USER6> Man, do I hate that ridiculously complicated certificate system. I wonder how many first-timers don't recognize this as a bug and in frustration think "This is ridiculous, let me try again tomorrow".

<comment><USER7> I'm not a first timer, but I recently signed up for a developer account and went to set it up last night. I spent a few hours getting angry and trying everything I knew to make it work, until I went to the Apple Dev forums and saw a post about it.

It's so complicated that I couldn't tell if it was broken or if I was doing something wrong.

</comment></comment><comment><USER8> I wish deployment to the iPhone would be as easy as to the Android. Why mess around with deployment certificates in the first place?

<comment><USER9> Release android APK files are also signed.

<comment><USER10> Yes, apks are also signed, but the key generation is up to you. It's no problem to use self generated keys, it just has to be the same key across different versions of the same app.

</comment></comment></comment><comment><USER11> Only fitting that in that thread there is not a single reply from Apple.

<comment><USER12> It is only 14 hours old, started on a Sunday evening in a user generated content community forum. It's 6am in Apple land, I'm sure some employee is about to get a surprise.

<comment><USER11> I think the answer is more along the lines of seclorum's reply. Ops people in self-respecting companies are always watching.

</comment></comment></comment><comment><USER13> Well that's a bummer.

RDARs have been filed. Actions will be taken. The mothership will come back up. Haters will still hate code signing and provisioning profiles.

</comment><comment><USER14> Does anyone have any insight into this problem at all?

</comment><comment><USER15> Ask Anonymous to put down these crappy systems for life

<comment><USER16> Aye. What mothership? I'm not a fucking slave to the retardation that is this entire company. They regularly show they can't manage anything properly.

<comment><USER4> They seem to be managing revenues and their share price just fine.</comment></comment></comment>