Graham's Number Is Too Big to Tell How Big It Is - <AUTHOR> https://blogs.scientificamerican.com/roots-of-unity/grahame28099s-number-is-too-big-for-me-to-tell-you-how-big-it-is/ <comment><USER2> Graham's Number used to be the biggest number I could name, but now I understand that TREE(3) ( [https://en.wikipedia.org/wiki/Kruskal%27s_tree_theorem](https://en.wikipedia.org/wiki/Kruskal%27s_tree_theorem) ) is bigger still by a truly incredible amount (and TREE(1) = 1, and TREE(2) = 3).

Unfortunately I don't understand that Wiki page.

The page links to [https://en.wikipedia.org/wiki/Friedman%27s_SSCG_function](https://en.wikipedia.org/wiki/Friedman%27s_SSCG_function) , which is supposedly even bigger but I can't follow the text of the first page so won't attempt to read that.

<comment><USER3> TREE(3) is indistinguishable from zero compared to Loader's number[1], which basically takes every bit pattern up to some n and expresses this as a program in the Calculus of Constructions. This system is a bit weaker than being Turing complete, but the programs do always terminate (this makes the number computable compared with, say, the Busy Beaver number which does a similar thing with Turing complete programs).

It also has the geek cred of being represented by an obfuscated C program (the unobfuscated verson is also available[2]).

[1] [http://googology.wikia.com/wiki/Loader%27s_number](http://googology.wikia.com/wiki/Loader%27s_number)

[2] [https://github.com/rcls/busy](https://github.com/rcls/busy)

<comment><USER4> I can trivially define a function that's vastly larger than that. What's interesting is when these numbers are useful for something.

k(1) = TREE(1), K(2) = TREE(TREE(2)), K(3) = TREE(TREE( <(repeats (TREE(3) time (TREE(3)))

Sequence 1, 2, non comprehensibly large number.

Now define m(x) in terms of k and m(x-1).

<comment><USER3> > k(1) = TREE(1), K(2) = TREE(TREE(2)), K(3) = TREE(TREE( <(repeats (TREE(3) > time (TREE(3)))

What you've made here is what's known in googology circles as a 'salad number'. It doesn't make a conceptual leap above what the TREE function can do anyway and is kind of similar to saying TREE(3) + 1.

SCG(13) is much bigger than your K(3) and Loader's number is much bigger than SCG(13). There are (computable) numbers bigger than Loader's number which are mentioned in the googology link in my previous post (Greedy clicque sequences and finite promise games).

<comment><USER4> Yea, the point was to pick something trivial. K(3) is larger than TREE( any obvious function to a non mathematician of any printable number).

But it's the m(x) that's actually large in that example.

<comment><USER3> > But it's the m(x) that's actually large in that example.

Sure, it's large (mindblowingly so), although I'm not quite clear exactly how you define m(x).

It's hard to get a grasp on just how much vastly larger each of these 'rockstar' numbers is to the previous one when you ascend this conceptual hierachy. (To a certain extent, that's the point of the article.)

You could make a K(K(K(...(n)...) function where you painted a K on each particle in the visible universe (about 10^80) and it still wouldn't come close to Loader's number. The point is that you can't simply recurse TREE and hope to get a number that's conceptually any bigger than TREE itself.

<comment><USER4> Yea, at some point you really can't tell if function 1 grows faster than function 2. Anyway to pick a large m(x).

m(0) = 1; m(x) is the recursion of all finite functions defined using k(m(x-1)) symbols that produce larger numbers than their input defined at stage m(x-1).

So a 1 step function F1(x) = X + X and F2(x) = X ^ X,... including any function that has been included in a mathematical paper to this point that takes one ore more finite numbers as an input.

And because these are all finite functions call them recursively in whatever order produces the largest output starting with the initial input (x). Now, to size this depends on what initial notations are allowed, so m(1) is a finite number.

Next level could then include F#(x) where F1(F2(x)) etc.

PS: The above is roughly equivalent to saying infinity +1 and is not interesting IMO. I can also drop the k from the above, but again the point is to use the dumbest approach that works.

<comment><USER3> Sounds a bit like Yudkowsky's number[1] (your main step is the first one, everything else is salad), which is a computable version of Rayo's number[2])

[1] [http://googology.wikia.com/wiki/Yudkowsky%27s_Number](http://googology.wikia.com/wiki/Yudkowsky%27s_Number)

[2] [https://en.wikipedia.org/wiki/Rayo%27s_number](https://en.wikipedia.org/wiki/Rayo%27s_number)

<comment><USER4> Sure, but you need a large seed number at some point for functions like this. ex: Rayo's used 10^100.

So, they are all going to be take large value and use it to boost some other function m(x). I just happen to pick a large f(x).

</comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER5> Obligatory: [https://www.scottaaronson.com/writings/bignumbers.html](https://www.scottaaronson.com/writings/bignumbers.html)

(Yes, I know this gets posted every time one of these topics comes up, but there's always someone new who hasn't read it yet.)

<comment><USER6> I assumed your link was going to be this one about a "graspable" description of the number 52! (factorial).

[https://czep.net/weblog/52cards.html](https://czep.net/weblog/52cards.html)

Start a timer that will count down the number of seconds from 52! to 0. Then walk around the world along the equator, at the very leisurely pace of one step every billion years. The equatorial circumference of the Earth is 40,075,017 meters. After you complete your round the world trip, remove one drop of water from the Pacific Ocean. Now do the same thing again: walk around the world at one billion years per step, removing one drop of water from the Pacific Ocean each time you circle the globe. The Pacific Ocean contains 707.6 million cubic kilometers of water. Continue until the ocean is empty. When it is, take one sheet of paper and place it flat on the ground. Now, fill the ocean back up and start the entire process all over again, adding a sheet of paper to the stack each time you've emptied the ocean.

Do this until the stack of paper reaches from the Earth to the Sun. Take a glance at the timer, you will see that the three left-most digits haven't even changed.

<comment><USER7> Just to snark a little - that model assumes a constant earth. After a billion years (the first step) there will be no water left in the pacific anyway. If there's even a pacific ocean by then due to plate tectonics...

Sorry.

<comment><USER8> The page being quoted points that out:

> Of course, in reality none of this could ever happen. Sorry to break it to > you. The truth is, the Pacific Ocean will boil off as the Sun becomes a red > giant before you could even take your fifth step in your first trek around > the world. Somewhat more of an obstacle, however, is the fact that all the > stars in the universe will eventually burn out leaving space a dark, ever- > expanding void inhabited by a few scattered elementary particles drifting a > tiny fraction of a degree above absolute zero. The exact details are still a > bit fuzzy, but according to some reckonings of The Reckoning, all this could > happen before you would've had a chance to reduce the vast Pacific by the > amount of a few backyard swimming pools.

<comment><USER7> Well in which case I apologise :)

</comment></comment></comment></comment></comment><comment><USER9> David Metzler's series "Ridiculously Huge Numbers"[1] is a good introduction to this. It goes rather well beyond puny little integers like Graham's number.

Loader's number has already been mentioned here, but I don't see any mention of the Busy Beaver function[2]. BB(n) is the maximum number of 1s that can be written of a 2-color, n-state halting Turing machine starting from a blank tape and counted after the machine halts. This is of course uncomputable, and grows very quickly. Rayo's function (Rayo(n) = the smallest natural number greater than all natural numbers that can be uniquely identified by a first order set theory expression of at most n symbols) grows even faster, but that requires a non-recursively enumerable set theory or the use of non-provable functions.

[1] [https://www.youtube.com/watch?v=QXliQvd1vW0&list=PL3A50BB9C3...](https://www.youtube.com/watch?v=QXliQvd1vW0&list=PL3A50BB9C34AB36B3) [2] [http://googology.wikia.com/wiki/Busy_Beaver](http://googology.wikia.com/wiki/Busy_Beaver)

<comment><USER3> > David Metzler's series "Ridiculously Huge Numbers"[1] is a good introduction > to this. It goes rather well beyond puny little integers like Graham's > number.

Yes, David Metzler's series is great and, I would say, essential viewing if your interest in large numbers is piqued.

While he doesn't go through some of the big numbers talked about her (TREE(3), SCG(13), etc), he gives an excellent explanation of the fast-growing hierarchy. This is really the closest thing we have to a 'standardized' way of comparing the sizes of very large numbers.

I would also recommend Giroux Studios' 'Extremely Large Numbers'[1], which takes a similar style to Metzler's videos and goes further with the fast- growing hierarchy. (Does something called 'infinite collapsing functions' sound interesting...?)

[1] [https://www.youtube.com/watch?v=vq2BxAJZ4Tc&list=PLUZ0A4xAf7...](https://www.youtube.com/watch?v=vq2BxAJZ4Tc&list=PLUZ0A4xAf7nkaYHtnqVDbHnrXzVAOxYYC)

<comment><USER9> Metzler's series got expanded a while back, he does have some sections on TREE (though not on SCG, SSCG, etc). IIRC there's a brief bit about ordinal collapsing functions as well, but not very detailed.

<comment><USER10> Let me propose YOUTUBE(n) which represents the number of YouTube videos about the mathematics of large numbers.

</comment></comment></comment></comment><comment><USER11> A while back someone on math stackexchange asked "Graham's Number: why so big?" and I wrote what I think is a pretty good explanation.

If you're interested, it's at [https://math.stackexchange.com/q/163423/25554](https://math.stackexchange.com/q/163423/25554)

<comment><USER12> Superb.

</comment></comment><comment><USER13> Somewhat more visually satisfying explanation:

[https://waitbutwhy.com/2014/11/1000000-grahams- number.html](https://waitbutwhy.com/2014/11/1000000-grahams-number.html)

<comment><USER14> Man I really wonder what your brain is doing when you try to comprehend those numbers.

> thinking about Graham's number has actually made me feel a little bit calmer > about death

</comment></comment><comment><AUTHOR> "But Graham's number is different. I can't tell you how many digits it has. I also can't tell you how many digits its number of digits has, or how many digits the number of digits of its number of digits has. They're all too big."

<comment><USER15> This is really mild in comparison to the number. You can't tell how many times after repeating that you can tell the number of digits in it.

</comment></comment><comment><USER16> Thinking about Graham's Number reminds me of this quote from CS Lewis's That Hideous Strength

"Saturn, whose name in the heavens is Lurga, stood in the Blue Room. His spirit lay upon the house, or even on the whole earth, with a cold pressure such as might flatten the very orb of Tellus to a wafer. Matched against the lead-like burden of his antiquity, the other gods themselves perhaps felt young and ephemeral. It was a mountain of centuries sloping up from the highest antiquity we can conceive, up and up like a mountain whose summit never comes into sight, not to eternity where the thought can rest, but into more and still more time, into freezing wastes and silence of unnameable numbers. "

</comment><comment><USER17> This raises the question of what it means to "tell someone how big it is". Does it mean to write it using some particular notation (such as positional notation or exponentiation)? Does it mean to instill a satisfactorily good image in someone's head of how big it is? I mean, mathematically speaking, any definition of a number is as good as any other, and Graham's number can be defined perfectly well.

</comment><comment><USER18> Don't know about you, but I like this explanation of Graham's number:

[https://youtu.be/1N6cOC2P8fQ](https://youtu.be/1N6cOC2P8fQ)

</comment><comment><USER19> Conway chained arrow notation [0] is really mind blowing. The simple notation of "3 -> 3 -> 3 -> 3" results in a number that is larger than Graham's number.

[0] [https://en.wikipedia.org/wiki/Conway_chained_arrow_notation](https://en.wikipedia.org/wiki/Conway_chained_arrow_notation)

</comment><comment><USER20> Numberphile also did a great video on TREE(3) here (a 'useful' number larger than Graham's): [https://www.youtube.com/watch?v=3P6DWAwwViU](https://www.youtube.com/watch?v=3P6DWAwwViU)

</comment><comment><USER21> There was a puzzle in the MIT mystery hunt a couple years back that involved sorting large numbers. Graham's number was somewhere in the middle.

[http://web.mit.edu/puzzle/www/2016/puzzle/identify_sort_inde...](http://web.mit.edu/puzzle/www/2016/puzzle/identify_sort_index_solve/)

</comment><comment><USER22> "And in Go, which has a 19-by-19 board and over 10150 possible positions, even an amateur human can still rout the world's top-ranked computer programs."

When was this written? Evidently before 2017.

<comment><USER23> > By Evelyn Lamb on April 1, 2014

<comment><USER24> A bit of a tangent, but it blows my mind how quickly Go went from "computers are so terrible at it that they can't even beat a decent amateur" to "computers utterly crush the world champion."

</comment></comment></comment><comment><USER25> I really don't like this kind of writing, it spending too much time gawking at the number and little explaining.

I would rather recommend this video of Graham himself explaing Graham's Number. [https://www.youtube.com/watch?v=HX8bihEe3nA](https://www.youtube.com/watch?v=HX8bihEe3nA)

</comment><comment><USER26> My children loved to invoke googol, like most children it seems. "I want to eat googol cookies!" But I always sternly warned them it was a big number—most of their invocations pretty much entail the observable universe immediately collapsing into a black hole. Then of course they caught wind of googolplex, which is just nuts, and I keep telling them "that's nuts!" Now they're onto Graham's number, and I've run out of tools to convey how insane it is. I'm relegated to saying things like "Remember googolplex? Well that's peanuts compared to Graham's number." I don't think I'm getting through to them.

</comment><comment><USER27> The linked Numberphile video mentions that a black hole the size of a human head wouldn't have enough entropy to encode Graham's number. So what diameter of black hole would actually be required?

<comment><USER3> Well, you could plug Graham's number into the Bekenstein–Hawking formula[1]. The formula defines the area and there's a factor of the plank length in there, but Graham's number is so overwhelming that the the result is pretty much Graham's number in any units you want.

[1] [https://en.wikipedia.org/wiki/Black- hole_thermodynamics](https://en.wikipedia.org/wiki/Black-hole_thermodynamics)

</comment></comment><comment><USER14> Reminds me of Chaitin's constant:

> In the computer science subfield of algorithmic information theory, a > Chaitin constant (Chaitin omega number)[1] or halting probability is a real > number that, informally speaking, represents the probability that a randomly > constructed program will halt.

> Each halting probability is a normal and transcendental real number that is > not computable, which means that there is no algorithm to compute its > digits. Indeed, each halting probability is Martin-Löf random, meaning there > is not even any algorithm which can reliably guess its digits.

~ [https://en.wikipedia.org/wiki/Chaitin%27s_constant](https://en.wikipedia.org/wiki/Chaitin%27s_constant)

</comment><comment><USER28> Are there even a Graham's Number of things we could count in the observable universe?

<comment><USER29> Definitely no. Overwhelmingly and absurdly no.

Think about it this way.

You can count by just adding. |||| is four. When you're counting small things, that works fine.

Then you have multiplication. Instead of writing |||||||||||||||||||| we just write 20. We developed a new abstraction to write large numbers easier.

Then you have exponentiation: 10000000000 is just 10^10. This is abstraction is all the further you need to go to talk about the number of atoms in the Universe (which is roughly 10^80), the speed of computers (And exaflop is 10^18 operations per second, there are 10^7 to 10^8 seconds in a year, and the universe is 10^10 years old, so if each atom were an exaflop computer, you could do 10^(80+18+8+10) = 10^116 operations. Easily written in scientific notation. This is really all the level of abstraction needed for roughly writing large numbers in science and technology. But not for math. Certain proofs can require absurdly larger numbers.

So what if we abstracted exponentiation? So, instead of writing 10^10^10 (which is 10^10000000000), we write, say, 10^^3. And we can keep doing that. But what if we iterate on the number of _abstractions_? So the number of "^"s is abstracted, i.e. 10 ^{m} 10. and THAT is abstracted n times (i.e. we replace m with the previous 10 ^{m} 10, n times). Graham's number is n=64.

No doubt I probably made a mistake in here... But:

tl;dr: no, we need to develop totally new abstractions to represent Graham's number. Numbers which can be merely represented directly in our universe are easily written in exponential format.

</comment></comment><comment><USER30> It's not too big to comprehend. It's a number, which if you could keep all digits in your mind, would cause your head to collapse into a black hole several times larger than observable universe.

</comment><comment><USER31> It's a bit of a tangent, but if you find it pleasing (stirring might be a better word) to contemplate large numbers like this, and are curious about why that may be so, you may be interested in Kant's reflections on the aesthetic appreciation of the sublime, see [https://en.wikipedia.org/wiki/Sublime_(philosophy)#Immanuel_...](https://en.wikipedia.org/wiki/Sublime_\(philosophy\)#Immanuel_Kant) for an intro.

</comment><comment><USER32> [http://www.polytope.net/hedrondude/scrapers.htm](http://www.polytope.net/hedrondude/scrapers.htm)

</comment><comment><USER33> Since we're talking about mind-boggling quantities, although this is more related to cardinals it's one of the most fascinating pieces I've ever read.

[https://johncarlosbaez.wordpress.com/2016/06/29/large- counta...](https://johncarlosbaez.wordpress.com/2016/06/29/large-countable- ordinals-part-1/)

<comment><USER34> I just read all three posts. Very silly, very entertaining. I remember seeing that "clock diagram" of ordinals years ago, and wondering what happens if you take it further. Now I know!

</comment></comment><comment><USER35> Is just the elegance in they way it outputs the large number. I could easily do an expontianial of an exponential of exponential repeatedly exponentially and that would be hard to imagine, but it would look hacky

</comment><comment><USER36> So here's a question that popped into my mind: Is it possible to define two computable functions, f() and g(), such that the truth or falsity of f(x) < g(y) is not computable?

<comment><USER37> No, could be proven by the transitivity of computability under composition.

Provided the function <(,) is computable for all typeof(f) and typeof(g).

<comment><USER36> Interesting, thanks. So it should be possible to define f() and g() such that neither of those are computable, but the truth of f(x) < g(x) is computable, but not so much for f(x) < g(y). Could one construct a couple of monotonically increasing uncomputable functions with that known relationship?

<comment><USER37> >So it should be possible to define f() and g() such that neither of those are computable, but the truth of f(x) < g(x) is computable, but not so much for f(x) < g(y).

The difficulty is really just defining an uncomputable function that has a definite value for some domain, but this can be done. Let's call one h.

f(x): -abs(h(x)) g(x): -f(x)

Gives your second inequality.

</comment></comment></comment></comment><comment><USER38> A good example of mathematical representation as compression.

</comment><comment><USER39> I guess it's all in the eye of the beholder. For instance, Erdos would say that, for him, the Graham number is just 1.

</comment><comment><USER40> I just watched a video on how this number is derived and now my head hurts.

</comment><comment><USER41> This needs a [video] tag.

</comment><comment><USER42> I love articles like this, they make science so approachable.

</comment><comment><USER43> Should these be called numbers or rather just processes which (in principle) arrive at numbers?

<comment><USER37> >Should these be called numbers or rather just processes which arrive at numbers?

They are one and the same. You can use a Graham's number place value system and Graham's number is simply written while a number like 7 might be quite complex to represent.

<comment><USER43> If a number and the process used to arrive at a number were completely equivalent, then going through the process to arrive at the number would never be worthwhile. Yet people are often interested in actually going through these processes to generate numbers, when it's practical to do so.

<comment><USER37> That's because they want to represent the number in a particular representation.

They are not "completely" equivalent, they are equivalent up to the representation, converting between representations can have very high computational costs.

But equivalent up to the representation is the usual notion of equality in mathematics, and if you mean something else you have to define it.

(Obviously in computer science, this difference is quite important and we need to differentiate between an expression and it's evaluation)

<comment><USER43> There still seems to be a difference in kind between a number represented in such a way that no further processing is needed, versus represented in a way in which further processing is needed.

To me, such a fundamental difference seems to deserve a distinction in nomenclature.

<comment><USER44> That's a distinction in goals though, not in concepts. If we want to know how many people are on a bus "the number of people you would count if you bothered" is a perfectly true answer. It's an accurate representation. You perhaps can't do anything more than talk vaguely about abstract bus populations with it, but that is a reasonable thing to do.

On the other hand, maybe "17" is the answer you want, because you need to compare it to some other integer or plug it into a function. Also useful things to do, but not always. And not even more often than the trivial alternatives.

Even though we're significantly biased toward wanting the latter form, it still means the same thing as the former. And the former is a description of a process, while the latter is a number. Or the former is a number, while the latter is a particular encoding of a process. Same difference in the end. We even define numbers by describing the processes we use to generate them.

</comment></comment></comment></comment></comment></comment><comment><USER45> FOOT</comment>


No Cooking for Me (thanks Mint) - <AUTHOR> http://webpoet.wordpress.com/2008/08/19/no-cooking-for-me/

<comment><USER2> Umm, right.

 _Writer of poetry embodying the web experience by one who is especially gifted in the perception and expression of the online experience._

If you say so. I, for one, found that this was an astonishingly bad format for whatever gem of wisdom or intelligence the "author" felt like imparting to the world.

<comment><USER3> i have no idea what that poem even said</comment></comment>


MIT Media Lab faked key elements of "personal food computer" project: insiders - <AUTHOR> https://www.businessinsider.com/mit-media-lab-personal-food-computers-dont-work-fake-staff-say-2019-9 <comment><USER2> As a fellow scientist this enrages me to no end.

It is little wonder that people lose faith in science if these kinds of quack researchers continue to claim revolutionary new inventions while swindling investors and the public out of money.

To nuance a little: I am not outraged by the fact that this project didn't work out. Research projects fail all the time; research is difficult and uncertain. The continued lying and pretending ("fake it until you make it"), however, is _very_ problematic and in _some_ labs and in _some_ research fields systemic.

Let's hope MIT and/or the Media Lab have an adequate response to this immoral misconduct.

<comment><USER3> "to no end" means: uselessly. "no end" means: endlessly.

[https://english.stackexchange.com/questions/69501/meaning- an...](https://english.stackexchange.com/questions/69501/meaning-and-usage-of- to-no-end#69504)

</comment></comment><comment><USER4> This is obviously poor timing with the Epstein scandal, but I feel like this isn't the first or last time this happens at the Media lab. Lots of ambitious projects are started by ambitious and/or desperate doctorates that we never hear about, some more bullshit than others.

</comment><comment><USER5> Maybe they can start by understanding how Click and Grow works, especially the soil in their capsules.

</comment><comment><USER6> MIT Media Lab is, almost entirely, a venue for precocious grad students to pad their resume at this point. When was the last time any meaningful research came from there?

<comment><USER7> There is a tremendous amount of image filtering and computer vision research that has come from there and get the last two decades. Don't get carried away with an internet pile on and try to make everything black and white.

</comment></comment><comment><USER8> Theranos redux.

<comment><USER9> Please don't post unsubstantive comments to HN.</comment></comment>


Low-Lock Singletons In D - <AUTHOR> http://davesdprogramming.wordpress.com/2013/05/06/low-lock-singletons/

<comment><USER2> This is an elegant solution to the double checked locking bug <http://en.wikipedia.org/wiki/Double-checked_locking>, incurring insignificant overhead.

<comment><USER3> Unfortunately, the space overhead is not quite that insignificant. It requires at least one bit of storage per thread; this does not matter much for a singleton class, but if you want to implement more general write-once data structures (such as arrays or hash tables), it's not negligible.

Somewhat less problematic is that fast TLS is not natively available on all architectures (in particular, Mac OS X). Luckily, this can be worked around relatively easily.

<comment><USER2> D does its own TLS implementation on OS X. But now that newer versions of OS X have native TLS, we'll be scrapping ours and using the native one.

</comment></comment></comment><comment><USER4> Or you could use atomic swaps on the initialized bit. That's both cheaper and simpler.

psuedocode:

        member atomic32 init
        member mutex lock
        member obj ptr

        membarrier()
        if (atomic_load(&init)) {
          return ptr
        } else {
          locked_init()
          atomic_save(&init, 1)
          membarrier()
        }

Not an expert, use this at your own risk.

<comment><USER5> If you have atomic swaps (hardware "lock-free"), the global shared instance pointer should be enough - since it either holds a valid pointer or it doesn't.

<comment><USER4> No, you don't want two threads trying to allocate the object at once. You still need a locked init.

<comment><USER5> Yes, there would be an allocation race, so if you cannot accept allocating unnecessarily in a discardable/recoverable way (but also one that preserves the semantics of the singleton: one and only one instance returned over its life), you would still need a flag. Though you might instead use an "incomplete"/place-holder reference value to simulate the flag and prevent duplication of effort/wasting resources while the allocation happens - all in the space of the pointer.

</comment></comment></comment></comment><comment><USER6> Doesn't D have the ability to do stuff on class initialization? Or does it not initialize classes lazily?

In Java, this is how a threadsafe Singleton looks like:

            private static MySingleton instance = new MySingleton();

It will be initialized when the class is first used.

The whole double-checked locking and TLS thing is IMO a huge pointless smartassery contest in VM lawyering hinging on the eminently false premise that having singletons in a heavily multithreaded environment initialized sooner than they're used is a problem that anyone needs solved.

Whereas in reality, 90% of all applications don't need lazy loading, and for 90% of those that do, the above is lazy enough.

<comment><USER7> I think you missed a static keyword in that line of code.

<comment><USER6> You're right; fixed.

</comment></comment></comment><comment><USER5> I don't think thread-local variables are necessary.

Consider a global flag that gets instantiated and synchronized across threads/cores to a state of 0 such that if it ever gets set to 1, it was after publishing and synchronizing the shared instance via a global pointer. This pointer, and the global flag, will not revert for the rest of the singleton's life (noted in the article) - so there is nothing to synchronize past that - and it is only for the guarding flag's 0 (unallocated) case that there is a question if things are synchronized. That check and potential allocation are what need a standard lock (provided by D's syncronized block), which the example already provides.

<comment><USER3> To get such a global flag with the desired behavior, you need explicit memory barriers. Otherwise, you cannot guarantee that it won't become visible to another processor before the object's data itself becomes visible.

The problem here is that the memory accesses for the path that bypasses the synchronization block are not guaranteed to occur in the correct order without barriers.

<comment><USER5> Yep - it should be enough to force a coherent view for all as part of the initialization.

<comment><USER3> Yes, it's well-known that you can fix the problem with memory barriers. But the article's point was that such memory barriers can be avoided entirely for the common execution path if you have fast thread-local storage (because you can make sure that every thread is forced through the full synchronization block once before accessing anything). Given that memory barriers can be expensive on some processors, that's a not insignificant win.

<comment><USER5> Does D's synchronization not contain memory barriers (I don't know)?

(Edited)

<comment><USER2> The problem with memory barriers is that they are slow. David's solution using TLS avoids them entirely for the usual case, hence it is much faster (as his benchmark results show).

<comment><USER5> Thanks for your comment. I do see that the TLS is used in a conditional to avoid the barriers in most cases (the already-initialized case), but the initialization still happens in a synchronized block. I may be wrong, but the docs for D say that effectively wraps the block in a critical section which seems likely to include rw barriers, meaning the code given has barriers at init _and_ also uses TLS. If so, the TLS would be unnecessary, for my reasons above - causing me to suspect that the example has just hidden the barriers behind the _synchronized_ keyword.

<comment><USER2> Yes, when it is synchronizing there are memory barriers. But the point is the synchronization and memory barriers can be skipped once the singleton is initialized. The usual case can then run without barriers.

<comment><USER5> Thanks again. If I am right though, the memory barriers could also have been skipped without thread-local values since, due to the barriers on init, no thread's view would revert to it's pre-init state anyway. As rbehrends mentions, barriers are not the only factor... For example, global memory access may be slower on some systems due to decreased locality (a property provided by the TLS), but I don't know what if any value that would have in this benchmark. There is also a comment on that page that does the same thing as my TLS-free approach using a more reasonable static global initialization syntax in Java in response to a question of if D's initialization would be semantically equivalent too.

Edit: (Not waiting for reply link to appear...) When I say "the memory barriers could also be skipped" I am referring to any other memory barriers past those associated with initialization, not those associated with initialization. There would be memory barriers at initialization, but that is the only need for memory barriers and I believe that is provided here by the synchronized keyword. The object presented in the article then looks like a cache-friendlier version of a single global variable with the necessary barriers limited to the initialization of the global instance pointer (which might also be done as in the Java example given in the comments on the page). The TLS does not eliminate the need for any barriers, only helps eliminate non-local reads. That might allow a performance gain depending on the cache behavior (or, for example, in the presence of NUMA), but it hasn't reduced the need for locking IMHO.

<comment><USER2> If multiple threads are accessing two globals, two threads are not guaranteed to see changes in one or the other in the same order. This is called "sequential consistency". The only way to get sequential consistency between threads is to insert memory barriers or use synchronization.

There is no way around this. Your statement that memory barriers could be skipped is exactly the source of the double checked locking bug. I know this is hard to understand, which is why it has tripped up a looong list of very smart people over the years.

David's article solves the problem by having one of the globals not be global at all, but thread local.

As for performance, David's article shows with benchmarks that his solution is a huge win.</comment></comment></comment></comment></comment></comment></comment></comment></comment></comment>


Who owns student-created intellectual property? - <AUTHOR> http://legalblogwatch.typepad.com/legal_blog_watch/2011/01/who-owns-student-created-intellectual-property.html

<comment><USER2> Check your school's policy.

I'm doing an honours thesis this year and some of my ideas have immediate commercial applications, so I looked it up. At the University of Western Australia, unpaid work by students remains the property of the student (Sub- regulation 4(2) of the Intellectual Property Regulations).

The rules change if your work is funded somehow.</comment>


Ask HN: What is my carbon/green gas footprint? - <AUTHOR> I've been trying to find a google calculator that would tell me what is my carbon and green gas footprint, but I failed to find one that is accurate and extensive.<p>- I work from home<p>- I live in a small one bed flat with my gf (50m^2), no aircon and efficient district heating<p>- use trams/bikes/electric scooters<p>- drive 10k miles a year (27 miles per gallon equals 10.5 liters per 100 kilometers)<p>- eat beef once a month.<p>- 16 flights a year (2,5h flights on average)<p>- I buy very little stuff (no TV or any other electronic apart from macbook, phone and a screen)<p>- my location has a CO2 production of 7.5 tonnes per capita <comment><USER2> I'm surprised how many people crave some sort of grade or score like an insurance appraisal when it comes to their footprint. I guess so if it's high, they can guilt themselves into reducing it, and if it's low, they can guilt others into reducing theirs (good luck with the second part).

There's also a big "cosmo-quiz" element here, where certain aspects involve a temptation to lie to yourself in order to get the score you feel you "deserve".

If I told you a cross-section of passengers on the RMS Titanic was comparing their relative contributions to the momentum of the ship toward the iceberg, you'd probably gain a different perspective on the question you asked.

A few nits here:

• _I work from home_

In what country, what kind of industry, and what kind of home? A coal commodities trader in Australia vs. a wind turbine designer in Denmark might make for a huge swing.

• _drive 10k miles a year_

Bumper-to-bumper or wide open high-speed driving? There's at least a threefold difference in those two numbers, with bumper-to-bumper using far less carbon.

• _eat beef once a month_

What about chicken? almonds? grapes? corn? Coca-Cola? The relative carbon footprints of each food would be necessary to know. Beef itself has a radically different footprint whether consumed in say, Texas, Brazil, or Japan.

• _16 flights a year_

On your own personal GulfStream V, or crammed in to full-up Spirit A321's? The former is a huge use of fuel whereas the latter uses fewer gallons of fuel per mile per person than driving an SUV alone.

• _I buy little stuff_

Wait until you reproduce, move, or your government expands. This is not a place you can commit savings and I think a lot of people struggle to accept this. Further, the stuff you buy can almost be inversely proportional in terms of transportation infrastructure requirements. Someone who gets one small Amazon package a month living on an Alaskan island with millions of dollars of bridge-to-nowhere infrastructure would be far bigger a carbon producer than a shopaholic clothes-horse living on a major Manhattan thoroughfare.

<comment><AUTHOR> > they can guilt themselves

I dont feel guilty and wanna guilt trip someone. I'm interested in the subject, because there is a lot of false information.

Is buying Tesla really that great? What if I drive very little? Maybe my totals C02 would be low (expensive production of Tesla).

Is beef that bad for C02? I have to grow grass that captures C02.

<comment><USER2> Is buying a Tesla that great for CO2 footprint? No, nor is buying any new car. Over the life of the vehicle, it's pretty close to a wash vs. a similarly- sized new BMW roadster, unless you drive it an awful lot. If buying a Tesla helps Tesla make more batteries more cheaply, and make gasoline a lower-volume commodity, then there's some benefit there.

Beef is bad for CO2 for 3 reasons:

1) getting water (pumping) to the beef or the cropland to feed the beef often causes CO2 to be produced.

2) growing cattle feed is extremely CO2-intensive due to the ammonia-based fertilizers corn uses. Every stalk of corn is producing CO2 because of the way we grow corn.

3) beef's popularity and need for feed means we're repurposing rainforest and releasing eons of poorly-sequestered carbon. It's a one-time hit, and then after that the damage is minimal, but it's a big one-time hit.

If you go strictly grass-fed beef, I suppose you could argue you're not producing as much CO2, but substitute CO2-intense beef would get that much cheaper in price, negating most of the benefit.

</comment></comment></comment><comment><USER3> Sounds like you have a minimal foot print other than maybe the flights but still below average.

Instead of spending time calculating your foot print so precisely:

Volunteer more in your community

Help elderly neighbors

Stay in closer contact with family and friends, visit them more (even if you fly)

Exercise more

Get out and enjoy nature

Get out and see the sights in your area

Sounds like you have a good general idea of what will reduce your carbon footprint, nice work.

Now focus on what your footprint on life will be, focus on helping others and enjoying life.

</comment><comment><USER4> the late David MacKay's "sustainable energy, without hot air" book about sustainable energy production versus energy consumption will help you roughly estimate your energy consumption. it's not the same thing as a carbon footprint, but it'll be more or less proportional.

[https://www.withouthotair.com/c18/page_103.shtml](https://www.withouthotair.com/c18/page_103.shtml)

worth reading the book if you have the time and are interested. it's free online.

From your list the one item that jumps out at me is 16 * 2.5 hour flights per year. i'd guestimate that accounts for 25% or more of your annual energy consumption, and 25% or more of your greenhouse gas emissions. probably roughly similar energy consumption footprint to eating 1 kg of meat / day.

personally i think the main thing people with relatively* high-energy affluent lifestyles can do regarding reducing their personal carbon footprint is to have fewer children than they want to. it's not really a done thing to talk about this, maybe it will be in a decade or two.

* relative in the global sense</comment>


Learning Curves for Different Programming Languages - <AUTHOR> https://github.com/Dobiasd/articles/blob/master/programming_language_learning_curves.md <comment><USER2> Everyone seems to be focusing on the PHP vs Haskell thing and seem to be missing the other points. Here's a summary:

Callbacks in Javascript make you feel more productive, but in fact you become less productive.

Design patterns in Java don't actually make much of a difference in productivity, but you think they do.

Templates in C++ seem hard but with a big payoff, but they don't accelerate productivity.

Unit tests in python do make you more productive, though it doesn't feel like it. Decorators on the other hand do not make you more productive, but they make you feel more productive.

In Lisp, macros accelerate both the feeling of productivity and actual productivity.

In Haskell, once your brain stops hurting you become productive. When you learn monads, your brain will hurt for a bit. While your brain hurts, your productivity declines. Once you get past understanding monads, your productivity grows at roughly the same rate as it did before you knew monads (in other words, monads do not accelerate productivity). Then you learn category theory, which has no bearing on your productivity but makes you feel less productive.

PHP is a bit of a cheap shot, stating that you won't become more productive over time but you will always feel super productive.

<comment><USER3> I'll take another tack and suggest that productivity today is more a function of what libraries might be available rather than language choice.

A language like Python has a massive number of really good libraries spanning a range of disciplines. Is it the "best" language (whatever that means)? Don't know. Don't care. You can get the job done and the ecosystem is huge.

I am not comparing Python to Haskell or anything else, just using it as an example. I don't use Haskell and wouldn't know how the libraries compare.

My only point is that when all the smoke and bullshit clears out the only thing that matters is if you can get the job done as required. If this includes a performance metric than language performance is important. If it does not, then library availability or other criteria might quickly become more significant.

From my own perspective, it would take a lot for me to choose anything other than Python for my work. When a platform mandates it --iOS native apps-- you have no choice. On embedded systems it's mostly C. When Python fits I can get shit done with it. Nothing else matters.

<comment><USER2> The graphs are not productivity vs language choice. They are productivity vs experience in a given language.

In languages with strong libraries, I'd expect a diminished benefit from experience. 10 years python experience doesn't make you much more productive in standing up a django application vs someone with 1 year of experience. Thus, the curve for python might very well be quite flat (since you start fairly high to begin with).

Lisp, on the other hand, may not start as high on the productivity scale. Because of its powerful macro system, the language can be tailored to suit your problem better than anything else.

That's what the graphs are talking about. How valuable experience is (and comparing it to how valuable we think our experience is).

<comment><USER4> Libraries can only take you so far.

A python developer with limited experience is likely to use too many 3rd party libraries in simple cases where they are really not needed. As the application grows this turns into a maintenance and/or performance nightmare.

Not to mention the fact that it takes experience to understand/troubleshoot/fix third party code. When things go wrong the dev with 10 years experience is going to be vastly more productive than one with less experience.

I am a python dev with >10 years experience and I manage numerous junior devs with limited experience, so I see this kind of thing all the time.

<comment><USER2> But are you actually gaining productivity when fixing third party code? Or are you losing productivity? I would say you are paying back the gains you got from using the library in the first place and therefore losing productivity. Granted, you generally come out ahead.

I think that's the plateau in most languages. You get to a point where you are fighting the language/ecosystem as much as it's helping you and so productivity plateaus.

</comment></comment></comment></comment></comment><comment><USER5> I am increasingly convinced that Haskell only exists so that people who know it can pat themselves on the back for being wonderful.

<comment><USER6> With the exception of pandoc, I don't recall seeing anything particularly impressive from the Haskell camp.

(Btw, this, actual stuff people use, is how I measure programming languages -- this metric takes into account communities, libraries, practical issues, etc all together, and ties them with practical results. It's my version of "let the market decide").

<comment><USER7> Darcs used to be the poster child for Haskell but then somebody came along and wrote a much better DVCS in C, of all languages. Draw your own conclusions...

<comment><USER8> Still use darcs to this day. Darcs is magical AND productive. I use a script to play back my darcs commits into a git repo so i can put my projects on github. I love you darcs, I love you.

</comment></comment></comment></comment><comment><USER9> Really don't understand the pure hatred that people have for PHP, I'm at network engineer and I don't have any desire to become a programmer because I love my job, however I've wrote some very useful applications that myself and my team use on a daily basis to make networking easier for us.

For me it was simple to learn PHP and create something 'useful', basically every web server is capable of running it which makes my life a lot easier as well.

Surely the fact that someone can hack together code within a few minuets that doesn't profess to be a coder is a good thing, regardless of the language that there using?

There is no better programming language than the one you know.

<comment><USER10> I'm no mechanic and I have no desire to be one but I've changed my own brake pads, surely anyone can adjust their car's brakes and many other tasks with a few simple tools and a book.

I don't understand why mechanics say some cars are better than others.

<comment><USER9> Playing around with motorbikes is actually one of my hobbies, and I have some very nice and quite expensive Snapon tools which work wonders in the garage.

However I'm certainly not going to suggest that changing your breakpads was done incorrectly because my tools cost more than what I'm assuming yours did, or that I could complete the same job a bit quicker and therefore better.

Sure, if you're going to change break pads all day long for the next year I can suggest some very nice tools which might help you.

But instead I'd like to say well done on changing the break pads, I'd wish more people would use the tools that they have at there disposal, show some initiative, and do the same.

</comment></comment></comment><comment><USER11> For goodness sake people. You can take a comic as an attack on a particular programming language, but how is this useful? Maybe there is wisdom in this comic or not, but there is value in people reflecting and presenting a humorous point of view.

I have used all of the languages above and found the comic humorous and greatly exaggerated. But I think that there is something here. If you haven't really used the exalted languages in this comic please try them. You can only learn from the experience.

Also, if users of a particular language appear to be elitist, this does not say anything about the value of the language itself.

An open mind is going to be both happier and more capable.

</comment><comment><USER6> He wanted to make a cheap joke, but PHP should be the opposite: productivity is rather high, while self-assesment is low.

<comment><USER12> I think by "self-assessment" is meant something more like "self-regard", the whole being taken to mean that PHP programmers have a relatively high opinion of themselves, which is not justified by the code they generate.

I gather the author is perhaps not a native speaker of English, so perhaps this is a subtlety which has simply passed him by. As such, I've opened an issue on Github to suggest the replacement of the term. (Also another, to suggest the Javascript chart be updated to account for promises; I've somewhat less high hopes of that one, given that the author appears to be a disciple of the Haskell language family and to entertain the prejudices so commonly associated therewith, but who knows? It's worth a shot, in any case.)

<comment><USER6> > _I think by "self-assessment" is meant something more like "self-regard", > the whole being taken to mean that PHP programmers have a relatively high > opinion of themselves, which is not justified by the code they generate._

I read it this way too, and this is what I'm disagreing with. I've seen far more programmers for other languages having a high opinion of themselves than PHP guys, which are more workman-like.

The worst offender in this regard would be some Javascript guys (and their n-th rediscovery of the computer programming wheel).

</comment></comment></comment><comment><USER13> This isnt even funny.Unless you want to take a cheap shot at PHP and glorify Haskell,the language everybody brags about but almost nobody uses professionally.

</comment><comment><USER14> I'm not a PHP user, nor do I like PHP, but I do know plenty of PHP users that are quite productive with the language.

<comment><USER15> There's no scale on the vertical axis to compare different curves. You can only compare the productivity and the self-assessment within a language.

<comment><USER16> But you can compare derivatives. Which is the stab at PHP.

</comment></comment></comment><comment><USER17> Oh wow lel so funny, 10/10, pease make more PHP jokes, they are so super funny. And you are right, too! Not a single PHP developer was ever productive and shipped a product. None. Never. And especially PHP devs walk around and proclaim "We are the elite! Our language makes coding fun and hip!!!!" all the time.

</rant>

<comment><USER18> Actually, right in these comments PHP programmers proclaim how productive they are, how PHP powers half the web and how Haskellers haven't done anything practical.

So it seems your sarcastic rant completely misses the mark.

Disclaimer: not a haskell, nor a php programmer.

<comment><USER19> Which language do you use this days?

<comment><USER18> I've discovered elixir several weeks ago and fell in love. Dynamic functional language with great concurrency support and ruby syntax. Wow. Lots of other goodies, too.

Started a complete rewrite of my data analysis project in elixir and it is going great. I am nearly sure that my chemistry with elixir will stick for a long time.

Due to practical reasons javascript is my primary choice for small, short-term projects. As an example, meteor is really interesting. I consider JS to be a safe-ish investment of my time due to its momentum and huge ecosystem. It doesn't make me happy, though.

So, to answer your question my languages of choice are JS + Elixir.

Before elixir I've tried python, ruby, go, r, javascript, haskell and c. Btw, I consider programming in haskell to be a good learning exercise for understanding advanced CS concepts.

</comment></comment></comment></comment><comment><USER20> I wish the article didn't include the php learning curve. Then this thread could have been an interesting read.

</comment><comment><USER21> It seems that it interchanges "productive" with "writing clean code".

PHP is ugly but can be productive. Haskell is beautiful, but well, I know a lot of people encharmed by it, but no-one productive (i.e. delivering products quickly; it's not the same as solving pure, mathematical problems).

<comment><USER22> Do you know alot of Haskell programmers? Because I'm enjoying my typesafe SQL queries, typesafe intra-application linking, typesafe templating, etc. Haskell is capable of far more than "pure, mathematical problems"—indeed, typed IO is a premier feature of the language.

edit: sorry, this was pretty defensive; I shouldn't have written this comment so hastily.

<comment><USER23> You know, C#/F# programmers are enjoying most of the above in spades, and the libraries are fully vetted and mature to boot; could say the same for Scala to some degree.

Can we say the same for Haskell? Let's take a sample: you say, "I'm enjoying my typesafe SQL queries"

There are 2 Haskell query DSLs worth talking about (read: that support joins): Esqueleto and OpalEye. The latter is fresh off the presses and not yet ready for prime time (see the "ideal sql" samples interspersed with the performance killing actual sql); the former at first blush looks decent, but then you realize, whoops, no string based SQL interface (for those ultra complex db- specific queries business requirements demand, but cannot be expressed in the dsl), and no Oracle or SQL Server support -- yikes, bye bye enterprise; in fact both libraries officially support _one single_ database, Postgres.

Also, given Haskell's lack of a module system (hello global namespace conflicts), the choice of operators is somewhat, well, hideous (Haskell itself remains beautiful though, at least in terms of concision).

Not sure how things are on the web framework front, but given the claims of achieving C-like performance, that Yesod and Snap basically face plant in a popular benchmark[1], one wonders where reality and the ideal world Haskellers seem to live in, meet.

[1] [http://www.techempower.com/benchmarks/#section=data-r9&hw=pe...](http://www.techempower.com/benchmarks/#section=data-r9&hw=peak&test=db)

<comment><USER22> Hi virtualwhys, won't have time to respond to everything but wanted to mention Esqueleto supports MySQL/Postgres/SQLite, they're mentioned in the testing section of their Hackage page [https://hackage.haskell.org/package/esqueleto](https://hackage.haskell.org/package/esqueleto).

Re: the techempower benchmarks, my understanding is that they used an old version of GHC which didn't include the MulticoreIO manager or something like that. It's since been fixed [1] but it's been awhile since a TechEmpower benchmark (iirc round 10 was pushed back but they're now working on it again [2]).

[1] [https://github.com/TechEmpower/FrameworkBenchmarks/commit/9e...](https://github.com/TechEmpower/FrameworkBenchmarks/commit/9e8701c4311e04c92b8379819c65457697f07b7d)

[2] [https://github.com/TechEmpower/FrameworkBenchmarks/issues/12...](https://github.com/TechEmpower/FrameworkBenchmarks/issues/1273)

</comment></comment></comment></comment><comment><USER24> It seems like a lot of people love to hate PHP, and I am not the biggest fan of PHP myself but some of the arguments are a bit off. My current consultancy focuses on coming into companies in a last ditch effort to fix problems with startups, generally after they have failed some sort of technical due diligence when being sold. I get a fairly even mix of most languages (Ruby, PHP, Python, .Net, Java) and they all have problems in the wrong hands.

In 2014 (so very recently, this year), I was brought into a company that was just about to be sold and failed a technical due diligence. One of the red flags was that most of the engineers were in the process of leaving having "accomplished a dream and sold their amazing system to a large organization". They left for really big, well known companies rather than finish the technical due diligence and take an aqui-hire position.

A look at the code showed why. While these were all honestly rather Senior level engineers, they had written some of the most horrible Ruby, JRuby, and Clojure code I have seen in my career. Often it seems they decided well known and good frameworks were just "not good enough" so they decided to write and not maintain their own. Their list of technical sins was quite long but the last I will mention is that they never could decide, from day to day, what the right architecture was, so they just changed it, over and over, on a whim.

The point of this story is, languages don't write poor code, engineers do. I know that people will say, "But PHP has an ecosystem of Junior developers just picking it up and pushing out bad code and never really learning." This may be true, but it's actually just as true with Ruby, Python, .Net, and Java. Those languages, Ruby and Python in particular, are just much better at the PR game of making themselves look "more mature" than PHP is.

</comment><comment><USER23> tl;dr humerous Haskeller takes steaming dump, rejoices; one may think that one is not being productive, and yet one's actual productivity sky rockets, whereas in other languages (exception, LISP) one's actual productivity is less than one feels, especially in the case of PHP where delusion apparently reigns.

Seems to be a riff on the text editor comic graph where emacs morphs into dragon-eating-its-tail recursion as one approaches unreachable mastery [1]

[1] [http://ergoemacs.org/emacs/emacs_fun.html](http://ergoemacs.org/emacs/emacs_fun.html)

</comment><comment><USER25> Say what you want but PHP is one of the most Rambo-bad-ass languages I've ever used. You toss everything to the wind if you want and you will still get a working product.

Few languages have that sheer "Survive" feel to it. For that alone I think PHP should be celebrated. Note: I'm not a PHP developer.

<comment><USER26> I think that most of the things people hate about PHP are the things that make it work. It doesn't force you into a particular paradigm, and it all but encourages mixing PHP and HTML together into one horrifying but incredibly convenient stew. It doesn't force you to write clean, elegant or secure code (you can, but it doesn't hold your hand in that regard.) A lot of it is still just wrappers around c. You're not chained to a package manager (although you can use one if you want) or a framework (although you can pick one of many.)

And yet, for almost everything people want to do when they want to put something on the web, it's not only perfectly adequate, but in some ways more efficient than other languages. Most of the web is still CRUD anyway. Take stuff from a database, iterate it, insert it into html, serve html. Or maybe do all that, and serve json instead. This is still far, far easier to do in PHP than it is other languages.

That said, as a professional PHP developer, there is still plenty about the language that drives me up the wall. I think anyone who works with it and is serious will admit there are issues with the language. But no one can say it isn't battle-tested, or that it doesn't make it easy to get something up and out onto the web.

</comment></comment><comment><USER27> Decorators are more than simple syntactic sugar in Python ;)

It seems overly critical, but still funny (the Haskell one is probably the most spot on)

And after all, Facebook uses PHP and MySql

<comment><USER28> > Facebook uses PHP

This is the common rebuttal of PHP jokes - but pointing to a sole outlier is rarely a solid defense. Especially when they have created Hack[1] and HHVM[2]. So it's not entirely accurate to say they "use PHP."

[1] [https://en.wikipedia.org/wiki/Hack_(programming_language)](https://en.wikipedia.org/wiki/Hack_\(programming_language\))

[2] [https://en.wikipedia.org/wiki/HipHop_Virtual_Machine](https://en.wikipedia.org/wiki/HipHop_Virtual_Machine)

<comment><USER6> > _This is the common rebuttal of PHP jokes - but pointing to a sole outlier > is rarely a solid defense._

Sole outlier? Hardly. Half of the web is powered by PHP, including tons of websites with huge traffic and usage.

> _Especially when they have created Hack[1] and HHVM[2]. So it 's not > entirely accurate to say they "use PHP."_

Hack and HHVM do not show some inherent PHP issue that something like Ruby or Python would not have.

Hack is mostly an attempt to add type checking/hinting to PHP. The lack of type checking would be the same if they used Python or Ruby or Node+JS or whatever.

And HHVM is an attempt at a speedup, to work at Facebook like economies of scale. Considering that plain PHP is on par speedwise with Ruby and Python, that's again not something that would be saved using those other languages. Which is why Google tried to do Unladded Swallow (for Python), Dropbox does their own thing, RoR companies invest hard on speeding up Ruby/Rails, etc.

TL;DR: Hack and HHVM may be proofs of some lack in PHP for Facebook uses, but are not proofs of PHP lacking things compared to other similar languages like Python and Ruby.

<comment><USER29> _> Half of the web is powered by PHP, including tons of websites with huge traffic and usage._

What powers the web: web servers or web sites/applications? If it's web servers then your claim that half of the web is powered by PHP is false because I'm—and I'm going to be honest here—yet to see/use a web server written in PHP.

<comment><USER6> Obviously web sites/applications.

Web servers would just server static sets of pages without some means to run dynamic code.

<comment><USER29> _> Web servers would just server static sets of pages without some means to run dynamic code._

Web applications respond to requests. That's all they do. Web servers parse those requests and deliver responses appropriately. You're reducing the role of all intermediaries (DNS servers, caches, etc) and unfairly praising the web application. The web server serves both non-changing static files and the generated documents.

</comment></comment></comment></comment></comment></comment><comment><USER30> I am working on a commercial SAAS application written in Haskell. I have been programming computers since 1980, with solid experience in at least a couple dozen programming languages. I chose Haskell for this project because of its programmer productivity and runtime performance. I have not been disappointed. I am always amazed at how little code it takes to get things done. The Achilles Heel of too many languages and their implementations is concurrency support. Haskell had that problem licked ten years ago. Once my code compiles, I know it has few remaining bugs. It runs fast and there are enough good third party libraries to meet my needs.

So what's not to like about Haskell? It has a brutal learning curve. Not so much because it is hard, but because it is different.

</comment><comment><USER31> Presumably inspired by [http://www.terminally- incoherent.com/blog/2006/08/01/text-ed...](http://www.terminally- incoherent.com/blog/2006/08/01/text-editor-learning-curves/)

</comment><comment><USER32> Re: Haskell monads

If something hurts my brain, I don't want to do it; I don't care about the long-term benefits. Most humans feel the same way and that's why Haskell will never become mainstream.

<comment><USER33> ...and that's the difference between an amateur and a professional.

<comment><USER32> No, it's not. Software developers are human. Being a professional does not always override human nature. Statistically, most "professional" software developers will not want to adopt a language with a high cognitive load.

<comment><USER33> Doing what you need to do, and not what you want to do, is the heart of professionalism.

</comment></comment></comment></comment><comment><USER34> Poor PHP. It just keeps getting dumped on.

<comment><USER35> And rightly so. Frankly, I think the only reason PHP keeps floating on is the inertia it has. All the investment in tools, existing codebase and developer experience are what keep it going, not language merits.

And yes, this means, that whatever you invest in, be ready to abandon it and move forward, preferrably sooner rather than later. After all, langauges are _nothing_ but tools. Don't take them personally.

<comment><USER6> > _And rightly so. Frankly, I think the only reason PHP keeps floating on is > the inertia it has. All the investment in tools, existing codebase and > developer experience are what keep it going, not language merits._

Considering the alternatives PHP is not bad at all. It's not like Python or Ruby are some pinnacle of language design.

It's main BS is a polluted default namespace, incosistent function naming, and a few semantic inconsistencies. It's not like any other language doesn't have its share of BS.

Plus what it lacks (a proper AST etc) it's getting. It has been improving ever since 5.0, and fast. Including getting a vast speed increase with 7 that will leave Python and co in the dust.

</comment></comment></comment><comment><USER36> The stigma around Haskell is quite unfortunate. Most complaints that I've heard leveled at Haskell are variations of "it's too academic". Given that those complaints usually come up when one is tackling abstractions like Functors, Applicatives and Monads, it would seem that the true sentiment is that "Haskell is too abstract".

Interestingly, I have yet to hear someone complain about abstractions like Collection, Stack, Dictionary, or looking at the ever popular OOP abstractions Class and Method.

Why is it that OOP is widely accepted[1], and yet Haskell-like FP has yet to take off? Well, I think I have an explanation for why this is.

The abstractions commonly used in Haskell are perhaps a bit "more abstract" than those seen in most OOP programming. Most people can intuit the value of collections/classes/etc., and those that can't are pushed in the right direction by the majority of the industry.

Compare the situation of popular imperative languages to that of Haskell: the utility of the former is easily acknowledged and has the support of the industry, whereas the latter is harder to fully appreciate without investing some time and has the industry actively suggesting that the abstractions are useless.

Haskell-like FP is, unfortunately, where OOP probably was when it was still "the new thing". "Why would anyone use this? Classes, interfaces, methods, messages... Too academic!"

And then OOP picked up momentum as people discovered the utility of encapsulated state, programming to an interface (instead of an implementation), the ability to isolate the System Under Test via mock objects... And then those that tasted the benefits worked really, really hard to shift the mindshare of the industry to accept these abstractions as "good things".

I hope Haskell et al will get there some day. The thing is, ideas like Monads are incredibly useful - just as useful as any of the more popular abstractions. They're just one more tool in the toolbox - if you don't know them, you might be missing out.

In an attempt to dispel the myth that abstractions common in Haskell are academic and useless for professional programming, I would ask one thing of you: please, please, please watch Tom Stuart's talk "Refactoring Ruby with Monads" (given at Barcelona Ruby Conference 2014): [https://www.youtube.com/watch?v=J1jYlPtkrqQ](https://www.youtube.com/watch?v=J1jYlPtkrqQ)

The abstractions are useful. Yes, just like any of the abstractions that you may have already mastered, they do take time to learn. It's an investment. I know the payoff might not be immediately obvious, but I promise that it's right around the corner. There's a practical, pragmatic reason Haskell is being used to great effect at places like ThoughtBot, Facebook, Skedge.me, and more.

[1] This is almost a given now: recruiters have often quizzed along the lines of "why is OOP a superior paradigm?"

</comment><comment><USER37> Ugh, they left off Perl.

</comment><comment><USER38> What about ruby ?

<comment><USER39> I think the fact that Ruby didn't even make the list tells a lot about how far it has fallen in terms of mindshare. I have nothing against Ruby, its people or its ecosystem, but it's beginning to seem like a bit of a flash in the pan.

<comment><USER25> 10 years+ totally a flash right?

<comment><USER39> When you have more than a few years' experience yes, something like this seems like a flash in the pan.

[http://www.tiobe.com/index.php/content/paperinfo/tpci/Ruby.h...](http://www.tiobe.com/index.php/content/paperinfo/tpci/Ruby.html)

Peaked in 2009, now down to a third of that popularity. Other measurements might give you different numbers, but the same trend. As I said, I have nothing against Ruby, but it just doesn't seem to be holding its position.

</comment></comment></comment></comment><comment><USER40> This is a lot of debate for something that's intended to be funny.

If all the lines were accurate, would it have been funny at all?

</comment><comment><USER41> Add ruby and c#

<comment><USER42> How about C# vs F#? Both have great support. You'd think if people were 2x-3x more productive in a functional language, you'd get a lot of developers moving from C# to F# because both have excellent support from Microsoft.

<comment><USER2> "support from Microsoft"

I know a few Microsoft employees who got in trouble for using F# internally.

<comment><USER19> Those don't represent the rest.

</comment></comment></comment></comment><comment><USER43> Can you share what did you use to make those beautiful graphs ? I really like the fuzzy axis lines.

<comment><USER44> The author is using the Matplotlib Python library. [1]

Similar style charts to that used by Randall Munroe in XKCD.

See also this D3 style for producing similar charts by Dan Foreman-Mackey. [2]

[1] [http://matplotlib.org/xkcd/examples/showcase/xkcd.html](http://matplotlib.org/xkcd/examples/showcase/xkcd.html)

[2] [http://dan.iel.fm/xkcd/](http://dan.iel.fm/xkcd/)

</comment></comment><comment><USER14> Would learning Monads really come before learning Category Theory in Haskell?

<comment><USER45> Monads are a construct from category theory, and one with a particularly significant use in idiomatic Haskell, so I'd expect learning Monads as used in Haskell to generally precede a broad understanding of category theory for most Haskell programmers.

<comment><USER14> Thanks, good to know. I should clarify that I was genuinely asking a question and not making a statement.

</comment></comment></comment><comment><USER46> For elmers out there, what will a graph of Elm look like?

<comment><USER14> Probably similar to Haskell, but with less productivity :p

<comment><USER19> Because?

<comment><USER14> Because it's a fun language to play around with. I guess it depends on your definition of productivity.

<comment><USER19> Don't follow you and your logic at all nor understand how you came with it.

</comment></comment></comment></comment></comment><comment><USER47> Does anyone know how the graphs were drawn?

<comment><USER48> The graphs have been generated using Python's matplotlib[1] 2D plotting library[2].

[1] [https://github.com/Dobiasd/articles/blob/master/programming_...](https://github.com/Dobiasd/articles/blob/master/programming_language_learning_curves/generate.py)

[2] [http://matplotlib.org/index.html](http://matplotlib.org/index.html)

<comment><USER49> I love to see PHP vs Haskell debate about productivity while actual work is done in Python.

</comment></comment></comment><comment><USER50> Someone needs to label their axis better

</comment><comment><USER51> Pretty accurate, I'd say.

</comment><comment><USER52> Bad programmers are bad no matter the language... Why you don't waste your time writing an interesting post of your preferred language instead of make jokes about another ones? Maybe the answer is that you can't even write a line of quality code... you people the Nelson Muntz of code..</comment>


TypeScript Modules - <AUTHOR> http://www.johnpapa.net/typescriptpost/

<comment><USER2> I find TypeScript to be an exciting new take on the language. I look forward to using it more this year. Thanks for your post and your PluralSight course</comment>


The case for simple passwords - <AUTHOR> http://glassbalcony.tumblr.com/post/88793017790/the-case-for-simple-passwords

<comment><USER2> >Why do we keep enforcing non-memorable passwords, instead of complex but memorable words?

Because most users' idea of "complex but memorable" is their mothers' maiden name or their favorite album or the city they were born in, maybe with some of the letters replaced with numbers or "123" at the end. Most of us have seen the "correct horse battery staple" XKCD[0] which suggests that a simple passphrase is stronger than a complex password. But how well do you trust yourself to remember a hundred different passphrases as opposed to a hundred different passwords? You won't... you'll probably just end up using something short and easy to remember and sharing the same few key phrases among multiple accounts and then you're basically where you started.

> I also wonder if brute force attacks can't be effectively limited by > imposing a rate limit on login attempts or requiring an email verification > every once in a while

Which is fine, unless the password reset questions are guessable, or your email is vulnerable, or thanks to a SQL injection issue the site's entire database has been dumped onto Pastebin. Bruteforcing the site and bruteforcing the hashes are two different issues. That said, I don't know the math well enough to know for certain which solution (password vs passphrase) is really the better one.

[0] [http://xkcd.com/936/](http://xkcd.com/936/)

</comment><comment><USER3> Yea, some sites don't allow space. Or some disallow other special characters while blocking others. Or limit to 16 characters (outlook.com)</comment>


Bit Twiddling Hacks - <AUTHOR> http://www.graphics.stanford.edu/~seander/bithacks.html

<comment><USER2> This was posted a number of times before:

<http://news.ycombinator.com/item?id=2570269>

<http://news.ycombinator.com/item?id=513935>

<http://news.ycombinator.com/item?id=86419>

And also:

<http://news.ycombinator.com/item?id=1811104>

</comment><comment><USER3> These are cool, but how much is automatically done for you by the compiler? For example, if I changed all of my calls to min(x,y) with

r = y + ((x - y) & ((x - y) >> (sizeof(int) * CHAR_BIT - 1))); // min(x, y)

my code would quickly become unreadable. I could define a macro, but those are supposedly evil[1].

[1] [http://www.parashift.com/c++-faq-lite/inline- functions.html#...](http://www.parashift.com/c++-faq-lite/inline- functions.html#faq-9.5)

<comment><USER4> Many of the very simple algorithms are done by a good compiler, more complex ones generally are not. It is pretty easy to turn these into clean, generalized functions using templates in C++ and std::numeric_limits. I have a substantial library of generalized algorithms constructed from bit-twiddling primitives that does not use any macros.

The value of these examples is that if you understand the underlying mechanisms behind them you can use those building blocks to construct even more complex (and extremely fast) algorithms than demonstrated at the link. Complex, high-level algorithms can be implemented using these bit hacks once you wrap your head around what they are actually doing. The caveat is that the code will be opaque for programmers that are not fluent in bit-hacking.

For most applications you won't see much performance benefit because these are micro-optimizations. If you have a small kernel that is being executed a hundred thousand or million times per second then algorithms constructed this way can be a substantial performance optimization (easily integer factor speedup, I frequently see 10x for components).

Algorithms built on bit-twiddling primitives tend to have two properties that make them particularly efficient on modern processors. First, they make very good use of superscalar CPUs, putting the parallel ALUs to work. Second, they often take branching algorithms (e.g. small tight loops, ?: operator, if statements) and convert them into branchless algorithms. If you are doing performance and latency sensitive code, this method of building algorithms is worth learning. For everyone else, it is a neat bit of computer science arcana that really delves into the nature of integers.

</comment></comment><comment><USER5> If you enjoyed this, you'll also probably like Hacker's Delight: <http://www.hackersdelight.org/>

</comment><comment><USER6> I like Morton Numbers--they're a great example of the notion that dimensionality is an interpretation, and you can compress higher dimensions down to 1 while still retaining a 1-to-1 correspondence. However, good luck with modifying the bit twiddling algorithms shown here when you want to deal with Big Numbers that overflow C/C++'s built-in types. Here's a slow (I haven't measured how slow) Python version that's insensitive to how big the number is:

        def tomorton(x,y):
          x = bin(x)[2:]
          lx = len(x)
          y = bin(y)[2:]
          ly = len(y)
          L = max(lx, ly)
          m = 0
          for j in xrange(1, L+1):
            # note: ith bit of x requires x[lx - i] since our bin numbers are big endian
            xi = int(x[lx-j]) if j-1 < lx else 0
            yi = int(y[ly-j]) if j-1 < ly else 0
            m += 2**(2*j)*xi + 2**(2*j+1)*yi
          return m/4

<comment><USER4> There is a straightforward way to extend bit interleaving to bit strings of arbitrary size using bit-twiddling. The output of the magic constants just have to be shifted in a regular pattern (which varies as a function of dimensionality) so that each word in the array has its bits correctly ordered.

The magic constants used in the bit-twiddling example also have a very regular derivation. Designing an algorithm that computes the correct constants for Morton Numbers of arbitrary dimensionality is pretty simple.

There is a neat generalization of this algorithm that extends it to irregular bit interleaving patterns at the cost of requiring a few more magic constants (also derivable). I once wrote a compact engine that used algorithmically generated transform constants to produce arbitrary bit interleaving patterns in an arbitrary number of dimensions via these bit-twiddling algorithms.

<comment><USER6> Hey, you finally made the leap to HN! Did you independently discover a lot of these things yourself or did you come across parts in books/papers? For me the canonical example of deriving magic numbers is with the fast inverse square root trick (my favorite paper on it is <http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf> ) but I haven't seen many other instances... I haven't gone nearly far enough yet but I like getting pointed suggestions.

There were some recent submissions here about related topics like space- filling curves and secret sharing that I've looked at before. When I started looking into abstract algebra and came across finite fields I sort of laughed at the Wikipedia page mentioning right at the beginning "Finite fields are important in number theory, algebraic geometry, Galois theory, cryptography, coding theory and Quantum error correction" with each topic being linked. It's a fun way to procrastinate.

If your engine isn't part of some secret sauce I think it would be neat to study it. Unless you know of an already existing open source equivalent that's not hidden away in the corners of something like GCC?

<comment><USER4> I found most of them in code and on the 'net but came up with a couple myself. When I started looking at bit interleaving some years back, I found a few examples for 2- and 3-dimensions but not much explanation. If you step through the algorithm and label every bit to watch how they move, it starts to become obvious what is going on. This was how I learned. The constants mask individual bits so that the sum of the shifts applied to a bit equals the total shift. If a bit needs to be shifted 5 bits to its final position, the mask is not applied to that bit for the ">>4" and ">>1" step. Consequently, constants and shifts for a particular transform do not have to be based on powers of two, just numbers where the sum of some subset of shifts matches every shift in the integer you are transforming.

Once you know that, you can generate any distribution you need. However, Morton numbers take advantage of a property of their bit distributions where intermediate steps never corrupt a bit that is not going to be masked off anyway. This is not true for some other bit interleaving patterns. Extending it to arbitrary patterns requires two masking operations with another magic constant at each step which protects bits that would otherwise be destroyed in the simple Morton algorithm.

Nothing like the transform engine I wrote is open source to the best of my knowledge. There is no reason I could not open source it, I just haven't. It is pretty efficient in that it can do a number of reductions and simplifications to the minimum number of steps and constants required to produce an n-dimensional interleaved result. For irregular patterns, you end up with quite a few no-op steps that can be eliminated; for regular patterns you can reuse steps, saving memory. I'll probably write it up and put it on the web at some point.

</comment></comment></comment></comment><comment><USER7> Premature optimization heaven!!

But seriously, I'm going to crawl through this and see if there is anything that can speed up some drawing code I have. Very nice!

</comment><comment><USER8> These are pretty neat. I use a few of them relatively often at work, but if I ever saw

c = ((((c - 0x3f800000) >> r) + 0x3f800000) >> 23) - 127;

in production code I would be sad.

<comment><USER9> If properly commented, why would that make you sad?

I think this story is relevant: [http://www.folklore.org/StoryView.py?project=Macintosh&s...](http://www.folklore.org/StoryView.py?project=Macintosh&story=Saving_Lives.txt)

Think of all of the time software wastes in people's lives by being bloated and inefficient.

In Java, for example, the default HashMap implementation [0] uses a while loop to compute the capacity of the array it will use as storage. Using the next highest power of two algorithm in the page listed is faster than this loop. Imagine if every JVM was microseconds faster every time a HashMap was allocated or resized. On one server, computer, or phone it's meaningless. On hundreds of millions of phones phones, PCs, and servers that adds up to meaningful amounts of time and energy.

[0] <http://www.docjar.com/html/api/java/util/HashMap.java.html>

</comment></comment><comment><USER10> Search for Ratko Tomic bits on google. He was doing these optimizations in the late 80s and early 90s.

How I miss the RIME/RelayNet C language forums...</comment>


Is Growth Hacking just a new fad? - <AUTHOR>

My take on it: Growth hacking is building something users love and let the world know about it - it has been around for ever. <comment><USER2> In disruptive industries people wear many different hats, and it is common to simply ask the 'web design guy' to do a bit of growth hacking for the company. It doesn't mean they now become a full time growth hacker; it just means that visitors need to convert somehow, and some design skills can achieve that. What annoys me is when an employee is called a growth hacker on the company page or wears this title like a badge of honour. All employees can do a bit of GH on the side, but it should never be a full time position IMHO.</comment>


Fingerprints and Passwords: A Guide for Non-Security Experts - <AUTHOR> http://xato.net/authentication/fingerprints-and-passwords/ <comment><USER2> Firstly I see all biometrics as a _username_ not a password.

I assert I am lifeisstillgood - and I enter my shared secret so that pg can make a reasonable assumption that the person he originally told the secret too has not shared it and therefore is at the other end if the transaction.

The problem with fingerprint recognition is it is a zero-factor authentication. What we have here is a very long username with say 44 bits of entropy(#). No matter how long that username, it's not a secret. I wonder around leaving it everywhere - just like "lifeisstillgood".

Without a shared secret, a username is not a sufficient security device - it's just what I am asserting - zero factor authentication is a problem.

(#) now this is an interesting issue. Fingerprints have been assumed to be 100% unique amoung humans. But with DNA fingerprinting came a confidence level, and now forensic scientists are resisting assigning confidence levels to fingerprints mostly I think for the apocalypse of having to review 30 years of convictions then made unsafe.

</comment><comment><USER3> I'm glad someone is talking about this. If you set a passcode, iOS encrypts your data with a key derived, in part, from your passcode and a per-device salt; Apple claims that even with access to the device, a nine digit passcode would take 2.5 years to brute force. [1]

A fingerprint is only useful for authentication, not key derivation, which makes it effectively useless in protecting your secrets from a determined attacker. As it stands today, my data is encrypted with a key that isn't stored on my device. Unless Apple has developed some kind of fingerprint-based key derivation algorithm, that can't be the case for the hapless user who replaces his passcode with a fingerprint scan.

I fear that the innovation announced today is going to make people and their data less safe, not more.

[1]: [http://images.apple.com/iphone/business/docs/iOS_Security_Oc...](http://images.apple.com/iphone/business/docs/iOS_Security_Oct12.pdf)

<comment><AUTHOR> "A fingerprint is only useful for authentication, not key derivation"

exactly

</comment></comment><comment><USER4> I would make the following points.

1) Not accounting for salting and variations of hashes, one can have at most 19 resets of core biometric assuming the normal number of fingers and toes.

2) Biometric fingerprinting merely proves that you have the digit. No proof if said digit is attached to human (see Hollywood blockbuster!).

3) Susceptibility to coercion. It's much harder to refuse to swipe your finger (willingly or otherwise) at the border than to refuse to give up a password.

<comment><USER5> Why would you need to reset biometrics (point 1)?

<comment><USER4> The equivalent of losing your password.

</comment></comment></comment><comment><USER6> >Third party must have access to raw data

Is there a reason that fingerprints can't be stored as hashes instead of the raw data? It would presumably involve re-enrolling if the fingerprint comparison algorithm gets changed, but how often does that happen?

<comment><AUTHOR> The problem is that fingerprint matching isn't exact, there are thresholds you must allow for so there is no exact code to match to. Although some implementations may make this possible, it is an issue that all biometric methods must address.

It's like allowing a password that is close enough, in that case you would need the real password as well, not just a hash.

<comment><USER7> Sure, though there are simhash implementations, where you can compute a hash that itself can be used to compute a hamming distance between two inputs.

(This is used a fair amount in search, to cluster similar documents.)</comment></comment></comment>