The centenary of the 20th century's worst catastrophe, the Spanish flu - <AUTHOR> https://www.economist.com/science-and-technology/2018/09/29/the-centenary-of-the-20th-centurys-worst-catastrophe <comment><USER2> I wonder if a discussion around Spanish Flu should also include the 1956-58 Asian Flu as well as the 1968-69 Hong Kong Flu?

Would the much more open travel of today, compared to the far more closed international travel of yesterday have had a significant impact on virality and mortality of those two more recent pandemics?

I've sat in on a meeting in the post Tamiflu/bird flu scare environment that provided a macro view of the challenges facing a small country like New Zealand.

My thoughts are that a financial hedge against a pandemic might include:

Going "long" tele-presence such as Zoom, Skype, etc as well as streaming entertainment.

Going "short" passenger airlines, lifestyle retail, and shopping mall REITs.

As far as global/macro risks go, pandemic is top of mind for me.

I perceive pandemic as a lower risk and likelihood than another global financial shock.

But I view them both as ultimately inevitable.

It's just a question of severity for both.

But Imthinkmthe difference is that another GFC would not precipitate a pandemic.

But a pandemic could precipitate a GFC.

<comment><USER3> > But a pandemic could precipitate a GFC.

I dont see why. Some industries would suffer, but others would prosper. It would not be a whole-encompassing GFC like when the banks derail.

<comment><USER4> A pandemic with casualty rates comparable to the Spanish Flu would mean a rapid worldwide GDP drop comparable to a GFC simply because even if the GDP- per-capita would stay the same, there would be less people, so a drop in both production and demand. It would also mean an immediate jump in household default rates as a noticeable portion of families lose their main earners. Both of these factors are likely to cause banks to derail as well.

</comment></comment></comment><comment><USER5> [http://archive.is/7aEug](http://archive.is/7aEug)

[https://outline.com/3Yndgb](https://outline.com/3Yndgb)

<comment><USER6> Hero

</comment></comment><comment><USER7> Extra credits has a series about this pandemic: [https://www.youtube.com/watch?v=XQ9WX4qVxEo](https://www.youtube.com/watch?v=XQ9WX4qVxEo)

</comment><comment><USER8> The most rollicking fun song about the Flupandemic ever made was by the Flying Fish Sailors: [https://www.youtube.com/watch?v=JV938U4Y96w](https://www.youtube.com/watch?v=JV938U4Y96w) Not to be missed, if you're interested in the topic and don't mind lighthearted songs about widespread death.

</comment><comment><USER9> I think it was "Adam Ruins Everything" that pointed out that that flu basically killed everyone it could i.e. except for those that were resistant, it killed until it ran out of people to infect. Scary.

</comment><comment><USER10> _We Heard the Bells: The Influenza of 1918_ , a documentary from the Health Department

[https://archive.org/details/gov.hhs.cms.006719](https://archive.org/details/gov.hhs.cms.006719)

</comment><comment><USER11> Buy NIOSH-approved N95 particulate respirator masks. They're like $2/per on Amazon.

Make sure they fit you, and your family. Get different types / sizes.

You won't be able to buy them -- anywhere -- once media organizations start reporting on an outbreak.

Don't tell anyone you have them.

Ignore people who don't think this is worth worrying about. People are stupid.

<comment><USER12> I wouldn't trust my life to a respirator mask I bought from Amazon. How would I know I didn't get a fake?

<comment><USER13> It has NIOSH approval printed right on it. Or, at least, written in crayon.</comment></comment></comment>


The Early History of Smalltalk - <AUTHOR> http://worrydream.com/EarlyHistoryOfSmalltalk/ <comment><USER2> Previous discussion:

[https://news.ycombinator.com/item?id=17913668](https://news.ycombinator.com/item?id=17913668)

[https://news.ycombinator.com/item?id=7926141](https://news.ycombinator.com/item?id=7926141)

[https://news.ycombinator.com/item?id=9907556](https://news.ycombinator.com/item?id=9907556)</comment>


New Facebook SDK for PHP - <AUTHOR> https://github.com/facebook/facebook-php-sdk-v4

<comment><AUTHOR> I know PHP isn't a favorite around here, but it still accounts for (what was recently) a majority of all web apps that use Facebook. We built a more modern implementation, using newer language features, and have big plans for it.</comment>


Thank you for giving me the opportunity to explain this to you - <AUTHOR> http://diveintomark.org/archives/2009/10/19/the-point <comment><USER2> I was curious if the printed book included mention of the GNU license so I "searched inside" on Amazon.

These two paragraphs are pretty odd sitting next to each other: <http://timfreeman.org/copyright_dip.png>

<comment><USER3> I complained about that, but it was too late to do anything about it. (You don't usually even see those frontmatter pages during the book- writing/editing/proofing process.)

<comment><USER4> Why complain? It's a little funny: the latter paragraph ends "... without the prior written permission of the copyright owner and the publisher", which, apparently, the former paragraph grants. No?

</comment></comment></comment><comment><USER5> _I don't know where that leaves you as a business._

I suspect this leaves Apress at the "Require all further authors to contractually promise us, in writing, that they are assigning Apress the _exclusive_ right to publish/distribute the content and have not written any legal landmines which contradict this clause into the sections we routinely don't read".

<comment><USER6> That _is_ the standard Apress contract now. Mark made his initial contract with Apress quite a long time ago when it was a far smaller company where special deals could be made.

<comment><USER7> wrong, i still make special deals with apress all the time :D

<comment><USER6> Haha, I'm sure! I suspect knowing the head honchos helps, though I miss Gary.

</comment></comment></comment></comment><comment><USER8> So do Apress pay royalties to Mark currently, on a per unit sold basis? If these new people can publish under the GFDL then presumably Apress can (are?) as well.

<comment><USER9> I assume Apress is constrained by their contract with Mark.

<comment><USER10> It's an interesting question though; such a contract must specifically _remove_ any rights the GPLD gives Apress.

Otherwise it's hard to see how they couldn't wiggle out of paying royalties?

<comment><USER9> >such a contract must specifically remove any rights the GPLD gives Apress

I assume the contract commits Apress to pay royalties to Mark based on their sales of the book's print edition. If they contractually agreed to pay royalties, they would be in breach of contract regardless of the licence under which Mark released his copyrighted content.

Notwithstanding the licence, Apress must have decided that they could make enough money on sales to justify the money they're paying to Mark.

Look at it this way: he might have _released_ the book under a free document licence that another party could exploit, but he arguably wouldn't have _written_ the book if not for his contract with Apress. So if they didn't agree to pay royalties, there would be no book to sell.

</comment></comment></comment></comment><comment><USER11> You know, I love this.

Simply because I like when I purchase classics (not covered by copyright any longer) that I have the ability to choose the book based on criteria I cannot usually factor in.

I can opt for quality paper, for a nice and well-spaced font, for good- binding, for a nicer jacket, for a specific translation.

I like that there is the potential that I could purchase this book and be able to choose such things, that I could say "I'll pay this guy over here a little more as he's invested in the quality of the medium.".

I was very happy with the contents of Coders at Work for example, but disappointed with the paper selection and choice of font. I would have happily paid more to have a nicer package, so I love authors who would permit multiple companies to do this.

<comment><USER12> Just to be clear, translations are themselves protected by copyright. So, for example, if you want to read the Edith Grossman translation of Don Quixote, first published in 2003, you do not have the freedom to select from a wide variety of editions, as described in the parent comment.

</comment></comment><comment><USER13> This is what free software / free licenses needs, people who parade and exemplify it rather than compare it to non-free licenses or even hate on and fight against non-free software, by force.

<comment><USER14> I don't entirely understand his explanation though. All I understand is that Mark approves of what happened. I do not understand why it is a good thing and why he wants the world to work like this. He didn't explain that.

The whole logic of what and how you are allowed to charge for in the free software/content world seems completely arbitrary to me, even though I have read so much about it.

<comment><USER15> I'm not a lawyer, but my layman's understanding is something like this:

* If you wrote/created/designed it, you get to pick the license. You can give it to some people under the GPL, you can give it to other people under the BSD license, you can negotiate all kinds of crazy licenses for arbitrary recompense you dream up - it's up to you. * If you received a copy of some GPL'd code, freely or in exchange for money, you have the right to give copies to other people - freely, or in exchange for money. If you paid $1000 for some GPL'd code, you're allowed to burn it to a stack of CD-Rs and hand them out on the street corner. If you got it for free off the Internet, you can copy it to your own website and charge people $29.95 per download (whether these actions are _moral_ is another question, but they're legal). * If you give somebody some binary executables whose source was under the GPL, whether you gave them in exchange for money or for free, you must give them the source too, or give them the right to ask for the source later. If they ask for a copy of the source later on, you're only allowed to charge the cost of blank media - regardless of what you charged for the binary executables in the first place.

I think that about covers it. How's that?

<comment><USER14> _If you wrote/created/designed it, you get to pick the license_

I do get that part. But it doesn't help me understand the merits of any particular license.

Thanks for your attempt to explain the GPL to me. I already knew what the GPL says, I just don't see how it achieves its goals of increasing my freedoms.

For instance, I'm not allowed to use the source code of some of the software google has linked to GPL code. Even when I pay for using it (like when I run my code on google's servers), I lose all freedoms related to some of the code covered by the GPL.

If they let me download their code, they would have to let me use the source and sell it as well. But they can simply not let me download it and force me to run the code on their servers exclusively.

So, in this scenario using the GPL means that I can not view or modify the source code of the software I build on. I have to pay for using it, and I have to abide by further arbitrary rules included in their terms of service, taking away even more fundamental freedoms.

<comment><USER16> The GPL increases your freedoms by forcing people to give back, for free, the work they've done on top of GPL'd work they in turn received for free. With software as a service, this breaks down completely, because the derived work is never actually distributed.

The GPLv3 explicitly tries to deal with software as a service, but it's definitely more problematic since it's not as solidly grounded in copyright law as v2 is, it's harder to detect breaches of it, harder to prove breaches, and harder for the people in the justice system to understand it.

<comment><USER17> > _The GPL increases your freedoms by forcing people to give back, for free, > the work they've done on top of GPL'd work they in turn received for free_

No, the GPL forces people to distribute the source code of their own modifications, but that's only on redistribution. That's why with software as a service this doesn't work.

This has to be emphasized, because that's its central strenght.

The _majority_ of all software is made and run in-house, without ever being distributed. And open-source would not be what it is today without contributors that have SaaS as a business model.

> _The GPLv3 explicitly tries to deal with software as a service_

No it doesn't. The GPLv3 is still only a copyright license which only covers redistribution (as GPLv2). It is more problematic because it tries to define what distribution means (to prevent tivoization), and copyright laws have their own definitions, but it still is within normal bounds ... so it remains to be seen if it works, but FSF has got some pretty smart lawyers over there, and they did their homework.

The license that tries to deal with SaaS is AGPL. But that's not a copyright license anymore, and while it is considered to be "open-source", some people think that it shouldn't be, since it places restrictions on the actual usage of the software (like an EULA).

And you'll have a hard time convincing companies that have contributed to open-source to switch to AGPL. Hell will freeze over or a new gap in AGPL will be discovered before that happens. One way AGPL can be "monetized" is with dual-licensing. But that's just dishonest and definitely not free.

</comment></comment></comment></comment></comment></comment><comment><USER18> I did a search on Amazon, but couldn't find the non Apress version of the book in question.

I wonder if Apress forced the book to get delisted.

<comment><USER19> [http://www.amazon.com/Dive-Into-Python-Mark- Pilgrim/dp/14414...](http://www.amazon.com/Dive-Into-Python-Mark- Pilgrim/dp/1441413022)

<comment><USER20> Was anyone curious as to who this 'brazen' publisher was ?

Publisher: CreateSpace <https://www.createspace.com/AboutUs.jsp> "CreateSpace is a DBA of On-Demand Publishing LLC, a subsidiary of Amazon.com Inc."

Seems there are still priorities at Amazon if they suddenly stopped selling it.

</comment></comment></comment><comment><USER21> Kudos to Mark Pilgrim for believing in GPL's philosophy! Love DIP.

<comment><USER22> I sort of read this as more BSDish philosophy. One of the fundamental things he cites is the freedom for others to do something you might not like, which, IMO, is more of a BSD notion.

</comment></comment><comment><USER23> Very cool explanation :-)

I have several little writing projects that I distribute, but I chose the Creative Commons 'no commercial use, no derivatives' license because that was what I felt good with.

People who create stuff have the right to choose the license.

</comment><comment><USER23> I just had an Apress book published, and the contract gives APress the distribution rights - fine with me since they effectively paid me to write the book: their advances allowed me to have a really good time and spend most of my time writing for 4 months. (I enjoy consulting, but writing is even more fun.)

</comment><comment><USER24> Im confused too; in my basic Contract Law class, there's something called Value Received. If I don't pay for something, there is by definition NO CONTRACT. So any words (gpl etc) printed on the thing are just decoration.

<comment><USER25> You're describing the concept of "consideration" in contract law -- i.e., that each party to an agreement needs to exchange something of value in order for a valid contract to be formed. However, one doesn't need to pay _money_ for something in order for there to be an exchange of value.

Here, the copyright holder (Mark) has clearly given you something of value -- a copy of the text of his book. In exchange, you give the him something of value, as well - your a promise to abide by the terms of the GNU FDL (as referenced on the book's copyright page). Your promise has value to Mark -- if it didn't, he (presumably) would have simply released his work into the public domain, rather than under a GNU license.

The enforceability of open source licenses turns on this issue. The implication of your statement is that an open source license is unenforceable whenever a work is distributed for free (and obviously, this kind of distribution happens all the time). While there were some in the legal community who took this view in the past, the courts have rejected it. Check out the 2008 Federal Circuit decision in Jacobsen v. Katzer (<http://www.cafc.uscourts.gov/opinions/08-1001.pdf>), which turned on the enforceability of the open source Artistic License. Some of the more salient quotes:

\- "Traditionally, copyright owners sold their copyrighted material in exchange for money. The lack of money changing hands in open source licensing should not be presumed to mean that there is no economic consideration, however. There are substantial benefits, including economic benefits, to the creation and distribution of copyrighted works under public licenses that range far beyond traditional license royalties."

\- "The choice to exact consideration in the form of compliance with the open source requirements of disclosure and explanation of changes, rather than as a dollar-denominated fee, is entitled to no less legal recognition."

</comment></comment><comment><USER26> "My Zen teacher once told me that, when people try to do you harm, you should thank them for giving you the opportunity to forgive them."

Awesome</comment>


Notch's Livestream for Ludum Dare 21 (now on twitch.tv) - <AUTHOR> http://twitch.tv/realnotch

<comment><USER2> Anyone want a live stream of my Eclipse when I code my stochastic progressive photon mapper that will calculate photosynthetically usable radiation in an aquarium?

<comment><USER3> Sounds interesting. As long as you explain the math as you're coding.

</comment></comment><comment><USER4> I would really love to see more programmers streaming while they work.

<comment><USER5> Yeah.

I feel like I've learned how to program in a silo away from everyone else, and it's fascinating to see the mechanics of how others manipulate their code, the length of their code-build loop, etc

</comment></comment><comment><USER6> The chat in the stream is just trolls - are there are irc channels (or something) for it?

</comment><comment><USER7> Thanks you so much for such a great information. I will definetely recommend your website!

y8](http://www.y8america.com>y8);

</comment><comment><USER7> Thank you very much for your post! Very interested in your opinion.

<http://www.kizi.ws>

</comment><comment><USER7> very cool. I like this games <http://www.friv.gs></comment>


Will Bitcoin Be the Best Inflation Hedge? - <AUTHOR> https://hackernoon.com/embrace-the-fear-8t373yxt <comment><USER2> It may be true that bitcoin will be a good store of value but this article doesn't make a good case for it. For example, bitcoin is quite volatile, which would tend to make it a poor store of value. The article doesn't address that aspect at all. If obvious drawbacks aren't addressed then the case isn't made.</comment>


This city is so overcrowded it's paying people to leave - <AUTHOR> http://www.cnbc.com/2016/06/20/this-city-is-so-overcrowded-its-paying-people-to-leave.html <comment><USER2> We should do this in the US. There's plenty of housing in the US. Our only problem is that the distribution of housing doesn't match the distribution of people. And people are easier to move than houses.</comment>


Next Gen Wind Power Generator - Popular Mechanics 2007 Breakthrough Award winner - <AUTHOR> http://www.scribemedia.org/2007/10/12/shawn-frayne-windbelt/

<comment><USER2> And yet he didn't register windbelt.com or .org, which is too bad, because it's such a great name and a good place for people to learn more about it. I guess it's quite clear he's not in it for the money, though.

</comment><comment><USER3> I wonder how much power it would generate if you had a gazillion of these things lining our major highways. I bet there's nearly a constant 10mph breeze from all those cars.

<comment><USER4> What is your objective? If your objective is to help the environment, then this won't work; you are replacing coal/nuclear-generated electricity with gasoline-powered electricity, using a combination of of extremely inefficient mechanisms.

If your goal is to get free electricity by leaching off of cars, without regard to the environment, then it might work. But, there is a huge fixed cost to manufacture, transport, install, and test the machinery, and a non- negligible variable cost in maintaining the system.

<comment><USER5> The wind cars generate is not causally related to fossile fuel. Solar driven cars would also cause wind. And even now, generating additional energy from burning the same amount of fossile fuel can hardly be bad for the environment.

<comment><USER4> It isn't the same amount of fuel. If the car's engine is going to power something else besides the car, it is going to have to work harder.

Imagine the car is running in a vacuum and gets 30MPG. Now, add normal air resistance. It will not get 30MPG anymore. Now, add something else that further increases wind resistance. The car will get even fewer miles per gallon.

<comment><USER5> That assumes that air resistance is indeed increased. I doubt that, but I'm not a physicist... Maybe it depends on what is next to the motorways now?

<comment><USER4> Wind power works by creating wind resistance. In order for there to be _less_ air resistance with them installed, they would have to be replacing something that caused even more wind resistance. But, that seems unlikely.

</comment></comment></comment></comment></comment></comment><comment><USER6> How is this related to the resonance frequency of the belt? Is the system efficient only at certain frequencies? Do you need to select a belt to match current wind conditions?

<comment><USER7> You can probably change the resonance frequency by dynamically adjusting the tightness... It seems possible to make a rudimentary mechanical device that would do this.

</comment></comment><comment><USER8> The problem with the next generation of energy isn't creation, but storage and distribution.

Efficient batteries mean more progress than most generation breakthroughs.

<comment><USER9> I don't really think that batteries are so necessary, and this development is phenomenal.

This is huge. It means wind is cheaper than nuclear, even with most subsidies.

We don't need batteries -- Arthur Rosenfeld has done work going way back that shows how distribution isn't a problem for windpower. That's a widespread myth, perpetuated by media echo chambers, funded by big business.

<comment><USER8> Peak wind != peak demand.

That's all you really need to know to realize this is a storage and distribution problem.

Nuclear, coal, oil, natural gas, geothermal, hydro --- all the ways we currently make power are always available.

<comment><USER9> Did you know that superconducting power lines are commercially feasible, right now, for high capacity lines? Negawatt proposals account for a large part of the problem, if you make distribution efficient. And it can be made very efficient using superconducting lines.

For the brief periods where the world's overall wind production is low, if wind ever takes over most of the grid (it probably won't, considering the political dynamics), there is already a very effective storage technology -- liquid hydrogen. It has a practically limitless capacity (just add more tanks), and it avoids the toxicity problem of batteries, and it avoids the materials problem of fuel cells (still, nobody has found something cheap to replace platinum.)

<comment><USER8> Until hydrogen is stored in a solid material, using what some would call nanotech but what I call physics, it isn't going to be common. This isn't to say this is far off, just the way I see it coming -- with knowledge gleaned from physics PhDs working on the problem.

But the simple answer is 'yes'. Hydrogen could make an excellent base for a battery.

</comment></comment></comment></comment></comment><comment><USER10> Cool tech! My only concern is noise levels... anything that oscillates at high(er) frequencies is bound to produce a lot of uncomfortable noise.

</comment><comment><USER11> I take it the admins don't edit submission titles anymore...

<comment><USER12> "When used judiciously, swearing can be hilarious, poignant, and uncannily descriptive. More than any other form of language, it recruits our expressive faculties to the fullest: the combinatorial power of syntax; the evocativeness of metaphor; the pleasure of alliteration, meter, and rhyme; and the emotional charge of our attitudes, both thinkable and unthinkable. It engages the full expanse of the brain: left and right, high and low, ancient and modern. Shakespeare, no stranger to earthy language himself, had Caliban speak for the entire human race when he said, "You taught me language, and my profit on't is, I know how to curse."

\- Steven Pinker

<comment><USER11> I don't see any swearing, though. How is this relevant?

<comment><AUTHOR> well then I'm curious - why did you complain?

<comment><USER11> Because of cartoon swearing. What are we, in kindergarden?

</comment></comment></comment></comment></comment><comment><USER12> The next logical step is to take it to the nano level and make a paint that will make electricity when it gets a mild breeze.

<comment><USER13> Excellent idea!

</comment></comment><comment><USER14> wow thats really cool. between this and dean kamen's stirling engine, i have a feeling the third world is in for some _major_ changes in the next decade or two.

really awe inspiring :)

</comment><comment><USER15> Damn, that is impressive! But... Does it really scale? I sure hope so.

<comment><USER16> Scale in what sense? The stated motivation for the invention was to provide small amounts of power.

</comment></comment><comment><USER17> So is this the real deal?

<comment><USER16> What real deal? It doesn't seem far-fetched that it can generate enough power to run a few LEDs. Probably a pinwheel can do that too.

<comment><USER17> I meant the real deal in the sense of supplanting fossil fuels and/or nuclear power with regards to cost efficiency.

Dani seems to think that it is the real deal, and I hope that the Illuminati doesn't make the patent holder an offer he can't refuse.

<comment><USER16> According to the article, the problem it is solving is generating small amounts of power inexpensively and reliably. It would power those LED lights which are used to allow people in developing countries to read at night.

You seem to think that this is a small-scale proof of concept even though there is no reason to think that this is anything but the full sized device.

He doesn't claim nor does it seem credible that there is a particular advantage to this technology on larger scales. Bearing friction, which he cites as a problem at the small scale, is not such a big issue for larger generators.</comment></comment></comment></comment>


Which programming language is fastest? - <AUTHOR> http://shootout.alioth.debian.org/fastest-programming-language.php

<comment><USER2> The fastest language is the one that you know well enough that you are actually able to implement and release your ideas to your users. Benchmarks speed is only one part of the equation.

<comment><USER3> Nope - that's the fastest language for you.

</comment></comment><comment><USER4> I once heard a joke related to this: Dev1: "Did you know C# is faster than C?" Dev2: "No, really? By how much?" Dev1: "Oh about 6-12 months"

</comment><comment><USER5> "No. ... No."

Benchmarks are worthless unless they accurately model your application and workload. Is C 42 times faster than Python for doing numerical calculations? No. If you are using NumPy, the difference is more like 10%. (I pulled the 10% figure out of my nether orifice, but I believe it to be in the ballpark.) Yes, I know that NumPy is buckets of C with a tasty Python frosting.

<comment><USER3> > Benchmarks are worthless unless...

There's a page for that! <http://shootout.alioth.debian.org/flawed- benchmarks.php#app>

> If you are using NumPy...

[http://shootout.alioth.debian.org/u32/program.php?test=spect...](http://shootout.alioth.debian.org/u32/program.php?test=spectralnorm&lang=python&id=2)

</comment></comment><comment><USER6> Things we don't need to hear, EVERY LAST TIME anyone says anything quantifiable about programming language performance:

1\. People are more or less productive in different languages.

2\. If a task can be done mostly in a library the speed of the programming language is less important.

3\. The performance difference between languages depends on the workload.

</comment><comment><USER7> I'm surprised that Racket is beating SBCL. When did that start happening?

<comment><USER8> They now have JIT compilation.

</comment></comment><comment><USER9> I don't want the fastest possible language or the most powerful possible language. I want the simplest language that is fast enough and powerful enough. The Benchmarks game is a lot of fun, but if I were making a language (especially one not designed for speed), I probably wouldn't put it up there. It encourages contributors to think "oh crap, if we optimized our X better, we'd be like 4 higher in the listings!" instead of "What sort of useful code can I write?".

</comment><comment><USER10> I'm impressed that PHP is now less than 20x slower than SBCL and Racket (Lisp and Scheme implementations). It's improved a lot since PHP4.

</comment><comment><USER11> Assembly Language, I guess.

</comment><comment> alok-g With so much variation in the time measured for a given language? Fastest to slowest is approaching a factor of 100 in some cases.

This study is useless (even if meaningful) with this much variation, and no clear explanation for why so.

<comment><USER3> > Fastest to slowest is approaching a factor of 100 in some cases.

Which cases?

</comment></comment><comment><USER12> GHC Haskell is doing surprisingly well. That must be a testament to the extremely high quality of the GHC code generator and optimizer.

<comment><USER13> Static type gives compiler plenty of information for analysis and can generate very optimized code.

</comment></comment><comment><USER14> You have to click around to see it, because the default rendering only includes GNU C++, not GNU C.

<comment><USER15> Graph including GNU C: [http://shootout.alioth.debian.org/fastest-programming- langua...](http://shootout.alioth.debian.org/fastest-programming- language.php?calc=chart&gcc=on&gpp=on&ghc=on&java=on&csharp=on&racket=on&sbcl=on&v8=on&hipe=on&lua=on&vw=on&python3=on&yarv=on&php=on&perl=on)

</comment></comment><comment><USER16> How about LLVM C & C++ ?

<comment><USER3> Here's where you can download the Python measurement scripts so you can make those LLVM measurements and publish them - <http://shootout.alioth.debian.org/help.php#languagex>

</comment></comment><comment><USER17> let's kill all the language lawyers...

</comment><comment><USER18> Also notice, time is plotted on a log scale.

</comment><comment><USER19> Seems quite different compared to what I remember previously. Have some communities been updating their interpreters/compilers to optimize for these tests?

(Reminds me of the 1990s when Intel built a special machine (which you could theoretically buy, to fulfill the demands) and wrote a special compiler for SPECs... :-)

<comment><USER20> Could be?... but I suspect its more _communities_ optimising their benchmark programs.

See footnote: _Which programming language is fastest? No. Which programming language implementation has the fastest benchmark programs?_</comment></comment>


Eager Execution: An imperative, define-by-run interface to TensorFlow - <AUTHOR> https://research.googleblog.com/2017/10/eager-execution-imperative-define-by.html <comment><AUTHOR> You can read out more about it in the blog post ( [https://research.googleblog.com/2017/10/eager-execution- impe...](https://research.googleblog.com/2017/10/eager-execution-imperative- define-by.html) ) or the README ( [https://github.com/tensorflow/tensorflow/tree/master/tensorf...](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/eager/README.md) ). This is still a preview release, so you may hit some rough edges.

Looking forward to your feedback as you try it out.

<comment><USER2> I'm on the team that worked on this -- happy to answer questions!

<comment><USER3> Hot damn this has got me all giddy. How will this work on single node multi- GPU systems? For example, with PyTorch you have to either use threading, multiprocessing, or even MPI. Can you think of a not-too-scary way to use eager execution with multiple GPUs?

<comment><AUTHOR> We're still fairly early in the project, so for now threading is the only supported way.

We can do better, however, and we're working on ways to leverage the hardware better (for example, if you have no data-dependent choices in your model we can enqueue kernels in parallel on all GPUs in your machine at once from a single python thread, which will perform much better than explicit python multithreading).

Stay on the lookout as we release new experimental APIs to leverage multiple GPUs and multiple machines.

</comment></comment></comment></comment><comment><USER4> Announcing TensorFlow's new development roadmap mandate: copy everything PyTorch is doing :-)

<comment><USER5> I think you mean Google is following the leadership of Chainer, like Facebook already does? PyTorch started as a Chainer fork. Its dynamic graph internals are all from Chainer.

<comment><USER6> This isn't art. There are no points for originality. If open source projects borrow the best parts from each other, that's a good thing.

<comment><USER5> It's not a bad thing. It's good for users. But give credit to the leaders in the field. If you make an iPod clone, you call it an iPod clone, not a clone of the Zume HD.

Chainer started it, was around years earlier, and it still has more users. So Google is not copying PyTorch, it's copying Chainer.

<comment><USER7> Do you have a source for Chainer currently having more users than TensorFlow?

<comment><USER8> Not more users than Tensorflow. But maybe more user than other dynamic deeplearning framework (PyTorch, Gluon, DyNet...)

</comment></comment></comment></comment></comment></comment><comment><USER9> TensorFlow: everything to all people.

Eager is actually not as innocent as "open-source projects borrowing the best parts from each other", as some commenters here suggest.

Google is attempting to dominate the machine-learning API and the Python ecosystem for scientific computing.

The company that controls the API influences which apps are built on it and how. Think about how Google bundled Android services on top of Android, and how that posed an existential threat to other companies. That's what's coming for TensorFlow. Many developers are too naive to realize it, or too short- sighted to care.

<comment><USER10> Huh? They're attempting to dominate the machine learning ecosystem by writing a bunch of free and high quality machine learning libraries? What exactly are they doing wrong?

I wouldn't compare a permissively licensed library to Android services at all.

<comment><USER9> I'm surprised I have to write this, but Google is not a charity. They are pouring commercial resources into Tensorflow for a reason. That reason is Google Cloud. Tensorflow is a Trojan horse to get people to use Google Cloud and other paid Google products. How do I know this? Because Tensorflow works better on Google Cloud than anywhere else, and Google is making a concerted effort to catch up with AWS in cloud, mostly through machine learning.

I didn't compare Tensorflow to Android services. I said that Tensorflow would serve as the basis of a service bundle, much like Android did. Let's come back in a couple years and I'll tell you I told you so.

<comment><USER11> > I'm surprised I have to write this,

Insulting the reader

> but Google is not a charity

truism

> They are pouring commercial resources...

As opposed to "non-commercial resources"?

> ... for a reason.

Everything happens for a reason.

> That reason is Google Cloud.

> How do I know this?

Pray tell!

> Because Tensorflow works better on Google Cloud than anywhere else.

This is the only real argument in this conspiracy. And if "anywhere" includes the users' hardware, it's wrong: tensorflow runs flawlessly on any Linux/NVIDIA hardware. Maybe it works better with GCE than AWS, but that would once again fall into that "rather unsurprising" category of factoids.

> Google is making a concerted effort to catch up with AWS in cloud, mostly > through machine learning.

This can be re-written as "Google has a cloud offering, which it tries to sell. And right now, machine learning is pretty hot". Throwing a "concerted effort" in there is just trying to jazz it up to something ominous. Which it isn't.

> I didn't compare Tensorflow to Android services. I said that Tensorflow > would serve as the basis of a service bundle, much like Android did.

"The basis of a service bundle" actually doesn't sound that scary. Nobody is disputing that Google offers services build on tensorflow. It just isn't any sort of "Trojan horse" conspiracy, and it is somewhat limited by the fact the tensorflow is OSS licensed and could be forked by anybody people suddenly find out it's full of geek soldiers.

<comment><USER9> > truism

Maybe, be people in this thread treat Tensorflow's creation as an act of simple altruism.

> And if "anywhere" includes the users' hardware, it's wrong: tensorflow runs > flawlessly on any Linux/NVIDIA hardware. Maybe it works better with GCE than > AWS, but that would once again fall into that "rather unsurprising" category > of factoids.

Sorry, Tensorflow is slow on GPUs compared to other frameworks. This is not just an early blip, its a consistent pattern that has been repeatedly demonstrated. Why is Tensorflow slow on commodity hardware? Why isn't Google with it's infinite resources making Tensorflow run as fast as other frameworks on GPUs? Because it needs to demonstrate an advantage on the Google Cloud with TPUs.

On that cloud, it surrounds Tensorflow with other functionality that makes it easy to build AI, which aren't part of the Tensorflow project. Tensorflow is hard and inefficient to serve for inference, for example.

Machine learning is Google cloud's only hope to salvage Diane Greene's efforts and extend their dominance to a new sector. They're running a distant fourth.

> actually doesn't sound that scary.

It sounds scary to a lot of companies that don't want to be controlled or destroyed by Google. But by all means, lend them a hand, geek soldier.

</comment></comment></comment></comment></comment><comment><USER12> Hey guys, if I could request... Please fix the serialization story for tensorflow. There 6 googleable methods to export from tensorflow and nobody knows what will work on the cloud, what can be exported from cloudml and what can be loaded on Android.

It has to be consistent and there has to be one way to do it.

I personally have a 10 message thread with Google cloud support on exporting a Cloud trained model to tensorflow and nobody could figure it out [Case #13619720].

<comment><AUTHOR> Did you try using SavedModel? It should be seamless to use downstream with tensorflow serving and it's not that hard to get estimators to spit those out.

<comment><USER12> I really wish. [https://github.com/tensorflow/tensorflow/issues/12750](https://github.com/tensorflow/tensorflow/issues/12750)

In fact if you dig up the case, then even official support told me that savedmodel needs some freezing using bazel otherwise it doesn't work.

The github page and stackoverflow are full of these. If you can, please take the message to the other side :(

I don't think the cloud guys (where training will happen in distributed mode) talk to the android guys (where models will be used after quantization). There is a huge serialization problem that all of us are currently struggling with.

<comment><AUTHOR> Ah, I didn't know SavedModel didn't work in android. I think freezing is still the way to go there? I'm sorry, I don't personally work on the mobile side of things.

<comment><USER12> I should apologize for hijacking this thread(and i'll stop here). But Tensorflow is getting to be unusable because of the serialization story. We don't have such issues on Caffe2 or anywhere else. It essentially means different parts of the tensorflow ecosystem are unable to talk to each other.

I really pray the tensorflow teams give it due importance.

<comment><USER13> I'm the original author of the freeze_graph script, so I'm to blame for a lot of the on-going mess here. For what it's worth I'm actively working on cleaning this up, since I know what a painful experience it is. Apologies for everyone who's struggled with this, and I will take a look at the case number mentioned above and follow up internally to see if there's anything I can help with.

<comment><USER12> Thanks for this! I would like to bring two things to your attention :

1\. We don't know what to use and its very confusing. For example, now there is [https://stackoverflow.com/questions/42216208/should- tensorfl...](https://stackoverflow.com/questions/42216208/should-tensorflow- users-prefer-savedmodel-over-checkpoint-or-graphdef). Will freeze_graph become canonical and we forget about SavedModel? And everything else deprecated? It should be part of the core API and workable on CloudML, where we don't have a lot of control on running scripts and certainly not Bazel builds.

2\. Android/ios story. Now you have the Pixel Visual Core as well... Please make it seamless all the way to Android or Ios or raspberry pi (whatever you guys support).</comment></comment></comment></comment></comment></comment></comment>


AT&T CTO claims US leads in mobile. Paging Truth Police? - <AUTHOR> http://communities-dominate.blogs.com/brands/2010/07/att-cto-claims-us-leads-in-mobile-paging-truth-police.html

<comment><USER2> I agree that Japan is ahead, but seriously, who gives a crap if every other person in Italy has two cell phone subscriptions? Thats retarded.</comment>


JavaScript: Use === Instead of == - <AUTHOR> http://codingstyleguide.com/s/129

<comment><USER2> The whole point of having two sets of comparitors (=== and == in this instance) is that you can use the correct one for any given circumstance. Proscribing the use of one in favour of the other is just woolly thinking.

<comment><AUTHOR> Yes but in most of the cases it's better to use === operators. I mean, they both are correct. It's just a matter of style

</comment></comment><comment><USER3> This is almost always the case to help avoid type coercion where one does not want it.

<comment><AUTHOR> Agreed, here are more JS styles that might be interesting for you: [http://codingstyleguide.com/lang/6/javascript](http://codingstyleguide.com/lang/6/javascript)</comment></comment>


Signal and GIPHY - <AUTHOR> https://whispersystems.org/blog/giphy-experiment/ <comment><USER2> One may wonder what the point of adding these is to an e2e messaging app, but I would contend that you don't want your messaging app to get into the same predicament as PGP where mere use of the app is considered suspicious.

You would also prefer it if your friends used this app so that you could communicate with them and not have to spend forever convincing them.

I am a Signal user, but as e2e crypto has moved into more mainstream services such as WhatsApp, and even Facebook's Messenger I've stopped trying to convince friends to install Signal since it's easier to just initiate private chats in these popular messengers.

</comment><comment><USER3> Interesting concept (using the Signal server as relay/vpn-like).

But honestly, I don't care about sending GIFs and I want a messaging service (especially a privacy-oriented) to be as sleek as possible. Additions like these just seem to increase the attack surface.

</comment><comment><USER4> This seems like system creep to me. Also, Giphy hasn't figured out a way to bring in revenue, knowing the history of these kind of services they will probably soon collect user data anyway to sell to advertisers.

I would be more a fan of static sticker packs, like Apple has introduced in their messaging app. Maybe even have independent artists make them instead of copyrighted content. Would fit more the philosophy of Whisper Systems in my opinion.

</comment><comment><USER5> I agree that this is rather useless. I have given up on Facebook and Whatsapp and what I am missing most is the double checkmarks when a message has been delivered / read, as well as attaching any kind of file to a message.

That being said, I use Signal extensively and have convinced some people to use it as well. It's an important piece of software to me.

</comment><comment><USER6> Why?</comment>


The Economics of Tidying Up - <AUTHOR> http://www.theatlantic.com/business/archive/2015/05/an-economist-reads-marie-kondo/392921/?single_page=true <comment><USER2> Obligatory link to Paul Graham's article on the same issue:

[http://paulgraham.com/stuff.html](http://paulgraham.com/stuff.html)

Quote: " _I think humans constantly scan their environment to build a mental model of what 's around them. And the harder a scene is to parse, the less energy you have left for conscious thoughts. A cluttered room is literally exhausting._"

You need to de-clutter to think better. It is certainly true for me.

</comment><comment><USER3> A good organizer is a hoarder. It's better to take a good at everything around, go category by category, and get rid of everything you don't need. Save nothing for those 'what if' scenarios that never come. Say goodbye to momentos that serve no purpose. If you feel joy when holding or looking at it, I would say that serves a purpose, but that's a fine line and easy to cross by putting everything in that category. Get together everything you're getting rid of and have a yard sale. Anything you don't sell, drop off what you can at a goodwill and throw the rest out.

You'll feel a huge weight lifted off your shoulders when done, a weight you didn't even know was there when you started.

</comment><comment><USER4> My experience is that a large fraction of creative people are basically lazy slobs. What can be done?

A professor I know installed two dishwashers in his apartment: one for dirty and one for clean. This seems awesome, but it's certainly tricky to make it really work: You need to limit yourself to only one load of dishes. You can get into the situation where you have two washers with clean dishes. You either have to mark one of them as dirty and re-clean those dishes, or ugh, sweep the clean dishes into one washer. Also pots never fit.

<comment><USER5> That seems entirely doable. I've wanted two silverware baskets. One for the holding the clean utensils outside of the washer, and one to be in the dish washer to receive the dirty.

Pots absolutely fit. The only pots and pans that don't go in the washer are non-stick. Everything else, including the jumbo soup pots fit. Not much else does along with the pots, and I don't care because I'm not washing a pot by hand.

As an aside, I actually finished up Kondo-izing my apartment about 2 months ago. I am working on selling the items that were too valuable to simply throw away. Very nearly close to being "finished".

</comment></comment><comment><USER6> Japanese manufacturing calls this "5S"

[https://en.wikipedia.org/wiki/5S_(methodology)](https://en.wikipedia.org/wiki/5S_\(methodology\))</comment>


Show HN: Chrome Extension saves the last Tweet you read to easily find it later. - <AUTHOR> https://chrome.google.com/webstore/detail/remember-last-read-tweet/fnfjecnchnojlpniikiibnglpbonimnb

<comment><AUTHOR> This is my first published extension. I'm sure there might be some issues which I'll be glad to fix.

This is the github page: <http://trufa.github.com/Remember-Last-Read-Tweet/> And this is here is the source: <https://github.com/trufa/Remember-Last-Read- Tweet>

The main reason I created this extension is the fact that it didn't make much sense to me the way the Twitter flow if you don't want to miss any tweet, I was always scrolling until I found my the last tweet I had read and reading things in inverse chronological order.

That said a new feature I will soon add to the extension is an option to mark the last tweet but go back to the top and start reading from there if you prefer that flow.</comment>


Gallup Poll: Americans' Biggest Problem in 2015? Government - <AUTHOR> http://www.govexec.com/federal-news/fedblog/2016/01/americans-biggest-problem-2015-government/124849/?oref=govexec_today_nl <comment><USER2> A lot of people would say police state is the biggest problem considering what happened to Ian Murdock recently (if you know who Ian Murdock was that is).</comment>


Twitter likely to kill its music app - k-mcgrady http://allthingsd.com/20131019/twitter-likely-to-kill-its-music-app/

<comment><AUTHOR> Twitter had a music app? I'm not trying to be funny or condescending - this is litteraly the first time I've heard of Twitter #Music, and I wouldn't say I've been living under a rock. Also I'm an avid Twitter user.

That being said, sorry it didn't work out. There's a lot of innovation to be made in the music industry.

<comment><USER2> [https://music.twitter.com/](https://music.twitter.com/)

<comment><USER3> Too bad that never appeared as an unrequested "promoted" tweet, instead of the routine promoted drivel that means nothing to me.

</comment></comment></comment><comment><USER4> This is annoying. I really liked the WeAreHunted startup which was killed on acquisition. The Twitter app had different functionality, and wasn't able to hold a light to the WeAreHunted music recommendation service.

I feel for the WeAreHunted guys, they really had stuff going for them.

[http://wearehunted.com/](http://wearehunted.com/)

<comment><USER5> I agree, WeAreHunted provided superior service to the Music app. The ability to play the entirety of a song without a Twitter and Spotify account was awesome — it was a great new way of discovering music.

<comment><USER6> Well if you have spotify they're posting the emerging charts again on it (still really miss the discovery engine though): [https://twitter.com/wearehunted/status/381496704052129792](https://twitter.com/wearehunted/status/381496704052129792)

</comment></comment></comment><comment><USER7> Maybe they're refocusing their team effort on things like EventParrot:

[http://www.techhive.com/article/2053686/twitters-event- parro...](http://www.techhive.com/article/2053686/twitters-event-parrot- account-experiments-with-personalized-news-alerts.html)

Another strange Twitter experiment on the surface. But maybe it's to test out some machine learning stuff they are building/acquiring.

Branching out into new territory trying to find meaning in the massive database they have. Music seems to have been a failure (or maybe just the UI/product was).

I work with a company doing NLP for book recommendations from Twitter feeds ([http://bookvibe.com](http://bookvibe.com)) and while it can be extremely challenging given the variety of Tweet slang/text, there is some value in the opt-in nature of peoples Twitter social networks. Much more than say Facebook, which from our testing completely fails at being a good source of recommended content, for ex recommending a movie because x liked it. Since on Facebook you friend a lot of people by proxy of knowing them in life (parents/old friends)... not following based on shared interests like with Twitter.

/tangential rant

<comment><USER8> Maybe tangential, but interesting!

It seems like not only do you get more information from someone tweeting about a book (etc) vs just liking it on Facebook, it takes more effort and that probably says something too!

</comment></comment><comment><USER9> I love Twitter's music app, I have discovered so much good music that I constantly use it to find new songs and bands.

However, I believe that the fact that one needs an additional paying service (Spotify, Rdio) to listen to full tracks is a friction that kills the product.

I was hoping that Twitter Music was going to be Twitter's version of Pandora or iTunes Radio, but not an extension of a third party $ervice.

</comment><comment><USER10> There's so much promise in Twitter #music. It would be a shame if they killed it rather than iterate on the product. I started using it the day it was released and was really hoping for something special.

I stopped using it regularly because it's leaderboard driven. Jay-Z was at the top of the hip-hop section for days on end. So discovering new hip-hop was nearly impossible, but they have that data.

<comment><USER11> That just goes to show how phresh is Jay-Z's music .

/s

</comment></comment><comment><USER12> Seems weird to not even try and iterate on it. The concept for #music seems pretty solid. I could see it being expanded into popular and trending lists for all different sorts of things: books, articles, fashion, movies, etc. And then Twitter could be the goto source for what's trending nowadays. That seems incredibly valuable if they could manage it. Wonder what has been deemed more important.

</comment><comment><USER13> I predicted this not long after they purchased We Are Hunted. I quite personally thought the actual We Are Hunted music discovery platform was fantastic, it was a well-built application and I always found it strange Twitter bought WAH. I personally know the WAH team they purchased are an incredibly talented bunch of developers, whether it keeps that team during the next phase remains to be seen though. The whole concept was flawed from the beginning and it didn't actually appear as though Twitter integrated any of the main core of the WAH discovery platform which was a well-written and surprisingly accurate algorithm.

Had they thought about it some more, marketed themselves better and integrated more of the features from We Are Hunted's music discovery engine, maybe it might have faired better. It's obvious this was very much an acquihire type of situation.

<comment><USER6> I absolutely loved (and miss) We Are Hunted's music discovery engine.

They recently started putting out the emerging charts again on Spotify, which is interesting (they were on twitter music, but since you only got a few second-clips of songs, it was useless to me): [https://twitter.com/wearehunted/status/381496704052129792](https://twitter.com/wearehunted/status/381496704052129792)

</comment></comment><comment><USER14> I enjoyed #music but if you're not particularly interested in the chart aspect of it, it loses its novelty quickly.

I found the recommendations seemed to settle and that was it, there didn't seem to be any point in going back once I had done my initial exploring. I just opened it up again now after several months to see much the same recommendations.

There's only so many recommendations that you can actually make though, so it's hard to blame them for that particular problem as long as the recommendations are accurate.

</comment><comment><USER15> Bigger companies get criticized all of the time for not being innovative or trying risky things.

When they actually do try something risky and it doesn't work out (e.g. Twitter Music), they get crucified for shutting it down, even though in all likelihood it's the right thing to do.

Can't win, it seems.

<comment><USER16> Risky. Yes. Innovative? Hell no!

</comment></comment><comment><USER17> I honestly had no idea twitter has a music app outside Spotify until now.

If I get it correctly though, does killing this also mean killing the backend which the Spotify app depends on?

If so that does that mean twitter admits it can't make money/data from it's twitter stream? That would put it in a horrible position when trying to sell its stream API to future clients.

</comment><comment> mkr-hn I remember this. I couldn't use it for the first three days due to bugs. Then it told me I needed a premium subscription to whatever I connected with to hear more than 30 second clips, and I never looked at it again.

</comment><comment><USER18> Wearehunted was the best music service around but when twitter got their hands on it, it was done! Useless. Someone recreate it please... I would pay cash money.

</comment><comment><USER19> Not too surprised by this. #Music is a really hard business to crack. Only a few have been able to do it successfully.

</comment><comment><USER20> They shouldn't kill it.</comment>


The Pitchforks Are Coming… for Us Plutocrats - <AUTHOR> http://www.politico.com/magazine/story/2014/06/the-pitchforks-are-coming-for-us-plutocrats-108014 <comment><USER2> we can only hope</comment>


Bypassing GitHub's OAuth Flow with a Head Request - <AUTHOR> https://blog.teddykatz.com/2019/11/05/github-oauth-bypass.html <comment><USER2> * 2019-06-19 23:28:56 UTC Issue reported to GitHub on HackerOne

* 2019-06-19 23:36:50 UTC Issue confirmed by GitHub security team

* 2019-06-20 02:44:29 UTC Issue patched on github.com, GitHub replies on HackerOne to double-check that the patch fully resolves the issue

* 2019-06-26 16:19:20 UTC GitHub Enterprise 2.17.3, 2.16.12, 2.15.17, and 2.14.24 released with the patch (see GitHub's announcement).

* 2019-06-26 22:30:45 UTC GitHub awards $25000 bounty

So used to these disclosure articles where the timelines look very different, communication is lacking and there's pushback on the bounties etc.

Refreshing to see that sometimes the process works as everyone hopes it will.

<comment><USER3> I mean, it's a total auth bypass in GitHub by simply sending a HEAD request, with a one line fix. The turnaround time shows that they have the ability to evaluate a serious report through HackerOne quickly, they have a dedicated engineer who could get in and make the one line fix, and they have the ability to deploy new code quickly. All good things!

I am mostly impressed that they paid out $25k in under a week. That's a sign of not just a good engineering setup, but some good bureaucracy as well.

<comment><USER4> Perhaps it does merely reduce to "being competent". But the contrast with nearly every other vendor out there is stark.

Been managing GHE for years, and I have been consistently impressed with Github's code quality, competence, and even product management (nearly every time I think, "there should be a way to...", there already is).

From the outside, at least, they look like the model to emulate for this sort of application.

<comment><USER5> You're both right, competency is in fact _really damn impressive_.

(I have come to think, as a software engineer, that we've comuterized so much of social life such that our economy literally could not afford it if it wasn't mostly crap).

</comment></comment></comment></comment><comment><USER6> This is why I hate it when people think there are N possible cases, and in a cascading if/else construct they only check for N-1 conditions and assume the remaining all fall within the Nth case. Thing is application logic in the real world is often fuzzy, it is entirely possible to overlook certain possibilities (which may or may not arise from bugs elsewhere); and even if you have considered all cases at present, future changes to other parts of the code may inadvertently introduce new possibilities.

Personally, I always check for all N conditions, and raise an exception when "the impossible" happens; this way, the application would fail noisily instead of silently doing something unintended. However, sometimes other people would "optimize" away my last condition, which is very frustrating.

Edit: Checking for all N cases helps with readability too. Otherwise one has to figure out what exactly is the remaining case by exclusion, which is sometimes not at all obvious.

<comment><USER7> A common reason people don't do it the way you're suggesting is dogma about code coverage.

If the code has branches for each possible case, and then an "else" to cover anything else (which raises an exception indicating something impossible has happened), there is often no good way to write a test that covers the "else" logic, since the coder doesn't believe there's a way to end up going there. Or if there is a way to force it to happen, it involves jumping through hoops that are too much effort.

<comment><USER8> Some languages have good alternatives to this. Examples:

* Rust has an unreachable!() macro that tells readers and static analyzers that it should be dead code; but raises an error if executed at runtime. [https://doc.rust-lang.org/std/macro.unreachable.html](https://doc.rust-lang.org/std/macro.unreachable.html)

* Languages with pattern-matching will either crash at compile-time if the set of clauses is non-exhaustive, or at run time if a case is missing. That is, if you don't have a catch-all clause.

<comment><USER9> Cool language feature! I've done this in other languages using a code style policy where all "naked" else statements and 'default' inside a switch statement must throw an uncaught exception or otherwise deliberately crash.

        if(option==1)
            do_somethimg();
        else
            do_something_else();

...must then be rewritten as:

        if(option==1)
            do_somethimg();
        else if(option==2)
            do_something_else();
        else
            abort();

This kind of defensive coding would have helped to prevent the famous 'goto fail' bug from a few years ago.

</comment></comment></comment></comment><comment><USER10> What a fantastic bug. Rails routes HEAD to GET, but .get? in a HEAD handler is false. Github uses a postback to /authorize to complete OAuth, distinguishing between the original GET and the completing POST with .get?. Rails sees the HEAD request and assumes it's a POST (because it's not .get?) --- and also assumes that, because it's a POST, it's CSRF protected, which it is not, because it is not actually a POST.

<comment><USER11> It's bad assumptions all the way down.

Also easy to bake into basic static analysis going forward. Knowing GitHub, I'd think a bug like this probably won't show up again in the near future.

<comment><USER12> > It's bad assumptions all the way down.

It _always_ is. The moment you can shine light between your model of what the code does and what it _actually_ does you have at least a bug and maybe much worse.

</comment></comment></comment><comment><USER13> > _So Rails (along with some other web frameworks) implements a clever hack: > it tries to route HEAD requests to the same place as it would route GET > requests. Then it runs the controller code, and just omits the response > body._

I wonder if Rails will fix the default implementation of handling HEAD requests, similar to how they overhauled the default handling of mass assignment of parameters in 2012 (coincidentally, a flaw also exposed via Github) [0]? Obviously, the latter issue posed a much bigger risk to the average Rails app.

[0] [https://news.ycombinator.com/item?id=3666564](https://news.ycombinator.com/item?id=3666564)

edit: fixed URL

<comment><USER14> > I wonder if Rails will fix the default implementation of handling HEAD > requests

It absolutely should. Nobody expected Rails to covertly turn HEAD into GET. It must be explicit "get_or_head" method in routes.rb

<comment><USER15> HEAD isn't turned into GET, it's _routed_ the same as a GET request. If it were actually turned into a GET request, then `request.get?` would have been true, and this exploit wouldn't have happened.

But I do agree with your point that routing of HEAD requests should be explicit.

<comment><USER14> > HEAD isn't turned into GET, it's routed the same as a GET request

Pardon my poor wording indeed, I intended to mean this too.

<comment><USER16> Rails actually did turn the HEAD into a GET back when this code was written - [https://github.com/rails/rails/blob/e17e25cd23e8abd45b170646...](https://github.com/rails/rails/blob/e17e25cd23e8abd45b1706463dd57c90fa6dcb7c/actionpack/lib/action_dispatch/middleware/head.rb#L8-L9)

</comment></comment></comment></comment></comment><comment><USER17> In the proof of concept[1]:

1\. Send an ajax HEAD request, which grants the permissions.

2\. However, since the HEAD response doesn't have valid CORS headers, you can't read the 'code' parameter from the HEAD response.

3\. To get around CORS, the proof-of-concept redirects the user to the same OAuth url _again_.

4\. Since the user has already authorized the scope (from the previous HEAD request), Github automatically redirects back to the redirect_uri (the proof- of-concept page) with a new 'code' that the author can then use.

So I have two questions:

a) If I have 3rd party cookies disabled, will the "credentials: 'include'," part of the ajax HEAD request still work?

b) Why does Github automatically redirect back the 2nd time without asking the user to authorize again? I thought it was best practice to ask the user to click authorize every time even if they're authorizing the same scope they previously authorized?

[1]: [https://not-an-aardvark.github.io/oauth-bypass-poc- fbdf56605...](https://not-an-aardvark.github.io/oauth-bypass-poc- fbdf56605489c74b2951/)

<comment><USER18> > I thought it was best practice to ask the user to click authorize every time > even if they're authorizing the same scope they previously authorized?

I've never seen an authorization server that works that way. Because I walked to make sure I wasn't missing anything, I went back and reviewed all the guidance I could find on the matter and can't find any reference to the suggestion you make.

<comment><USER17> Hmmm, is there guidance saying that you _should_ auto-redirect?

The spec says, "If the authorization server observes multiple attempts to exchange an authorization code for an access token, the authorization server SHOULD attempt to revoke all access tokens already granted based on the compromised authorization code."[1]

If an authorization server implements the recommended behavior and an auto- redirect, doesn't that mean that GET requests will no longer be safely considered immutable since they may cause revocation of previous access_tokens?

[1]: [https://tools.ietf.org/html/rfc6749#section-10.5](https://tools.ietf.org/html/rfc6749#section-10.5)

<comment><USER18> I did not get the impression that there is an attempt to reuse the authorization code, but rather that a completely new flow was initiated.

Reusing the same authorization code should of course be considered suspicious.

<comment><USER17> Ah, yes, that's correct. I guess I was assuming that once you issue a new authorization code, the authorization server should invalidate any previously issued access_tokens/refresh_tokens because the new authorization code represents a new grant. Or are you supposed to wait until the code is sent to the token endpoint (to get the access_token/refresh_token) before invalidating old access_tokens?

<comment><USER18> For web app clients, you definitely don't want to invalidate other access tokens in case the user has other sessions open. For native clients, the calculus might be different.

</comment></comment></comment></comment></comment></comment><comment><AUTHOR> I found a very similar bug in my code, though not in such a dangerous place! So thank you Teddy Katz and GitHub for helping me to fix a mistake in a less stressful way. This is why sharing detailed vulnerability reports is such a good thing.

</comment><comment><USER19> It took all of 8 minutes from the bug bounty hunter reporting, to Github confirming the finding. That's amazing.

</comment><comment><USER20> Interesting bug.

It makes me appreciate working with languages that support pattern matching like Elixir.

I think this type of bug would have been preventable with pattern matching because that single controller function would have likely been split out into 2 functions that each matched against a specific HTTP method, and when the unmatched pattern came into play (the HEAD request) it would have failed to find a match and then threw an error instead of processing it as something else.

<comment><USER21> This class of bug (CSRF bypass via route confusion) is probably more common in Phoenix apps. I've found a handful of apps vulnerable to this issue with Sobelow.

People create (for example) a get '/profile' and a post '/profile', and the action intended to correspond with post requests really just pattern matches against params.

I've also seen at least one app implement this properly, matching against the HTTP method as you described.

<comment><USER20> To be safe from this in Phoenix that would look like this right?

        def profile(conn = %{method: "GET"}, params) do
          # ...
        end

        def profile(conn = %{method: "POST"}, %{"user" => user_params) do
          # ...
        end

This would be in a case where your router looks like:

        get "/profile", UserController, :profile, as: :user
        post "/profile", UserController, :profile, as: :user

That's what I'm doing in my code base at the moment. Mainly thanks to Changelog open sourcing their platform, and you can see that pattern being used here: [https://github.com/thechangelog/changelog.com/blob/f9b0a7587...](https://github.com/thechangelog/changelog.com/blob/f9b0a758746f2cec10781b77eb0541cce765e054/lib/changelog_web/controllers/person_controller.ex#L90)

The above seems like the natural way to do it with Phoenix once you get a hang of pattern matching.

<comment><USER21> Yep, that's the way!

</comment></comment></comment></comment><comment><USER22> Presumably a SameSite=Lax cookie wouldn't have helped here, because

> "Safe" HTTP methods include "GET", "HEAD", "OPTIONS", and "TRACE", as > defined in Section 4.2.1 of [RFC7231].

But I wonder if GitHub could issue a separate SameSite=Strict cookie here as a defense in depth measure to cause the initial part of the PoC (HEAD request with credentials: include) to fail?

</comment><comment><USER14> Wow, why would the browser allow HEAD request in the first place w/o explicit confirmation from github server with CORS headers. This is very strange.

It also reminded me of why "match" was removed in the first place - [http://homakov.blogspot.com/2012/04/whitelist-your-routes- ma...](http://homakov.blogspot.com/2012/04/whitelist-your-routes-match-is- evil.html) \- you could route any POST request via GET therefore bypassing CSRF checks still getting inside the controller.

<comment><USER22> Why's it strange? In a properly designed application, it shouldn't do anything any different to the no-cors requests you can already achieve with e.g. an <img> element. HEAD, GET et al are all supposed to be "safe methods" per the spec.

<comment><USER14> You can't achieve a HEAD request with <img> elements, can you?

In a rails env the only way to upgrade to non-standard methods (PATCH, PUT etc) were always to supply _method and pass CSRF protection first.

This trick is clearly a bypass because it instructs browser to make a HEAD request, something it never did before. If you try to make other non-standard request you will get this error:

Uncaught (in promise) TypeError: Failed to execute 'fetch' on 'Window': 'PATCH' is unsupported in no-cors mode.

<comment><USER22> No, but you can achieve a GET which is also a "safe request method" per RFC7231. _All_ of these requests should be idempotent.

I'm not a fan of the hacks that exist to allow HTML forms to emulate other request methods. They're off by default in ASP.NET Core MVC, which is good IMO.

<comment><USER14> "should". Real apps are much more complicated than what they are in theory. In theory all CSRF protections must be based on an auth token, in practice they routinely rely on the method or referrer.

For this reason browser upgrades must be extremely careful to not break older protections.

That's why you cannot set your own referer (which is supposed to mean nothing), you cannot supply Content-type: application/json unless instructed by CORS preflight, etc etc.

Here, the backwards compatibility was clearly broken. It was never possible to send HEAD few years ago with regular XHR or <img>s. Web standards owe $25k back to github. Yes, github's routing was flawed but it wasn't exploitable until browsers allowed HEAD in fetch() no-cors mode.

<comment><USER22> >For this reason browser upgrades must be extremely careful to not break older protections.

It's too late for that though. We've already had e.g. Referrer-Policy come and break existing CSRF protection which treated an empty/missing Referer header as 'safe'. You're right that bad assumptions are going to made all over the place in the real world, but browser vendors shouldn't shoulder all of that responsibility.

You have to draw the line somewhere, right?

<comment><USER14> I worked a lot with client side bugs earlier, and clearly this trick has crossed this line. Browsers cannot say in one scenario that "content- type:application/json" are unsafe and in another allow completely unnecessary HEAD method that nobody ever used to be sent with 3rd party JS page.

Seriously who needs HEAD in their client side development? It's purely a technical method w/o clear use pattern. It's not even valid in <form method=""> so why would it be valid in fetch()? Oh and PATCH/PUT are still invalid in fetch().

We're lucky that this code pattern is only common in Rails. Otherwise it could open a whole class of bugs.

<comment><USER23> Wait, why is it useless? At minimum there is the example cited in the article of checking file length without having to download the actual file, but more generally, if headers have any value, and they must since they exist, why can't you imagine situations where you just want to see the headers without downloading a giant body?

<comment><USER14> For a client side code running on 3rd party page, there is no use case to let it send HEAD to you. Only GET and POST should be allowed by default, other methods only through CORS preflight. That was the premise of CORS. They broke it.

<comment><USER24> If GET is considered safe, HEAD must be as well. It's complete nonsense to claim HEAD is dangerous while GET is safe. Semantically, HEAD is literally just "do a GET but don't give me the body", so it should have the exact same server-side behavior as GET, except with the available optimization of not generating the response body (since it will be discarded).

The only reason this bug existed is because Rails treated HEAD as GET in some cases but not others. The sensible behavior here would be, in the Router, if the route didn't explicitly specify :head then it should convert the request to GET before handing it to the route. A route that wants to explicitly support HEAD (e.g. by skipping the response body) should explicitly specify :head on the route.

But the existence of this rails bug says nothing at all about the security of HEAD in general.

<comment><USER14> > The only reason this bug existed is because Rails treated HEAD as GET in > some cases but not others

It is the main reason, yes, but not the only reason. If it wasn't possible to craft cross-site HEAD (which devs use in real life like.. never?) the bug would stop right there.

With an extra method if-else logic turned faulty. I would argue 90% web devs don't even remember of HEAD and what it means. Reasonably so, because it's rather never used.

IMO order of blame: 1) rails 2) browsers 3) github code relying on .get?

<comment><USER24> > _If it wasn 't possible to craft cross-site HEAD (which devs use in real > life like.. never?) the bug would stop right there._

You're still focusing on the wrong thing. HEAD requests are largely obsolete at this point, yes, but that doesn't mean browsers would be right in changing the semantics of a HEAD request. The problem here isn't that browsers use the same security model for HEAD that they do for GET (as that's absolutely correctly) but that Rails decided to only partially support HEAD. Another simple fix for this bug would have been for Rails to simply give no special behavior to HEAD at all, and therefore any route that doesn't explicitly specify :head wouldn't be used for a HEAD request. The fact that Rails decided to deliver HEAD requests to a GET route without changing the request to actually appear as a GET request is a serious design mistake, and not one that browsers are responsible for.

<comment><USER14> Ok I can agree with that. This must definitely be discussed in rails/rails and fixed by design. I probably overplayed my concern with browsers.

</comment></comment></comment></comment></comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER25> This is the reason I don't use else much and use explicitly matching.

`if/else` is pretty much only use for boolean with exact 2 states.

Not like this issue but the use of `if/else` can lead to thing like:

      loop do
        # do thing and increase i
        break if i == 10
      end

If i go from 9 to 11, we never exit the loop.

In language like Erlang, when you write `if/else` it force you to handle all the cases with pattern matching which I think may help reduce amount of unhandled state check error.

<comment><USER12> Defensive code would have you write 'break if i >= 10'.

</comment></comment><comment><USER3> What is it about OAuth's design that provides such an incredibly diverse number of failure modes?

I feel like it's the most common critical vulnerability that crops up on every major site in one form or another.

<comment><USER26> "What is it about OAuth's design that provides such an incredibly diverse number of failure modes?"

A solid lack of understanding at all layers of the OSI model, especially the first three.

<comment><USER27> Did you mean the top 3 (Session-Application) not first 3 (Physical-Network)? This is deliciously ironic if not.

</comment></comment></comment><comment><USER28> And this folks is why you should always use separate sessions for different websites, and remember to log out of sites you aren't using.

</comment><comment><USER29> very cool, thanks for sharing. i'm a junior dev who recently implemented oauth in a rails app and this is instructional. thanks

</comment><comment><USER30> Ohhh, so that's how my github account was stolen.

One day I received an email saying that a third party app was added to my github account, they in an instant it says my password has been changed, key was stripped, etc.

<comment><USER22> If the folks at GitHub are half-decent engineers (and everything I've seen suggests they know what they're doing), they'll have request logs that would make it very very obvious someone had done this.

Would advise sending a support request in, if you think this happened to you.</comment></comment>


Python as an Alternative to Lisp or Java, Peter Norvig revisited - <AUTHOR> http://dr-josiah.blogspot.com/2010/12/python-as-alternative-to-lisp-or-java.html <comment><USER4> To me, it's not interesting at all to ask who can write a 100-1,000 line program faster in which language. The real interesting question is how efficient developers are once you're talking about a 100,000 - 1,000,000 line program that has been in development for years. Solving small problems is relatively easy.

<comment><USER5> Even at that scale, python code readability trumps over almost every other language out there. Compulsory indentation and there's only one way to do this mentality keeps everyone on the same page.

So, yeah, that's probably why Google uses python extensively.

<comment><USER6> I work at Google and we don't have that much Python in our codebase. There are some outlying cases that use it (like the YouTube front end), and it _is_ one of our official languages, but the vast majority of Google code is C++, Java, and JavaScript, with Python a trailing 4th place. Python is just not that suitable for large-scale software development.

Readability means different things at different scales. Reading Python "in the small" is easy; it's looks like pseudocode. Once you start writing larger programs, between the 5k and 10k mark, the looseness of Python starts to become a burden. It can be very difficult to look at a piece of Python code in a large project and know exactly what it does. Dynamic typing means that a whole class of serious programming errors go unnoticed until runtime - <USER2> often only for a specific, uncommon input.

("Compulsory indentation" ?! Whomever works on a large project with others and doesn't format their code to the standard of the project should be taken out and shot. I'm only half-joking. Indentation has almost nothing to do with readability, though. It's just common sense.)

(I'm surprised to hear you say "there's only one way to do this" with regard to Python, as in my experience there are always several ways of doing anything, and it's not uncommon to see different/competing approaches used in a single project.)

I'm biased, but Go is a great choice for large-scale software development. It has the brevity of a scripting language, but being statically typed and compiled Go can be more reliable and efficient. It's also smaller and more consistent than any mainstream language. Because of this, you can typically look at a piece of Go code from any project and understand what's going on. This is because it's difficult to abuse Go in the same way you see done in the other four languages I've mentioned, and that is truly valuable at scale.

<comment><USER7> "Indentation has almost nothing to do with readability, though. It's just common sense."

Um...it has EVERYTHING to do with readability. That is WHY it is just common sense.

<comment><USER8> Wonderfully indented code is not always readable. Readable code is always indented well.

</comment></comment></comment></comment></comment><comment><USER9> HN comment by Norvig on Lisp vs. Python <http://news.ycombinator.com/item?id=1803815>

</comment><comment><USER10> It is surprising that in 2010 we are still talking about efficiency in terms of lines of code whether the absolute number to express a problem or in the speed that these lines can be created. I realise that this is a proxy for the ability of a language to succinctly express a problem however it ignores all the major factors that determine how effective a piece of code is over its lifetime.

The ability of language X to solve a problem depends on:

1\. The expressiveness of the syntax to capture algorithmic complexity. 2\. The availability of tools to support the creation of the code. 3\. The ability of the typical programmer, conversant in the language, to write the code. 4\. The costs involved in maintaining the code over its lifetime.

Rendering all these dimensions into a single metric seems simplistic at best, undermining the argument as to which set of tools and technologies are deserving of more attention and ultimately plays into the hands of the people who wish to render programmers and programming into pure commodities.

</comment><comment><USER11> I wonder if another, equally valid, way of looking at the lines of code vs time is that if two programmers using different languages both complete the task in roughly the same amount of time, but one uses only half the total lines of code... that implies _not_ that that programmer is better, but that each of their lines of code took roughly twice as long to produce.

One of the things I used to do when working in large teams was wander around and look to see if anyone was having trouble debugging. Sometimes you'd find someone who'd been stuck on a bug for several days. So what I'd do was I'd sit down with them, and start putting in all the 'fluff' like indenting their code, splitting lines with multiple variable declarations each onto their own line etc. Essentially putting in all the 'long cuts' that they'd taken 'short cuts' around in order to 'speed up' the programming.

Often either they or I would see the problem immediately.

These days of course there are tools that do the auto-formatting, but I still try to optimise for readability, simplicity and elegance in my code.

Back to the lines of code as a metric issue (tm) in that scenario where it takes 2x as long to write a line in language X, and that line does twice as much, it is probably at least twice as complex as the 'more verbose' language... and I think this implies that it will be harder to debug and maintain later on. So arbitrarily complex languages are optimal for some internet 'toss off' (one off, toss away) competition, but not necessarily optimal for long term efforts.

Some of these languages that allow you to redefine the language itself on the fly allow you to do 'cool stuff' (tm) but tend to attract people who think they are much cleverer than they actually are. I think it is a regional variation, but all the Ruby fans in my city scare me. The thought of what would happen if I'd spent days or weeks on a bug only to find out it was caused by someone else 'tweaking' one of the core classes and not bothering to tell anyone else... _twitch_

<comment><USER12> I question your assumption that if something is done in 1/2 the lines of code then each line of code is twice as complex. You're equivocating on "complex". Each line may be "more complex" in the sense "does more", but not necessarily more complex as in "harder to understand" (and therefore more prone to bugs).

Code in a more productive (i.e. higher level) language is concise because it __hides __extra complexity you don't need to think about at the time, and is therefore __simpler __, not more complex (in the second sense).

<comment><AUTHOR> A perfect example of this is setting up iteration in Python vs. C++.

In Python: for obj in seq: ...

In C++: std::base_class<template_type>::iterator obj; for (obj=seq.begin(); obj != seq.end(); seq++) {...}

The reduction in lines for Python doesn't make it more complicated, it makes it cleaner and easier to express ideas.

</comment></comment></comment><comment><USER13> Norvig:

 _It took me about 2 hours (compared to a range of 2 to 8.5 hours for the other Lisp programmers in the study, 3 to 25 for C/C++ and 4 to 63 for Java) and I ended up with 45 non-comment non-blank lines (compared with a range of 51 to 182 for Lisp, and 107 to 614 for the other languages)._

Seems like the programmer, not the language, is the biggest determinant. If you have the Java programmer who wrote it in 4 hours, and the Lisp programmer who wrote it in 8.5 hours, you're better off writing it in Java!

If you want to write concise programs quickly, using the same language Peter Norvig uses might help, but being as good as Peter Norvig helps more.

<comment> wh-uws Yeah I really believe this is mostly about the programmer.

It takes a different type of programmer to even want to venture to learn lisp in the first place.

</comment></comment><comment><USER14> This is the kind of article that should more frequently come to the attention of enterprise management. There really is an inverse relationship between the expressiveness of a language and the number of bugs created. (That is, I am taking at face value the studies which claim a more or less linear relationship between lines of code and bugs, regardless of language.)

<comment><USER15> I have heard this before many times, and I tried to find a study that would defend that assertion one weekend and failed miserably. If you have a citation for one of those studies I would be in your debt.

<comment><USER14> Found this [http://amartester.blogspot.com/2007/04/bugs-per-lines-of- cod...](http://amartester.blogspot.com/2007/04/bugs-per-lines-of-code.html). Thanks for calling me on that, I was just repeating the popular assertion.

</comment></comment></comment><comment><USER16> I wonder how short a good Java programmer's solution would be compared to the J Random Java Programmers used in the study so long ago.

<comment><AUTHOR> I also wondered that.

<comment><USER17> Seven lines, of course. It's _obviously_ in the standard library.

<comment><USER18> That is why these SLOC measurements are stupid. If you find the right library or module, perhaps from CPAN, that can change everything.

</comment></comment></comment></comment><comment><USER19> For the most EXTREME algorithmic compression of information to number of lines in Python (with few to 0 intermediate values stored), I've found it hard to beat using nested function definitions with abstracted shared logic called by running the vars() builtin as the parameter list. Basically ship the current scope elsewhere to finish processing to ensure no logic is repeated.

I tend to not use separate URL mappers in controllers but have nested functions that define both logic and layout simultaneously. (Basically a tree structure of function definitions where the ending subpage elements are leaf nodes, and nodes render wrapper base templates on post traversal unless it was an ajax request). I can post some code if this doesn't make sense. Obviously not defining new variables nor using classes is extremely unpythonic and could pose difficulties for group work... minimum number of lines while fun isn't everything!

</comment><comment><USER20> This version clocked in at 1:35, gave up on the "professional code" requirement though :) Need to sleep.

<https://gist.github.com/752455>

</comment><comment><USER21> Anyone try the puzzle? The following does not occur in the sample output, but I don't understand why:

/78698/37395746288: Koch 8 Sud Hab Tirol

What did I miss in the rules?

<comment><USER22> Violates this requirement: "If and only if at a particular point no word at all from the dictionary can be inserted, a single digit from the phone number can be copied to the encoding instead."

The number you mention allows to get into the branch with the 'Koch o"d' - <USER3> no digit can be selected.

<comment><USER21> Aha! Yep, that was the problem. Thanks!

(I was reading the requirement as "If at a particular point no sequence of words from the dictionary can be inserted to complete the number, a single digit can be inserted" -- which still makes a lot more sense to me than the actual requirement!)

Sadly, no programming language could have helped me with this bug. :)

<https://gist.github.com/752506>

<comment><AUTHOR> Don't feel bad, I hit the same bug myself. :)

</comment></comment></comment></comment><comment><USER23> I saw Martin Odersky use this exact problem in a talk he was giving about Scala. It came out to about 10 lines.

</comment><comment><USER24> <http://p.hagelb.org/csb.gif>

<comment><USER25> Hacker News is not 4chan, and as such, do not reply "Cool Story Bro", unless you are replying to your brother that you thought the story he gave you was popular.

<comment><USER26> I upvoted you and downvoted him because I really don't want HN to degrade into Reddit/Digg/4Chan/etc. I come here specifically because it's _not_ one of those, and has a good signal-to-noise ratio (e.g. relevant conversations not overrun by silly memes)

<comment><USER27> What about Metafilter?</comment></comment></comment></comment>