Cache eviction: when are randomized algorithms better than LRU? (2014) - <AUTHOR> http://danluu.com/2choices-eviction/ <comment><USER2> Related: the author, Dan Luu has, IMHO, one of the best IT-related Twitter feeds out there: [https://twitter.com/danluu](https://twitter.com/danluu)

Highly recommended.

</comment><comment><USER3> One thing I've seen is that a weighted LRU is usually slightly better for unpredictable workloads. i.e. it will never evict high use cache data when there's a flurry of one-off traffic that would normally start evicting a normal LRU cache, and even a 2 random LRU scheme.

This is particularly relevant for databases and keeping rows in memory.

The algorithm is something like "add two weight when an item is used, and decay one from every item every second, evict items under pressure from the lowest weight to the highest."

<comment><USER4> Well, once you go down this path you gotta consider ARC: [https://en.wikipedia.org/wiki/Adaptive_replacement_cache](https://en.wikipedia.org/wiki/Adaptive_replacement_cache) as I believe it is designed to be scan-resistant.

<comment><USER5> Which is, unfortunately, patented: [http://patft1.uspto.gov/netacgi/nph- Parser?Sect1=PTO1&Sect2=...](http://patft1.uspto.gov/netacgi/nph- Parser?Sect1=PTO1&Sect2=HITOFF&d=PALL&p=1&u=%2Fnetahtml%2FPTO%2Fsrchnum.htm&r=1&f=G&l=50&s1=6996676.PN.&OS=PN/6996676&RS=PN/6996676).

<comment><USER6> Hmm given that patents span for 20 years, and that's essentially forever in computer world, once this patent expires it probably will be worthless.

In a world where advances are built on top of other advancements, patents just stifle innovation.

<comment><USER7> And yet innovation proceeds at a pace unmatched in history, and is so commonplace it gets dismissed as not counting when it's not a revolutionary breakthrough.

<comment><USER6> When you're referring to innovation, you're talking about everything. I'm referring to software.

<comment><USER8> It's relatively impolite to tell someone what they meant

</comment></comment></comment></comment></comment></comment></comment><comment><USER9> Are there any languages that allow you to give the compiler a hint that you're about to grind over a gigantic dataset so don't bother to cache any of this data because it won't be accessed again for a long time? It seems like it could be helpful in keeping a big crunch from obliterating the cache constantly. You might also be able to apply other optimizations, like preloading the next data blocks so they're ready when the CPU rolls around. Maybe compilers already do this behind the scenes?

<comment><USER10> Don't. Yes, there are instructions for this. No, don't use them, unless you really exactly know what you are doing and optimizing towards a specific, single µarch _only_ , otherwise they will invariably hurt performance, not improve it.

Similarly explicit prefetching usually does not improve performance, but reduces it.

(Non-temporal stores are quite a good example here, since a game engine used them in a few spots until recently, causing not only worse performance on Intel chips, but also heavily deteriorated performance on AMD's Zen µarch. Removing them improved performance for all chips across the bank. Ouch!)

<comment><USER11> Links, examples, tutorials?

</comment></comment></comment><comment><USER12> This 2 random cache scheme reminds me a lot of the 2 random load balancing scheme laid out in "The Power of Two Choices in Randomized Load Balancing" [https://www.eecs.harvard.edu/~michaelm/postscripts/mythesis....](https://www.eecs.harvard.edu/~michaelm/postscripts/mythesis.pdf) Which shows an exponential improvement in choosing the less loaded of two randomly chosen servers over just random.

<comment><USER13> It is indirectly referenced near the bottom of the page, with a pointer to [http://brooker.co.za/blog/2012/01/17/two- random.html](http://brooker.co.za/blog/2012/01/17/two-random.html), which references [http://www.eecs.harvard.edu/~michaelm/postscripts/handbook20...](http://www.eecs.harvard.edu/~michaelm/postscripts/handbook2001.pdf)

</comment></comment><comment><USER14> The "2 random choices" idea also shows up as a good idea in other settings, such as load balancing for hashing. I wrote a writeup[1], but if you google "power of two random choices" you'll see a lot of literature on it.

[1]: [https://jeremykun.com/2015/12/28/load-balancing-and-the- powe...](https://jeremykun.com/2015/12/28/load-balancing-and-the-power-of- hashing/)

</comment><comment><USER15> Redis supports LRU and random eviction: [https://support.redislabs.com/hc/en- us/articles/203290657-Wh...](https://support.redislabs.com/hc/en- us/articles/203290657-What-eviction-policies-do-you-support-)

I wonder if it would be worth adding a k-random eviction strategy, for a balance between the two.

<comment><USER16> Hello, now Redis (4.0, still in release candidate) supports LFU (Least Frequently Used) which should work better in most cases since LRU also is also just a way to approximate LFU, since the most frequently used items are often the last recently used ones.

<comment><USER17> _[...] since LRU also is also just a way to approximate LFU, since the most frequently used items are often the last recently used ones._

That is not really true. LRU and LFU favor different items, LRU ones used frequently in the short term, LFU ones used frequently in the long term. Only under special circumstances does one approximate the other, for example if your cache is large enough that LRU does not evict the most frequently used items when many less frequently used items are placed in the cache before the most frequently used items are accessed again, then LRU approximates LFU.

<comment><USER16> What I mean is that, the most frequently used objects, if accessed roughly with an even period of time, tend to be also the least frequently used objects, so if the accesses are very even LFU and LRU tend to be similar. For uneven access patterns, they are different, but usually LRU is used because access patterns are even so that it approximates LFU, since what we want to have in cache is, without other application-specific clues, the objects that we use more often. Knowing _exactly_ the access pattern one can use an application-assisted strategy which is optimal, but without clues LRU adapts well to different scenarios while LRU may fail in a catastrophic fashion.

Also note that your idea of LFU (in this context), from what you write, is perhaps one that does not adapt over time. Redis LFU employs a decay strategy so that the recent frequency is computed, not the whole-lifetime frequency of access, so even short lived items accessed very frequently for some time, will do well and will not get easily evicted.

Full story: [http://antirez.com/news/109](http://antirez.com/news/109)

<comment><USER17> That is what I meant, under specific assumptions about the access pattern they can show similar behavior. Classical LFU tracking the absolute frequency of items will keep items that are used frequently in absolute terms but infrequently in terms of the instantaneous frequency in the cache while LRU will evict such items in favor of items with high instantaneous frequency. Those two algorithms are in some sense two extremes, LRU cares about what is most frequently used right now, LFU cares about what is most frequently used over the entire lifetime of the cache.

The LFU variant you describe in the linked article is somewhere in the middle, it tracks the absolute frequency of access just like classical LRU but then it also decays this frequency and therefore turns it into something like a weighted and averaged relative frequency. But it is, at least for me, hard to tell what exactly the algorithm tracks, how the accesses are wighted over time and therefore were exactly this falls on the spectrum between LRU and classical LFU.

Algorithms like ARC and CAR also try to strike a balance between LRU and LFU with the difference that they adaptively control where on the spectrum to operate.

<comment><USER16> Yes, there is a tuning problem indeed. I made two parameters user-tunable (the decay and the logarithm factor of the Morris counter), but tuning needs some expertise. I've severe limitations on the number of bits I can use per object, but depending on the user feedbacks I may try some auto-adaptive approach as well in the future.

<comment><USER18> I used hill climbing to tune TinyLFU. A larger admission window improves recency-biased workloads, while a smaller improves for frequency. By sampling the hit rate and making an initial adjustment, it can determine when to change directions and hone in on the best configuration. Other than a small warm-up penalty, it quickly optimizes itself.

</comment></comment></comment></comment></comment></comment></comment><comment><USER17> _[...] choosing the least recently used (LRU) is an obvious choice, since you're more likely to use something if you've used it recently._

There are many other cache replacement policies [1] and they can outperform LRU especially if the quoted assumption is not true. It is for example quite common to have two types of data, one is frequently reused over very long periods, the other is reused over short periods after the first use. In those cases a more complex policy like ARC or CAR can provide noticeable improvements.

[1] [https://en.wikipedia.org/wiki/Cache_replacement_policies](https://en.wikipedia.org/wiki/Cache_replacement_policies)

<comment><USER19> > There are many other cache replacement policies [1] and they can outperform > LRU especially

The article is about CPU caches so speed and memory usage are very critical.

One of the main benefit of LRU is that it only needs one extra bit per cache line.

<comment><USER20> > One of the main benefit of LRU is that it only needs one extra bit per cache > line.

This might be well known, but why's that? I've recently seen a Go implementation of LRU and it uses a lot of memory. Maybe this would allow us to save some of that in a better implementation.

<comment><USER17> Requiring only a single bit is only true for a two-way set associative cache, i.e. the content stored at every memory address may only be cached in two different cache slots. In this case you can simply flag the other corresponding cache entry you did not access as least recently uses every time you access a cache entry.

The implementation in software was probably fully associative, i.e. every item can be cached in every slot. This requires a lot more memory and it is the same for caches in processors, they require more additional bits and logic the more freedom they have where to cache the content of every address.

To be more precise, you have to keep track of the order all cache entries were accessed which requires at least about n * log(n) bits unless you only implicitly store the access order by using something like move to front.

</comment></comment></comment></comment><comment><USER21> LRU is predicated on locality of reference.

Ideally we could peer into a crystal ball and know which items are going to be accessed in the near future and keep those in the cache at all costs. Since we don't know that, we use a predictor based on past behavior. If past behavior is random, then prediction is for shit. So we assume that behavior has locality: something referenced recently is more likely to be referenced again than something not referenced recently. Based on that guess, we sort things from least recently used to most recently (or approximately sort, using aging tricks to avoid actually sorting), and boot out the least recently used entries.

If accesses are completely random, then the LRU selection is pure overhead. Or worse; some patterns, like repeated sequential accesses of something large through a small cache, are anti-locality. If we are accessing a big buffer in a circle, then the next thing we are accessing at all times is _precisely_ the least-recently used item that LRU wants to boot out.

For situations like that, caching mechanisms sometimes support some API for providing a hint. "These memory locations are going to be needed soon". "This memory mapped file is being sequentially accessed". And such.

</comment><comment><USER12> Another characteristic of the data which would make random particularly bad is if reloading/recomputing the most popular items took significantly longer than reloading unpopular items. This could be the case for instance if item data size grew in proportion to popularity.

</comment><comment><USER22> Dumb question, what is "2-random"?

<comment><USER23> From the article:

...on real workloads, random tends to do worse than other algorithms. But what if we take two random choices and just use LRU between those two choices? __

" 2-random" is his short hand for the above scenario.

[edit: formatting, I have no idea how to signify a quote; I don't want preformatted because it makes a scroll box.]

<comment><USER24> On HN, typically a quote is done like this:

> This is a quote. It won't become a scroll box, no matter how long it gets. > It will just wrap to the next line. True, the next line won't begin with a > ">" character, but the convention is that the whole paragraph is a quote if > the first line begins with a ">".

</comment></comment></comment><comment><USER25> Often you can get away with dumping the whole cache when it fills up and starting fresh.

<comment><USER26> that's a horrible pattern. As soon as you go 1 bit over your cache size in a hot loop you'll have a 100% miss rate. (assuming each element is loaded once in the hot loop).

<comment><USER27> You don't use this pattern while looping. You use it while memoizing results that you don't want to compute again.

Here's an example, in the Python package wordfreq [1]. When you look up word frequencies, there's some normalization it has to do to your text. Some words are very common, and it would be silly to normalize them repeatedly. So frequency lookups are cached.

The cache dictionary has a maximum size of 100,000, so that exceptional or malicious cases don't use up all your memory. It is extremely rare for text to contain 100,000 distinct words, but if that happens, the cache gets full and the entire thing is dropped. It will quickly be re-populated with common words, of course.

Yes, you can make this perform horribly by looking up frequencies of ["zero", "one", "two", "three", "four", ..., "one hundred thousand"] in a loop. That's not realistic data.

Do you actually have a suggestion for how to do this faster? We benchmarked this against other cache strategies (with smaller cache sizes so it would drop sometimes) on realistic data. It's much faster than Python's LRU decorator, for example.

[1] [https://github.com/LuminosoInsight/wordfreq/blob/master/word...](https://github.com/LuminosoInsight/wordfreq/blob/master/wordfreq/__init__.py)

</comment></comment></comment><comment><USER28> When the cost of retrieving an item from your slower storage is pretty much the same for every item, may it be old or new, small or big, popular or not.

</comment><comment><USER29> Ajax made predictive (random)prefetching mainstream .its only natural that random eviction algorithm are coming along . when you pick one end of stick you pick another too</comment>


Apple Watch gold plating for $399 with a 3-day turnaround - <AUTHOR> http://www.watchplate.com/#our-story-1-alex

<comment><USER2> Or, much cheaper and a 4-hour turnaround: [https://youtu.be/MMF9I_9DAcs](https://youtu.be/MMF9I_9DAcs).

<comment><USER3> I was really hoping for a really nerdy video explaining how to electroplate an Apple Watch. Just masking off and spray painting the phone was disappointing.

</comment></comment><comment><USER4> Whilst there's nothing _really_ wrong with gold plating an Apple Watch, to me it feels on par with wearing a fake Rolex.

The difference is, whilst a Rolex is reasonably affordable, the Edition is clearly out of the price range of most people - so wearing something like this will be _so_ obvious.

However, I would love to see some companies coming up with custom Apple watches. Not to make them look more expensive, just to make them look different. For the first time, I might actually buy a customised Apple product if it weren't too expensive (maybe a wooden Apple watch case might look nice, for example.) We'll definitely see this with custom bands (really looking forward to that) but it'd be cool to see new watch bodies too.

As an aside, whilst I understand (and mostly approve of) the reasoning behind Edition, it's a shame that the only gold Apple watch is so expensive. I wish that Apple had created a gold coloured watch in addition to the solid gold Edition - similar to how many watch companies produce the same watch in stainless steel and white gold or platinum. Or how watch companies sometimes put a diamond on the back of the watch but none on the front.

<comment><USER5> How much do you think Rolex's cost? Submariner, Explorer II, and Datejust (very classic go-to Rolex models) are about $7000-$8000. Daytona chronographs start at around $10,000. And that's just for stainless steel. Gold Rolex watches are much, much more.

Apple Watch Edition is actually one of the cheapest solid gold watches out there

<comment><USER4> I think you misread my comment. I wasn't comparing Edition with a gold Rolex, just a low-end (perhaps second hand) stainless steel Explorer / AirKing / etc. If you see someone wearing a fake stainless steel Rolex, there's a genuine possibility that it's real (assuming you can't tell it's fake). But with Edition, the chance of it being real is pretty low. Thus, wearing a gold plated Apple Watch is pretty obvious.

I'm well aware of the costs of a Rolex (and most watch brands, I'm a watch enthusiast). You can pick up a Rolex for a few thousand pounds in Britain. New, they start at around £4000ish. Gold watches in general cost a lot more, especially if they have a gold link bracelet, and you're right that Edition is priced fairly competitively.

A stainless steel Rolex is, whilst quite a bit of money, affordable if you decide that you want it. I don't live in a major city and yet I'll still see a few on the wrists of people if I take a trip around town. Edition, however, would be quite a sighting - similar (in terms of required wealth), in my opinion, to seeing a complicated Patek on a wrist. (Whilst the prices are different, I'm saying this because of the upgrade issue, i.e. a £100K Patek will last many lifetimes, a gold Edition will be useless in less than 5 years).

<comment><USER6> I own a stainless Datejust (Rolex). The MetaWatch people gave me several (10+) of various models of their watches. I wear neither, and have no plans on an Apple Watch.

</comment></comment></comment></comment><comment><USER7> If you're merely well off you too can pretend to be an obnoxiously rich douchebag!

<comment><USER8> When did using a different color metal become 'obnoxious'?

</comment></comment><comment><USER9> easy business! it reminds me fake rolex thing ...

</comment><comment><USER10> It's a nice offer but I wonder how people should trust them with their watches?

<comment><USER11> I think it's a clause in the universal customer-business law that says "I want to pay what you're asking just as much as you want to give me the thing I'm paying for. My purchase and good will is more valuable to you than a series of thefts."

That's not written down anywhere except the over-arching idiom, metaphor, very ground of the relationship. Is the kind of relationship that can slippery slide into parasitism. And therefor I think extant in many sentient species. Great apes, many primates, birds, cephelopods maybe even.

I think it's a reflection of a few basic strategy for living in the world, in a world with limited resources, trust and exchange.

</comment></comment><comment><USER12> My bold prediction about the whole Apple Watch phenomena:

 __It will be a big bust.__ After the initial hype, not many adults would want to wear it.

This might upset some people (Apple fans?). But now, let's build a mental image together: one day, in the middle of a meeting at your work place, many of your colleagues rest their hands on the conference table (either using a tablet/phone/laptop, or holding papers). You raise your head and glance over the whole room, and you see there are so many Apple watches out there. They look the same, blink the same way, sound the same. The square-ish shape becomes kind of tiring and stupid, simply because you've seem them everywhere. They are really out there. A funny idea pops up in your mind: is this a robotic, dull and weird picture or what?

Watches are not like mobile phones, in terms of personal touches. Adults use phones mostly for their practical functions, and phones can be kept out of sight. Watches are different. Nowadays they are mostly for images/styles/personalities/fun, so, do you want to wear the same watch as everybody else and appear so average?

<comment><USER13> I've been wearing watch for its _utility_ for more than a decade. My watch (Casio ProTrek PRW-3000-1) has compass, altimeter, world time, sunrset times, alarms and so on. This watch is extremely robust in bad weather or even under water. It self-charges itself (it doesn't even has any external way to charge it). Sure, I've smartphone usually with me but ability to look up time in split second with a slight turn of wrist is valuable. But the more important is all these tools and reliability that they are available to me in all kind of weather, places and without need to worry about charging it. Now let me also make it clear that I do question this way of life where time matters so much. However that's different discussion and until conclusion arrives, watch is pretty useful tool.

If I'd all these features available in Apple Watch then I would buy it in heart beat. I can imagine several apps that would be super useful. However price tag is way too high and it needs charging _every day_. I think Apple Watch isn't going to be smashing success right now but given their investment levels, they might continue produce next versions that gets better and better and hopefully cheaper. It's important to remember that iPhone 1 wasn't smashing success either when it first came out given it's price tag and less powerful batteries.

<comment><USER12> I totally believe that your watch have served you extremely well, but dare I say you are in a minority in term of _normal_ daily life usage of watches. I don't know about you, but weekends/hiking trip/gym are a small part of my waking time. These things ("bad weather", "under water", "to look up time in split second", "all kind of weather", etc.) are the least I am concerned with. Instead I am interested in dressing(including small personal items) with a little personal touch, a little bit different. If so many people around you wear a Casio ProTrek PRW-3000-1, that's a silly situation, isn't it?

I feel the functions of watches you mentioned can be easily performed by a mid-range phone, and can be done better with a phone in terms of configurations/flexibilities/features with a few apps here and there. So I think with the prevalence of mobile phone, people put less and less emphasis on utilities when shopping and wearing a watch.

My silly prediction is not about doubting Apple watch's dazzling new utilities. It's about people's need for individuality/differentiations/style, especially adults, they want and can often afford to wear different things than the next person in the office.</comment></comment></comment>


Red states love Pinterest, blue states love Macs - <AUTHOR> http://engineering.monetate.com/2012/11/02/red-states-pinterest-blue-states-macs/ <comment><USER2> Super interesting. A few of those r-squareds are really high.

It'd be interesting to see if there's any products for which state-level usage predicts voting for Obama but individual-level usage does the opposite (as is true with wealth: <http://en.wikipedia.org/wiki/Ecological_fallacy>)

(Link to infographic is broken for me.)

</comment><comment><USER3> Cool analysis. I wonder to what extent the Mac/Obama correlation is explained by the fact that there aren't many Apple stores in Southern states and states with a lot of rural areas (which also happen to be Red states). If the opportunity to buy a Mac were equal I'm curious what how the correlation would change.

</comment><comment><USER4> _Red states love Pinterest, blue states love Macs_

\-- Poor states <want> stuff, rich states <own> Stuff

</comment><comment><USER5> Odd they singled out Pinterest in the headline since the percentage of any of the population on it is less than 1%. They could have just gone with "Red states love PCs and IE".</comment>


#iotashaming - <AUTHOR> https://sean-parent.stlab.cc/2019/01/04/iota.html <comment><USER2> Something seemingly glossed over in these discussions is whether calling it "iota()" is even that helpful.

The fact that a lot of software engineers -- engineers, not mathematicians! -- are unfamiliar with it at least points to an impedance mismatch between the standard and its intended users.

Calling this function "iota()" asks the reader/user to carry around with them a considerable history of CS/maths. If you're a physicist writing code for the LHC, sure. A game dev working on a AAA game? Possibly not. It's not a helpful term if you _don 't already know it_.

On the other hand, something like "std::sequence()" or "std::fill_range()" would be obvious to anyone, math degree or no.

<comment><USER3> It's just a word to learn, like lambda or for. At the end of the day you have to learn the semantics anyway; the label should be below your noise floor.

Musicians don't complain about having to use Italian words (e.g. fortissimo). Objecting to the foreign origin of iota (where the foreignness can be from its Greek origin or mathematical origin) is not worth the effort.

<comment><USER4> You can argue that "it's not so bad, just learn it", but the confusion from domain-specific jargon can really add up, from my experience, and I think more understandable terminology is almost always better. I think that if we want to design a welcoming system, we should try to make it intuitive and limit the number of weird words that you need to "just learn". Imagine if every CSS property was some greek letter instead of a descriptive name. Experts could still use it, sure, but it would be even more hostile to beginners.

Iota is particularly bad not just because it's hard to understand and remember, but because it's _easy to misunderstand_. In English, "iota" usually means "a little bit", so my initial guess (after re-reading it a few times to confirm it wasn't "itoa") was that it was a small float value, maybe some variant of epsilon.

Relatedly, I'm a fan of Elon Musk's email against acronyms at SpaceX: [https://gist.github.com/klaaspieter/12cd68f54bb71a3940eae5cd...](https://gist.github.com/klaaspieter/12cd68f54bb71a3940eae5cdd4ea1764)

</comment></comment></comment><comment><USER5> I don't understand the point this article is making, and don't agree with the sentiment either.

One should not feel embarrassed for not knowing something and then asking more in order to learn.

The correct term is not embarrassment, it is inquisitiveness - which must be encouraged and not shamed

<comment><USER6> > One should not feel embarrassed for not knowing something and then asking > more in order to learn.

Agreed: ignorance is not embarrassing. We're all ignorant about most things.

But it is embarrassing to say something like "why'd they name iota after a Greek letter? To seem smart?" As this article explains, there is a history there and it doesn't have anything to do with "seeming smart".

I didn't know the history of "iota". I'm only vaguely familiar with APL. And I've never listened to a Turning Award lecture. This makes me ignorant. But I also didn't criticize this feature from my place of ignorance because I'm aware of it. Had I done so, it would be embarrassing.

I _have_ criticized things from ignorance in the past, and it _was_ embarrassing.

</comment></comment><comment><USER7> If I understand correctly, _iota_ fills a data structure with a range of incrementing values.

...at the risk of sounding ignorant (perhaps I should be embarrassed?) why is _iota_ a clearer name than, say, _range_?

I do have to admit upfront that I've not spent overly much time on APL because in my day to day programming life, it's merely a historical curiosity that required a special keyboard.

Also, the author's assumption that a senior software developer should have studied a lecture from 1979 (that runs to 380ish pages) as a matter of course is, well, bloody odd. I've read Joe Armstrong's dissertation on Erlang from cover to cover because it was relevant to me. Can I now assert that any senior developer who has not should be embarrassed?

</comment><comment><USER8> _" I gave a lecture recently and a student stopped me. "I'm sorry, I don't know what a coroutine is. Can you explain?" More than happy to. That level of embarrassment.

If you have a better word, please provide it. But I believe embarrassment is the correct emotion to feel in response to one's own ignorance."_

"Embarrassment", for me, is definitely not the right word.

If I feel embarrassed, I do not ask. I will go quietly google it.

 _" Bothered"_ might be a better word?

<comment><USER9> I'm only going to feel embarrassment if it was some kind of prerequisite for the lecture, and like you I would probably just look it up afterwords (probably on YouTube).

I would admit to ignorance if I have never learned the subject and forgetfulness if I had learned it and forgot or just had a "brain fart" and temporarily forgot which would leave me annoyed at myself. I think this article misuses embarrassed.

</comment></comment><comment><USER10> From [https://en.cppreference.com/w/cpp/algorithm/iota](https://en.cppreference.com/w/cpp/algorithm/iota):

> The function is named after the integer function ⍳ from the programming > language APL.

The article spends a lot of time talking about how a lot of things leading up to std::iota are very important, but not very much time talking about why they're important.

</comment><comment><USER11> While I agree that the criticism "you're just trying to look smart" is misguided, it's a bit ironic that his response had the implication that "if I know this thing and you don't then you should be embarrassed [because I'm smarter/better than you]."

(I think that was the source of much of the objection to the comment, and the post makes no attempt to apologize for it, even if it was unintended.)

</comment><comment><USER12> iota is silly because it's non-descriptive even though there are so much more descriptive alternatives, such as simply naming it range. To me, iota falls under the same category as naming variables acig, gfeq, fqcl, aiwn, or any other permutation of of 4 letters that have nothing to do with what it does.

<comment><USER13> I also keep reading it as i-to-a which shows my own bias but doesn't help it being immediately understood.

<comment><USER14> Also, maybe shows your dyslexia.

</comment></comment></comment><comment><USER15> Entire articles and Twitter battles being fought over a simple _iota_ keyword.

Sometimes I think the software industry is deeply silly.

Actually, I think that a lot of the time.

</comment><comment><USER16> Is it just me who thought this was about the itoa C function?

</comment><comment><USER17> > By embarrassed I meant as when you are in a foreign country and you can't > remember the native words for please or thank you.

The reason why this is embarrassing is because it might imply a certain disrespect for the country you are visiting. But neither does a programming language and its community deserve the same level of respect as a country and its people, nor is the history of iota() comparable to knowing the word for thank you.

No visitor to England should ever feel embarrassed in any meaning of the word for not knowing why some food words have french origin and others don't. Nor should they need to apologise for stating that they find that confusing.

</comment><comment><USER18> While I don't really care what the history is, the name seems odd to me since I thought it was itoa() at first. It seems too similar to a common function (that nobody should use anymore).

</comment><comment><USER19> Being embarrassed isn't the same thing as telling someone they should be embarrassed.

</comment><comment><USER20> meanwhile, in crypto, a bullish trend is picking up speed: [https://coinmarketcap.com/currencies/iota/#charts](https://coinmarketcap.com/currencies/iota/#charts)

</comment><comment><USER21> New Testament: "until heaven and earth pass away, not an iota, not a dot, will pass from the Law" (Mt 5:18)

[https://en.cppreference.com/w/cpp/algorithm/iota](https://en.cppreference.com/w/cpp/algorithm/iota)

[https://superuser.com/questions/841439/excel-auto-fill-a- col...](https://superuser.com/questions/841439/excel-auto-fill-a-column-with- increment?lq=1)

<comment><USER22> My first context for iota was biblical, and I've used it as an expression my whole life (e.g., "Not one iota"). I was surprised to see it in STL, but after learning its history, I've been happy to use it in my code without mocking it.</comment></comment>


Uber Says Customers Give Up Right to Sue When They Agree to Use Service - <AUTHOR> http://gadgets.ndtv.com/apps/news/uber-says-customers-give-up-right-to-sue-when-they-agree-to-use-service-1673452 <comment><USER2> IANAL, but I think Reddit has a good explanation of the situation[1].

> TL;DR Uber isn't truly arguing they can't be sued with a straight face, > they're trying to trigger conditions that would send the case to arbitration > instead of trial because that's better for them.

[1] [https://www.reddit.com/r/technology/comments/61q0n9/uber_say...](https://www.reddit.com/r/technology/comments/61q0n9/uber_says_customers_give_up_right_to_sue_when/dfgiq2a/)</comment>


Rust 1.38.0 - mark-simulacrum https://blog.rust-lang.org/2019/09/26/Rust-1.38.0.html <comment><AUTHOR> Here is an example of the impact of pipelined compilation:

[https://gistpreview.github.io/?b19f31756dc76a050cf4fe55f348a...](https://gistpreview.github.io/?b19f31756dc76a050cf4fe55f348a9d2)

In the blue/purple graph, only the blue typechecking portion of a dependency's build needs to complete before kicking off subsequent builds that depend on it. The purple machine code generation portion can continue in parallel.

</comment><comment><USER2> It doesn't work any more on Raspberry Pi.

<comment><USER3> What happens?!

</comment></comment><comment><USER4> Judging from the 1.38.0 changelog, this one looks like a fairly toned-down Rust release. Nevertheless, bug-fixes and performance improvements as usual.

I think I'm going to skip this one until the recently stabilized async-await feature has finally made it in the next version. :)

<comment><USER5> It's in beta though. Planning to move ahead and start using it in our team now.

<comment><USER6> Please file bugs! We only backport major stuff to beta, but this is such an important feature that hearing about things early is even more important than it usually is.

<comment><USER5> Will do. Have been doing extensive tests with nightly for a while and it's been quite good except that lifetime bug that happened at 9/11...</comment></comment></comment></comment>


Show HN: I Built a Course to Teach Web Development on Rails - <AUTHOR> https://www.nimblelabs.com/course/build-an-app-from-scratch-with-ruby-on-rails <comment><AUTHOR> The link above is the content of the course. But the platform for creating courses used to teach this course is also open source and available here:

[https://github.com/NimbleLabs/CourseApp](https://github.com/NimbleLabs/CourseApp)

It is a course system that can be used to teach anything... not just Rails.

Enjoy!</comment>


Ask HN: Ideas on making money? - <AUTHOR>

So my last freelancer job ended up with me working for free. I put up some contact forms on my freelance website to get clients but don't know where to advertise my services, and don't have any money to do so.
I go on craigslist but my area doesn't seem to have a whole lot of jobs or contract jobs.
Job interviews I went to for software were hiring seniors only. I'm at junior/intermediate level.
Any ideas? I've been trying to make money for the past few months and coming up dry again and again and I'm losing all hope. <comment><USER2> You need a website if you don't have one already... If you have one, set it on your profile, 'cause this message on HN could have been a good "ad" for your talent :-)

</comment><comment><USER3> > I go on craigslist but my area doesn't seem to have a whole lot of jobs or > contract jobs.

Some advice that should be obvious -- move to where the jobs are.

</comment><comment><USER4> Try finding something online, i.e. odesk.com, elance.com, etc.

</comment><comment><USER5> Set up Google Alerts for local/remote jobs.</comment>


PEP 622 – Structural Pattern Matching - <AUTHOR> https://www.python.org/dev/peps/pep-0622/ <comment><USER2> Very interesting. This PEP is still in draft state, but I am interested to see how the community will react. For me, I have a few thoughts:

1) This is really close to Erlang/Elixir pattern matching and will make fail- early code much easier to write and easier to reason about.

2) match/case means double indentation, which I see they reasoned about later in the "Rejected ideas". Might have a negative impact on readability.

3) Match is an already used word (as acknowledged by the authors), but I think this could have been a good case for actually using hard syntax. For me, perhaps because I'm used to it, Elixir's "{a, b, c} = {:hello, "world", 42}" just makes sense.

4) I hope there won't be a big flame-war debacle like with :=

5) And then finally there is the question of: "It's cool, but do we really need it? And will it increase the surprise factor?" And here I'm not sure. And again, this was the concern with the new assignment expression. The assignment expression is legitimately useful in some use cases (no more silly while True), but it might reduce the learnability of Python. Python is often used as an introductory programming language, so the impact would be that curricula need to be adjust or beginner programmers will encounter some surprising code along the road.

I can't say this is a good or bad proposal, I want to see what other opinions are out there, and what kind of projects out there in the world would really benefit from syntax like this.

<comment><USER3> I have a visceral dislike of pattern matching. Lisp shows just how much people will abuse it in real-world production codebases. It becomes impossible to understand even simple logic without comments. I'd link to some examples, but I'm on mobile; suffice to say, pull up the emacs codebase and read through some of the more advanced modules like edebug.el. I'm not certain that one uses pattern matching, but it's a perfect example of "this codebase cannot be understood without extensive study of language features."

You may argue that I am simply not versed enough in pattern matching. "You should study harder." I would argue that simplicity is worth striving for.

I hope this PEP never moves beyond draft.

It's also shocking that most people here seem to be tacitly supporting this, or happy about it. Yes, it's cool. Yes, it might simplify a few cases. But it will also give birth to codebases that _you can't read_ in about, say, 5 years. And then you'll have a bright line between people in the camp of "This is perfectly readable; it does so and so" and the rest of us regular humans that just want to build reliable systems.

And oh yes, it becomes impossible to backport to older python versions. Lovely.

<comment><USER4> Apart from Clojure, lisps generally do not support destructuring pattern matching on an object/dict.

<comment><USER3> The defining feature of lisp is that it can support whatever you want, because the AST is available at compile time and is completely regular. If your point is about dicts specifically, then you might be technically correct, but I assure you that the majority of lisp codebases do support exactly the sort of pattern matching in this PEP. And the abuses are frankly egregious. Racket is the worst offender of them all, with syntax matching.

</comment></comment></comment></comment><comment><USER5> So it's actually a smart switch statement.

Seems like it doesn't create instances when you're doing

      Node(children=[Leaf(value="("), Node(), Leaf(value=")")])

instead:

1\. Node means "is instance of Node".

2\. Everything in between () is "has an attribute with value".

3\. List means "the attribute should be treated as a tuple of".. etc..

Very confusing, this definitely needs another syntax, because both newcomers and experienced devs will be prone to read it as plain `==`, since that's how enums and primitives will be working.

This syntax goes against Zen: It's implicit -- when using match case expressions don't mean what they regularly mean. It's complicated -- basically it's another language (like regex) which is injected into Python.

I'm a big believer in this feature, it just needs some other syntax. Using {} instead of () makes it a lot better. Now no way to confuse it with simple equality.

      match node:
        case Node{children=[{Leaf{value="(", Node{}, ...}}

<comment><USER6> It's worth noting that there's a _truly massive_ amount of precedent in other languages for Python implementing it using the syntax as proposed. Languages that have or are planning to include pattern-matching where the pattern syntax exactly mirrors the expression syntax like this include Rust, Swift, OCaml, Haskell, C++, Ruby, Erlang, and many, many more.

I understand the worry that newcomers might struggle, but I don't think it's going to be the case: newcomers regularly learn the languages listed above without stumbling across that problem. And if Python did choose a syntax like the one you're proposing, it'd also be the odd one out among dozens of mainstream languages including this feature, which I think would be even _more_ confusing!

<comment><USER7> Yes I think thats what the original commenter was missing. Pattern matching is not new ( but it is awesome ), there are already expectations of how it would look in Python.

I can't wait for this feature!

</comment></comment></comment><comment><USER8> glad to see this! though it's a shame that the proposed `match/case` is a statement, not an expression:

> "We propose the match syntax to be a statement, not an expression. Although > in many languages it is an expression, being a statement better suits the > general logic of Python syntax."

no matching in lambdas unless those get overhauled too :(

instead, let's get excited for a whole bunch of this:

      match x
        case A:
          result = 'foo'
        case B:
          result = 'bar'

(i guess i'm a _little_ salty...)

<comment><USER9> I wonder if this is intentional. FP constructs are increasingly discouraged in Python, taking reduce [1] as an example. Not that this is necessarily a bad thing, per sé -- I think it does simplify the language. But it's an opinionated decision that will discourage FP enthusiasm from finding a home in Python.

[1] [http://lambda-the-ultimate.org/node/587](http://lambda-the- ultimate.org/node/587)

<comment><USER10> With a good mix of comprehensions, itertools, functools and lambda, there is enough stuff to get creative with FP in Python anyway.

<comment><USER8> btw, my favorite FP-hack: let-in expressions with lambdas OR list comprehensions:

      let x = foo in expr

can be

      [expr for x in (foo,)][0]

(kinda reads like a Haskell `where` clause!) or:

      (lambda x = foo: expr)()

useful in a pre-walrus-operator REPL :)

<comment><USER11> If you want to program in Haskell, why don't you get a job programming in Haskell rather than inventing something so ugly?

You would not get through code review with that in any shop that has discipline.

<comment><USER8> > You would not get through code review with that in any shop that has > discipline.

... and i'd never think to try! that's why i mentioned using it in a REPL and called it a hack :) it's just fun. i played around with bytecode-rewriting too, doesn't mean i'd use it in production.

PS. for a less extreme version, the 1-elem-tuple trick is useful if you need an intermediate variable in a listcomp:

      [
        y+y
        for x in my_list
        for y in (foo(x),)
      ]

but it's (obviously) ugly & only useful if you're in a REPL and don't want to rewrite the whole thing.

</comment></comment></comment></comment></comment></comment><comment><USER12> Lately, Elixir has dethroned Python as the language that I get the most joy from using. Pattern matching in one of the big reasons. Great to see that Python core contributors (including Guido!) wants to see this feature in Python as well! Hopefully it will be well integrated and not feel like a tacked on feature.

If you're curious about why this is so useful, and reading the (quite dry) PEP isn't your thing, I would heartily recommend playing with Elixir for a few hours. Pattern matching is a core feature of the language, you won't be able to avoid using it. The language is more Ruby-like than Python-like, but Python programmers should still have an easy time grokking it. When I was getting started I used Exercism [1] to have some simple tasks to solve.

[1] [https://exercism.io/tracks/elixir](https://exercism.io/tracks/elixir)

</comment><comment><USER13> This PEP is burying the lede -- it introduces a `@sealed` decorator, which gives python ADTs: [https://www.python.org/dev/peps/pep-0622/#sealed-classes- as-...](https://www.python.org/dev/peps/pep-0622/#sealed-classes-as-adts)

<comment><USER14> I guess then python can have either and maybe? That would be real nice. working with exceptions sucks...

</comment></comment><comment><USER15> "The match and case keywords are proposed to be soft keywords, so that they are recognized as keywords at the beginning of a match statement or case block respectively, but are allowed to be used in other places as variable or argument names."

That's interesting. Python 3.6 had "async" and "await" as soft keywords, before they became reserved keywords in 3.7 [1]. However, soft keywords have just been added to Python more generally [2], so aren't such a special case anymore.

[1] [https://www.python.org/dev/peps/pep-0530/](https://www.python.org/dev/peps/pep-0530/)

[2] [https://github.com/python/cpython/pull/20370](https://github.com/python/cpython/pull/20370), [https://github.com/python/cpython/pull/20370/files](https://github.com/python/cpython/pull/20370/files)

</comment><comment><USER16> Interesting proposal, but I'm cringing at yet another overload for the * symbol.

a * b == "a times b"

a * * b == "a to the power of b"

f(* a) == "call f by flattening the sequence a into args of f"

f(* * a) == "call f by flattening the map a into key value args for f"

[* a] == "match a sequence with 0 or more elements, call them a"

Am I missing something? I know these all occur in different contexts, still the general rule seems to be "* either means something multiplication-y, or means 'having something to do with a sequence' \-- depends on the context". It's getting to be a bit much, no?

Note: HN is making me put spaces between * to avoid interpretation as italics.

<comment><USER17> It's already used that way for unpacking, e.g.

      >>> [x, *other] = range(10)
      >>> x
      0
      >>> other
      [1, 2, 3, 4, 5, 6, 7, 8, 9]

So this instance of the syntax is not that novel. If it's a mistake, it's too late to fix it.

A unary asterisk before a name means the name represents a sequence of comma- separated items. If it's a name you're assigning to (LHS) that means packing the sequence into the name, if it's a name you're reading from (RHS) that means unpacking a sequence out of the name.

<comment><USER11> You can also do [a, * b] when constructing a list so that b would be injected into that list after a - makes total sense.

</comment></comment></comment><comment><USER18> So far I like it.

Unpacking was huge 10 years ago, but nowaday even JS has object destructuring, so python was lagging behind.

It feels like they really spent a lot of time in designing this: Python has clearly not be made for that, and they have to balance legacy design with the new feature.

I think the matching is a success in that regard, and the __match__ method is a great idea. The guards will be handy, while the '_' convention is finally something official. And thanks god for not doing the whole async/await debacle again. Breaking people's code is bad.

On the other hand, I understand the need for @sealed, but this is the kind of thing that shows that Python was not designed with type hints from the begining. Haskell devs must have a laught right now.

We can thank Guido for the PEG parser in 3.9 whichs allows him to co-author this as well.

I expect some ajustments to be made, because we will discover edge cases and performance issues, for sure. Maybe they'll change their mind on generalized unpacking: I do wish to be able to use that for dicts without having to create a whole block.

But all in all, I believe it will be the killer feature of 3.10, and while I didn't see the need to move from 3.7, walrus or not, 3.10 will be my next target for upgrade.

</comment><comment><USER19> If you want it today, Pampy does most of it:

[https://github.com/santinic/pampy](https://github.com/santinic/pampy)

Even match on Point(x, y, _)

<comment><USER20> There is also switchlang¹ which _isn 't_ quite the same thing, but provides _some_ of the functionality of PEP-622 and pampy. I believe it is notable for including a nice descriptive README, and also having a small/simple implementation.

I personally prefer the pampy internals, but quite like the context manager usage from switchlang. I don't even know _which_ bikeshed I want to paint, let alone the colour.

1\. [https://github.com/mikeckennedy/python- switch](https://github.com/mikeckennedy/python-switch)

</comment></comment><comment><USER21> If you like pattern matching and Python, I recommend you check out [http://coconut-lang.org/](http://coconut-lang.org/) which compiles to Python.

<comment><USER22> Only having the prettier lambda in python would make my so happy.

</comment></comment><comment><USER23> This is the first PEP I'm really excited about. I hope the design is given more careful consideration, though, because destructuring in this manner more broadly across the language would also be killer.

My biggest concern is the class matching syntax. I feel like that would be much better deferred to a lambda style function or similar. The syntax matches instantiating a new class instance exactly, which seems like it could cause a lot of problems for tools that read and manipulate syntax.

</comment><comment><USER24> Can someone explain to me the history behind Python's aversion to switch statements? I get Python is opinionated and I'm not trying to start a language war, it was just never clear to me why the `if ... elif` pattern was the preferred idiom.

<comment><USER25> Taking this question from the opposite angle, what benefits do switch statements give us over if...elif?

Not actually a heavy Python user, but even though most languages I use regularly are more switch/case-heavy, I've never quite grasped why there's two largely interchangeable ways to do the one thing.

<comment><USER26> In lower level languages, when you use switch, you make it easier for the compiler to generate a jump table.

In higher level langues with strong, static types, the switch statement can indicate to the compiler you want to match on the type of the variable; it can do analysis then to make sure your pattern match is exhaustive.

<comment><USER25> These are good examples. Especially for a lower level languages this makes a lot of sense.

For higher level languages, I would imagine typeguards would provide some of the desired functionality here, while being much more lightweight than a full alternative conditional syntax.

</comment></comment></comment></comment><comment><USER27> Rust was my first experience with pattern matching, and I really learned to love it there. Seeing it come to Python will be great as well. I'm glad this is on the docket, and I can't wait to see how this draft evolves.

</comment><comment><USER28> I'm excited, but it seems like setting names by default is very odd. Quite a bit of the PEP is dedicated to the odd situations created by "case x" actually setting x rather than reading x ("case .x" would read x). Wouldn't this be a natural place for := ? So you would do:

      case x := _

to match and assign to x. "_" would always be the matcher. You always have access to the original item that the match was made on, so pulling out the matched items is often not needed, AFAICT. This would be explicit, and not too surprising. Then the whole dotted names part can be dropped - it works like normal Python at that point.

The PEP already suggests this for capturing parts of the match, why not just use it for all saved matches? It's more verbose, but consistent, with fewer caveats, and not always needed.

Disclaimer: My languages don't happen to include one with good pattern matching, so I'm not strongly familiar with it.

<comment><USER29> With pattern matching you _normally_ want bindings, at least local to the match construct (that the PEP proposes bindings with normal Python function scope, rather than local to the construct has plusses and minuses), so creating extra verbosity for bindings is complicating the normal case.

</comment></comment><comment><USER30> This is very exciting!

One subtle thing which I noticed is the distinction between class patterns and name patterns (bindings). In particular, it is possibly confusing that the code `case Point:` matches anything and binds it to the value Point, whereas `case Point():` checks if the thing is an instance of Point and doesn't bind anything.

<comment><USER17> Yeah, that seems like it's going to cause trouble, because you can make a mistake without noticing. If you write `case Point:` when you mean `case Point():` you won't get an exception or a missing name, it'll just look like it thinks all objects are Points.

Linters could help. You're shadowing `Point`, and because `case Point:` matches any value, if there's another case after that then something is wrong. But you can't always rely on linters.

</comment></comment><comment><USER31> Note that this just a draft/proposal. And there's heavy activity on the mailing list.

With that said, this has been suggested and discussed many times in the past. I imagine this will be as controversial as the walrus operator[1] was.

[1] [https://www.python.org/dev/peps/pep-0572/](https://www.python.org/dev/peps/pep-0572/)

</comment><comment><USER32> > case Node(children=[LParen(), RParen()]):

Is this will create a second Node instance and compare it to node?

If so, is it not less efficient performance wise than it's "counterpart" isinstance() + properties comparison?

If this method is less efficient, it could be confusing, specially for newcomer.

Am I missing something.

<comment><USER33> It reads like a Node instance construction, but it's actually syntactic sugar for: isinstance(node, Node) and node.children == [LParen(), RParen()]

<comment><USER34> It's not quite syntactic sugar, but you're right that (probably) no new object would be created. Based on the "The __match__() Protocol" section [0] of the Pep, matching will call into `Node`'s `__match__` method with `node` as the arg. If Node doesn't have any custom logic here, it'll use the default __match__ implementation [1], which checks `isinstance(node, Node)` like you said, then returns `node` for the python interpreter to check that `node.children` a) is a sequence, b) has two elements, c) has its first element matching `LParen`, using `LParen`'s `__match__` method, and d) has its second element matching `RParen`, using `RParen`'s `__match__` method. If none of these `__match__` methods are overriden, then it does basically function as the parent poster said (though I think it would work even if node.children were some other sequence type (e.g. tuple) containing `LParen()`, `RParen()`).

[0] [https://www.python.org/dev/peps/pep-0622/#the-match- protocol](https://www.python.org/dev/peps/pep-0622/#the-match-protocol) [1] [https://www.python.org/dev/peps/pep-0622/#default-object- mat...](https://www.python.org/dev/peps/pep-0622/#default-object-match)

</comment></comment></comment><comment><USER35> The implicit isinstance the repurposing of the constructor syntax all seems very un-Pythonic.

</comment><comment><USER36> This is great. I'm currently trying to rewrite a heavily object-oriented library into a more functional one (the rewrite is necessary because of licensing issues, and functional because the original code is a clusterf*ck of mutation) and despite the whole company working on top of Python, I was seriously considering implementing it in SML[1] specifically due to pattern matching making the underlying algorithm of the main data structure incredibly easier to reason about and implement.

[1] Yes I know coconut-lang is a thing, but I didn't want to introduce something that looks a lot like Python but isn't in our codebase

</comment><comment><USER37> >Note that because equality (__eq__) is used, and the equivalency between Booleans and the integers 0 and 1, there is no practical difference between the following two:

>case True: ... case 1: ...

From practical perspective this is great, but I can imagine many cases where one could want to differentiate between those.

On one hand the number usually can be nested inside a structure and matching on == is more flexible. On the other hand matching on 'is' is still letting users relax this behaviour and allows matching on type of primitives as well.

</comment><comment><USER38> This is trying to achieve a poor-human's multiple-dispatch with match-case syntax

</comment><comment><USER39> finally our own switch statement and a modern and powerful one at that. we needed this a long time ago!

</comment><comment><USER40> Very excited about this! Looking forward to using these super switches when they are released.

</comment><comment><USER41> Pattern matching in Python is such a mess.

Python 3 eliminated the ability to match on tuples in function heads.

For loops can match on tuples, but lambda headers can't.

As an Erlang fan, it's maddening.

</comment><comment><USER42> feels like languages are converging.</comment>


Validation library JavaScript - <AUTHOR> Hey guys, this is my first post here on HN, just wanted to share this little library I build myself to validate users input the easiest way possible. So i'd like to know what you guys find about this one. https://github.com/nightw0lff/validator-handler <comment><USER2> Just a few things:

\- Make sure to fill out the url filed when submitting.

\- Also, I would set the link to the github page, [https://github.com/nightw0lff/validator- handler](https://github.com/nightw0lff/validator-handler), rather than the npm page.

\- Mortal Kombat is awesome!

<comment><AUTHOR> thx bro, edited.</comment></comment>


The 4 Steps to Finding Your Voice by Stephen R. Covey - <AUTHOR> http://www.stephencovey.com/blog/?p=16 <comment><AUTHOR> I've got a marketing related blog (<http://www.volcanicmarketing.com/mp>) that hasn't gained as much traction as I expected it to and I suspect it's been partially because it doesn't have a strong and consistent voice, like say Signal vs Noise does. Digging around online, I came across this interesting article by Steven Covey (author of 7 Habits of Highly Effective People) and posses some really interesting questions that I think can help people start towards refining their voice. If you've got other good resources on crafting/refining/identifying your voice, pls add in the comments.</comment>


I Turned Down My Silicon Valley Dream Offer - <AUTHOR> https://boyter.org/posts/why-i-gave-up-on-my-silicon-valley-dream-offer/ <comment><USER2> I can relate to this article a lot. Been in Asia for over 10 years mainly because of family. It has definitely affected my career prospects. Its a hard decision to make when you have the ability to move to SV and earn lots of money, but deny it.</comment>


OKCupid's Study on Male Dating Photos Fails Reproducibility - <AUTHOR> https://blog.photofeeler.com/okcupid-is-wrong-about-smiling-eye-contact-mens-dating-profile-photos/ <comment><USER2> It's hardly surprising. OKCupid's audience is nowhere remotely near representative. I'd expect the same to be true for Tinder but harder to see from a casual glance, and I'm not about to do my own test.

But comparing the OKCupid dataset to their own like this proves nothing. There's no evidence the two tests measures even remotely the same thing, given that apart from audience differences OKCupid and Tinder also works vastly differently.

Some of their analysis of the flaws in OKCupids "study" may make sense, but claiming this is a "reproduction" is laughable. It's a marketing fluff piece with some bits in that may make sense, but isn't backed up by data that can actually be compared to the original study.</comment>


Ask HN: Which web browser do you use? - <AUTHOR> I'm currently using Vivaldi or Brave. Which browsers do you use and in which area do you work? <comment><USER2> Vivaldi, and chrome for dev. I am a web developer.

I didn't want to at first because I hated chrome, but I ended up doing most of my webdev with chrome (we were developing a webapp with chrome as primary target) and now I got used to its devtools (but wouldn't use this browser to do anything else).

I use vivaldi for everything else. I love the old opera spirit, even though vivaldi's still far from perfect imo. I can't wait for the mail client, too.

I may switch back to firefox instead of chrome for webdev once I give it a real try. I'll probably stick with vivaldi for everything else, though.

</comment><comment><USER3> Firefox and various extensions, forever it seems. I think the update will have many switching over, or back...

</comment><comment><USER4> Firefox developer edition , most of the time.

</comment><comment><USER5> Brave on mobile, Vivaldi on desktop</comment>


C Language Quirks - <AUTHOR> http://www.danielvik.com/2010/05/c-language-quirks.html

<comment><USER2> For far more of same, there's Koenig's _C Traps and Pitfalls_. Heck, the article (<http://www.literateprogramming.com/ctraps.pdf>) that grew into the book is even free online.

Also, for anybody doing modern C work, I strongly recommend both Hanson's _C Interfaces and Implementations_ and Ierusalimschy's _Programming in Lua_, 2nd ed. The former _nails_ writing good C libraries, and the latter covers one _particular_ library that provides a portable, C-friendly, mature, efficient (<http://luajit.org/>), ready-made scripting language that is a cleaner incarnation of JavaScript's "good parts".

Also, both are _good reading_. The former is a shining example of literate programming, and the latter is IMHO one of the best programming texts that wasn't co-written by Brian Kernighan. :)

<comment><USER2> ("Also, also"? Oops. Missed that before the edit window closed.)

<comment><USER3> How refreshing!!

As an editor, I must say that it warms my heart to know that someone out there actually proofreads his comments. Bravo!

Also, thanks for the C Pitfalls link. It will prove quite useful in my current project. The original article isn't too bad, either.

</comment></comment></comment><comment><USER4> I work on a compiler, I agree, there's some weird behaviour that's possible, but a lot of the things he's described are implementation defined. There are general conventions, but things like shifting values more than double their size is implementation defined.

If you really want to get a good handle on C, there's nothing like reading the spec.

</comment><comment><USER5> The common theme in almost all of these are:

1) implicit integer promotion causes hard to find errors 2) operator precedence is non-intuitive (just use parens anyways!)</comment>


What if Occupy Wall Street Protesters Did Startup Weekend? - <AUTHOR> http://feefighters.com/blog/occupy-wall-street-startup-weekend/

<comment><USER2> The author seems to focus on the number of bodies/man-hours invested in each startup weekend. These are hardly the most important metrics to consider. One of the main advantages that startup weekends have is that the groups present are self-selected. You couldn't randomly pick an equal number of people off the street and put them through the same program and expect to come up with the same results, because the self-selected group will have motivation that increases their productivity and success rate massively. And on a small scale, this is more likely to be a "successful/unsuccessful" binary scale, e.g. a startup whose founders are 20% as motivated will not create 20% as many jobs; it will in all likelihood create 0 jobs.

</comment><comment><USER3> What if the American revolutionaries just did startup weekend? You don't fix a corrupt system by hiding your head in a pile of money.

<comment><USER4> I read this more as being about creating jobs than making money for one's self.

<comment><USER5> Well it's great that they would be creating more jobs but it wouldn't fix the fact that people got bailed out and then used that money for their bonuses.</comment></comment></comment>


Netflix buys its first production studio complex - <AUTHOR> https://media.netflix.com/en/press-releases/netflix-announces-plans-to-open-new-u-s-production-hub-in-albuquerque <comment><USER2> Was Albuquerque chosen just for the funding or is there some other advantage? Seems like closer to the west coast would make access to both the manpower and services needed to the production of shows easier.</comment>


Help Test Docker CE on Raspberry Pi / ARM - <AUTHOR> https://github.com/alexellis/docker-arm/issues/17 <comment><USER2> It's a pity Docker is still not using multi-arch official images, despite all the tech (manifest lists) is already here and seems to be working. One still has use e.g. "FROM arm32v7/alpine" instead of "FROM alpine".

Without this, non-x86_64 use is somewhat painful, as one has to edit every single Dockerfile just so images can be built.

<comment><AUTHOR> You're right and I suspect it's because multi-arch isn't a business priority. The support for multi-arch is there and things are slowly moving in that direction. I'm more optimistic now than I was 2 years ago.

<comment><USER3> Actually Docker EE has multi-arch as a selling point[1] with support for Windows and Linux on x86 and Linux on IBM Z (s390). These three options require different Docker images, so it would make sense for them to figure out a way to indicate image architecture sooner rather than later.

1: [https://blog.docker.com/2017/08/docker-enterprise- edition-17...](https://blog.docker.com/2017/08/docker-enterprise- edition-17-06/)

<comment><AUTHOR> I don't think there's additional multi-arch support in EE which is not present in CE. When I say support here I mean in terms of there being a complete suite of official multi-arch images. I believe the points in this article are still relevant - [https://blog.alexellis.io/5-things-docker- rpi/](https://blog.alexellis.io/5-things-docker-rpi/)

</comment></comment></comment></comment><comment><AUTHOR> Quick update

It looks like a pending PR for 17.07 fixes Docker Swarm on Raspberry Pi which is great. [https://github.com/alexellis/docker- arm/issues/14](https://github.com/alexellis/docker-arm/issues/14)

There still needs to be thorough testing around armv6 and arm7 along with Stretch + Jessie.

[https://github.com/alexellis/docker-arm/labels/community- sup...](https://github.com/alexellis/docker-arm/labels/community-supports- docker)

To track the relevant items I've labelled Issues "community-supports-docker" and also put in some note about tuning-up for building Docker on RPi.

</comment><comment><USER4> Note that you have been able to run LXD with Ubuntu Core on the pi since 16.04.

Docker is a bit more efficient while LXD is more secure.

<comment><USER5> Out of curiousity, I've not looked at LXD much, do you have any info. on where it's better than Docker from a security perspective?

<comment><USER4> IIRc docker runs as root while lxd runs as a normal user.

I think the Ubuntu wiki has some articles about lxd security.</comment></comment></comment>


Amazon soars after earnings beat - <AUTHOR> https://www.cnbc.com/2020/01/30/amazon-amzn-q4-2019-earnings.html <comment><USER2> Interesting tidbits:

\- 150 million amazon prime users globally (equivalent to to combined france + germany population (or) half of US population). Impressive!!

\- Rivian is integrating Alexa into its electric vehicle lineup, including its upcoming fleet of 100,000 all-electric Amazon delivery van. Amazon has made investments in Rivian. Going to compete with Tesla?

\- Amazon Music has more than 55 million customers worldwide. Collectively, in the U.S., U.K., Germany, and Japan, Amazon Music customers have grown nearly 50% year-over-year;

\- Prime Video received eight Golden Globe Award nominations, with Fleabag winning Best Television Series, Musical or Comedy, as well as Best Performance by an Actress in a Television Series, Musical or Comedy, for Phoebe WallerBridge.

\- AWS announced three Arm-based instances (M6g, C6g, R6g) powered by AWS's new Graviton2 processors, that deliver up to 40% better price and performance than current x86 processor-based instances. Threat to intel?

\- AWS announced the general availability of AWS Outposts, a fully-managed service that extends AWS infrastructure and services to virtually any data center, co-location space, or on-premises facility. On-premises is gaining strength?

[https://ir.aboutamazon.com/static- files/f3589a21-d023-4e4c-9...](https://ir.aboutamazon.com/static- files/f3589a21-d023-4e4c-9897-1498c60885d2)

<comment><USER3> How simple (or difficult) is it to migrate from an x86-based instance to an Arm-based instance?

<comment><USER4> I'm gonna give the unhelpful shot of "it depends" with a chaser mixed from "anecdotal experience".

Having done a lot of work with Raspberry Pis over the past few years, I've been pretty impressed with the number of libraries and packages that compile for ARM. I've done stuff like building fullscreen electron apps (for theatre projections), doing some light video processing in ffmpeg, running a plex server, running a DIY Time Capsule (which required formatting a drive with HFS+ and then using some HFS+ based libraries).

There are probably holes: I haven't tried doing deep learning stuff on a Pi (I'd guess some frameworks work and some don't but I don't know which) and to that end I definitely haven't tried anything CUDA related (I have no idea if Nvidia's proprietary drivers compile for ARM).

But overall, I get the feeling that with Android a lot of libraries started shipping for ARM, which made Raspberry Pi possible, which has gotten more libraries and packages to ship for ARM, which should hopefully make people's transition in serverland much easier (especially if you're doing run of the mill web server stuff).

</comment></comment></comment><comment><USER5> Net sales ~$280B (products and services) Net Operating expenses ~$266B Operating income ~$14.5B on that huge amazon.com revenue.

AWS is an amazing business itself but it's easy to underestimate what a massive strategic advantage it is for amazon - compared to other retailers - to have it in their portfolio! [edited M to B - thanks for catching that :)]

<comment><USER6> B not M

<comment><USER5> corrected - thanks !

</comment></comment></comment><comment><USER6> AWS Record Quarter at $9.95 Billion revenue, up 34% year on year. Operating income from AWS also up 19% to ~$2.6B

</comment><comment><USER7> A single $2000 strike call option expiring tomorrow was trading at $250 just before close. If Amazon closes at $2100 tomorrow that option will be worth $10,000. Amazing.

<comment><USER8> There are always massively out of the money options expiring soon that are worthless and would skyrocket if the company suddenly became much more valuable. They're not valued highly because that very rarely happens, no matter what the guys at /r/wallstreetbets tell you.

<comment><USER7> This is actually noteworthy because the $2k strike was by far the most heavily traded call option today...not even close, so this wasn't an extremely random dumb lotto bet made by 2 people on /r/wsb

<comment><USER9> It was heavily traded but there was an equal amount written/sold as bought.

Were the writers/sellers lacking of foresight? Were buyers prescient? Was everyone gambling?

<comment><USER7> I'm not sure what your point is. Sellers obviously think the credit they earn is worth the risk. Buyers think the price they pay is worth it too. It's just a two-sided marketplace like many other things.

Options writers can and should hedge losses by not writing naked calls (highly risky in situations exactly like this) and instead buy a higher strike option which caps losses e.g. a vertical spread.

<comment><USER9> You said the option/strike in question was not a dumb lotto bet and you submitted the volume of trading as your supporting evidence.

But the state lottery is literally a dumb lotto bet with super high volume.

So I don't see how this wasn't some set of lucky gamblers. If ER went another way, there'd be some other group making lots of money. Everyone speculating about the future (which is fine depending on the financial circumstances of involved individuals)

</comment></comment></comment></comment></comment></comment><comment><USER10> So they're about back to where they were in 2018.

</comment><comment><USER11> Unless I'm reading this wrong AWS generated 47% of Facebook's total 2019 revenue in Q4.

<comment><USER12> The value of that fact depends on how the margin compares.

Half (I made that number up) of AWS revenue is passthrough to hardware vendors.

</comment></comment><comment> y-c-o-m-b As they cannibalize or threaten small businesses[1], treat their employees poorly[2][3], and encourage/allow Chinese counterfeit products[4][5].

[1] [https://www.washingtonpost.com/technology/2020/01/16/popsock...](https://www.washingtonpost.com/technology/2020/01/16/popsockets- sonos-tile-congress-antitrust-hearing)

[2] [https://www.businessinsider.com/amazon-employees-describe- pe...](https://www.businessinsider.com/amazon-employees-describe-peak-2019-2)

[3] [https://www.theguardian.com/technology/2019/apr/02/revealed-...](https://www.theguardian.com/technology/2019/apr/02/revealed- amazon-employees-suffer-after-workplace-injuries)

[4] [https://www.washingtonpost.com/technology/2019/11/14/how- ama...](https://www.washingtonpost.com/technology/2019/11/14/how-amazons- quest-more-cheaper-products-has-resulted-flea-market-fakes/?arc404=true)

[5] [https://www.theatlantic.com/technology/archive/2018/04/amazo...](https://www.theatlantic.com/technology/archive/2018/04/amazon- may-have-a-counterfeit-problem/558482/)

<comment><USER13> What's the point of this comment besides being inflammatory?

All those things are always discussed tirelessly in HN every time there's something about Amazon. We get it. And it's ok to bring them up here. But how about adding something useful to the discussion, instead of just making that statement and posting a bunch of links?

<comment><USER14> I note that the resume on your website states that you're currently employed at Amazon

<comment><USER13> I'm not. Used to. Could talk shit about Amazon for days, but that's not the point of what I said.

Thanks for being super creepy, and digging through my profile. Unfortunately you couldn't even get that right. And by the way, even if I still worked there I can't see how that discredits my opinion.

But since you seem to going down that route, I can say confidently that I don't like Amazon as an employer and many times I don't like it when I interact with it as a customer. Mind blowing, right? Someone who can be critical and still tries to seek objective opinions.

<comment><USER14> > Thanks for being super creepy, and digging through my profile.

no problem, next time there's a potential conflict of interest then state it in your post

> Unfortunately you couldn't even get that right.

it's hardly my fault if your resume on your website is out of date

</comment></comment></comment></comment></comment><comment><USER15> 3.3 b earnings in a quarter. Most of which is from cloud I believe? They don't break down.

Shopping- Walmart is catching up (but will probably not beat. It's a lossy business for Amazon I believe and as people realize the counterfeit problem the business goes down )

Cloud- MS will beat them in 3 years (which doesn't mean they will lose customers but growth will slow down )

Other areas they have tough competition.

I'm beginning to wonder if it's a stock bought by faithful.

<comment><USER16> > Cloud- MS will beat them in 3 years (which doesn't mean they will lose > customers but growth will slow down )

Is this actually true? I thought MS bundled a bunch of "office 365" stuff in with "cloud" to boost their numbers.

<comment><USER15> Debunked earlier by an MS employee, no less, on HN itself

<comment><USER16> Can you link to that please?

<comment><USER17> It wasn't debunked, what you said was correct. Microsoft does not break out Azure's sales or operating income numbers, it's all reported together with the other cloud products. All they reveal each quarter is Azure's growth rate.

<comment><USER18> Actually, they used to bundle O365 and Azure numbers together, but it's been broken out for at least a year or two: [https://www.microsoft.com/en- us/Investor/earnings/FY-2020-Q1...](https://www.microsoft.com/en- us/Investor/earnings/FY-2020-Q1/press-release-webcast)

</comment></comment></comment></comment></comment></comment><comment><USER19> So don't expect any of your pet Amazon complaints to change any time soon.</comment>


Bitcoin Risks Crashing to $900 If Dot-Com Mania Is Any Guide - <AUTHOR> https://www.bloomberg.com/news/articles/2018-02-12/bitcoin-risks-crashing-to-900-if-dot-com-mania-is-any-guide <comment><USER2> That would be amazing, if it still held that much value after a crash. There is no lower barrier at $900 any more than there is at $90 or $9.</comment>


The Great Re-Branding: MBAs in Tech Startups - <AUTHOR> http://ventureminded.me/post/39061757622/the-great-re-branding-mbas-in-tech-startups

<comment><USER2> To me it depends a lot on the stage.

A fresh-minted MBA can't, by virtue of their degree, do anything useful for a small outfit. (They may have useful skills as well from a previous life, but if so they're not, for the purposes of this discussion, an MBA; they're a developer or a designer or a product manager or a VP of engineering who happens to have gone and gotten a degree.)

I can see a 30-100 person shop taking on an especially bright and unusually humble fresh-minted MBA as a junior product manager or something. Because at that size, you can afford a person who won't pull their weight for a while while they're learning. And it can be great to have somebody who doesn't have to unlearn the bad habits gained elsewhere.

This guy, though, wouldn't be at the top of my list. A 25-year-old with circa 2 years of work experience? One who's blogging about how MBAs are the new black? He doesn't really seem to have the "humility and willingness to learn" that Ben Horowitz was talking about.

<comment><AUTHOR> Not arguing that MBAs are the "new black." I'm simply saying that one explanation is how many MBAs who have been successful at tech startups are known for other things - not the degree.

And as for your jab after reading (or rather, misinterpreting) one blog post, we can simply agree to disagree.

Thanks for commenting and checking out my blog, though - happy holidays!

<comment><USER2> No jab intended. I just think it's a self-serving argument, and it's hard not to consider the source.

I agree that many people with MBAs have been successful at startups; nobody disputes that. Of course, so have many people with literature degrees. And, famously, so have many people with no degrees.

My personal view is that MBAs have little value, positive or negative, in a startup context. A view that many people share. Most recently, Mark Cuban: [http://www.reddit.com/r/IAmA/comments/15doqt/mark_cuban_this...](http://www.reddit.com/r/IAmA/comments/15doqt/mark_cuban_this_is_my_ama/)

My main concern with entrepreneurial people getting them is that it can make them unwilling to put in the time necessary to learn useful skills. The recent MBA grads I know see their peers taking high-level jobs with fancy titles at large companies; starting at the bottom in a startup context doesn't look very appealing in contrast, especially with student loans kicking in.

Happy holidays to you as well.</comment></comment></comment>


Climate change won't make the Earth uninhabitable by 2100 - <AUTHOR> http://mashable.com/2017/07/10/new-york-mag-climate-story-inaccurate-doomsday-scenario/ <comment><USER2> This post had an earlier, more accurate title, which you can still see in the <title> tag. "Do not accept New York Mag's climate change doomsday scenario"

The article says that there's still hope if we act now. It does not say that climate change cannot make the Earth uninhabitable by 2100.</comment>


Third fatal Tesla Autopilot crash renews questions about the system - <AUTHOR> https://www.cnbc.com/2019/05/17/elon-musk-to-review-all-of-teslas-expenses-in-a-new-cost-cutting-plan.html <comment><USER2> We should really be looking at the stats, is this system safer than a human driver?

Given the number of reported fatalities reported recently, it may not be.

<comment><USER3> the problem with stats is that incident rates bunch together extremely heterogeneous driver, vehicles and driving environments, so for example the "40% safer" figure from the ntsb years ago is _extremely_ misleading

since the autopilot has a very limited field of applicability the only way to determine if it's safer is to compare it with actual driving data details between the tesla car fleet within similar condition and I think the only data we can get as outsiders it's "number of death in tesla on highways" and "number of death in tesla on highway with autopilot", but deprived of relative miles driven in each mode information it's going to be quite meaningless, and even with the data at hand it might very well be that the datapoint are too few to reach a significant confidence about the findings.

</comment></comment><comment><USER4> HN conversation on this from yesterday: [https://news.ycombinator.com/item?id=19932918](https://news.ycombinator.com/item?id=19932918)

</comment><comment><USER5> Seems like tall Semis are an issue for Teslas, one of the crashes a year ago was also a similar scenario.

Perhaps they should add more vertical FOV on the sensors?

</comment><comment><USER6> How many people need to die until Tesla is made accountable for lying to the public about the capability of their auto pilot?

Maybe a bus full of dead children?</comment>


Show HN: Learn to Code with Interactive Challenges - Method-X https://edabit.com/explore <comment><AUTHOR> Haven't had a chance to play with it yet but clicked around and it looks interesting. I like the idea of users posting their own coding challenges. The one thing I noticed this suffers from is a lack of a community base. Just clicking through the challenges on the front page I saw no discussions. But with that said I think this could be a neat application for new programmers. I know someone who is going through freecodecamp now. I'll ask them to take a look at this and see what they think.

<comment> Method-X Please do! And if you can, let me know what their experience is like: firstname.lastname@example.com

As for the lack of community, the site has been live for about a week now and it's already got 1000 registered users. In a few months I think it will be very active!

<comment><AUTHOR> Hey a 1000 active users is great. Well done. Maybe show challenges that have active discussions on the front page to showcase your active user base?

</comment></comment></comment><comment> Method-X I really hope some people find this to be a fun tool. I spent a little over five months building it by myself.

Before anyone asks, yes, the backend currently supports other languages! Specifically:

* C

* C#

* C++

* Elixir

* F#

* Haskell

* Java

* JavaScript

* Objective-C

* OCAML

* Php

* Python

* Ruby

* Rust

* Swift

Once I've smoothed out the rough edges and squashed some bugs, I'll begin working on rolling other languages out. Also, the challenges right now are rather easy BUT the system allows anyone to publish their own challenges: [https://edabit.com/guide/creating- challenges](https://edabit.com/guide/creating-challenges). So if you want harder/more challenges, by all means please help out! :)

<comment><USER2> How are you handling execution of each language? I've looked at [https://github.com/remoteinterview/compilebox](https://github.com/remoteinterview/compilebox) a bit, but looks like it has some issues around infinite loops.

<comment> Method-X Every time code is run/checked it's done inside a docker container. This allows me to set up an environment for as many languages as I want and unit test them. The containers run for a maximum of 2 seconds so if there's an infinite loop, the container is destroyed eventually anyway.</comment></comment></comment>


Lots of visible likes and shares lead people to spread more misinformation - <AUTHOR> https://www.niemanlab.org/2020/08/lots-of-visible-likes-and-shares-on-social-lead-people-to-spread-more-misinformation/ <comment><USER2> We even saw it here on HN with the Apple 30% debacle. Misinformation isn't always maliciously sown, but the mechanism of its spread is the same either way.</comment>


Google Fonts and 한국어 - <AUTHOR> https://googlefonts.github.io/korean/ <comment><USER2> Side note but 한글 is an awesome alphabet with a cool history, and anyone reading this line can learn how to read and say 한글 in 30min on Youtube. Try it!

Korea in general is pretty interesting too!

</comment><comment><USER3> Pretty cool, one of them reminds me of the lettering seen in the film "Moon" with Sam Rockwell.</comment>