Paul Graham provides answer to spam emails (2002) - <AUTHOR> https://www.infoworld.com/article/2674702/techology-business-paul-graham-provides-stunning-answer-to-spam-e-mails.html <comment><USER2> Spam countermeasures have led to some fascinating new technologies. In addition to the one cited in the article was Hashcash, which was developed a few years earlier:

[http://www.hashcash.org/papers/hashcash.pdf](http://www.hashcash.org/papers/hashcash.pdf)

Hashcash requires the sender to expend a small quantity of computational work, and attach a proof of this to the email before a recipient even opens it. The underlying assumption is that the burden would be insignificant for a real email sender, but onerous for a spammer.

The approach inspired the powerful anti-spam system at the center of Bitcoin.

It might be interesting to catalog all of the most innovative early approaches to combating spam, and the unrelated technologies that later arose from them.

<comment><USER3> I recently came across this idea to prevent friend request spam on social media, using the Lightning network. The idea is that the person sending you the friend request must attach a small amount of money (in the form of a special lightning payment). If the friend request is legitimate, you can accept it (and not claim the money). But if it's spam you reject the friend request but take the money instead. This is different than Hashcash in that it incurs real monetary costs to the attacker. Instead of using compute resources (for the mining algorithm), the money would actually end up in your pocket.

<comment><USER4> A much older example is the high cost of sending text messages basically eliminates text message spam.

<comment><USER5> Except the cost of phone calls, text messages and even postal mail is sufficiently low to result in spam across all three mediums in ever larger quantities than before

<comment><USER6> As he said, it is a much older version. As with everything the cost decreases over time to the point that it no longer outweighs benefit.

Put another way, this is the unfortunate flip side of free unlimited talk and text.

</comment></comment></comment></comment></comment><comment><USER7> I think this article doesn't provide much value over the original essay [1]. And of course, all excitement from the article is now highly obsoleted.

[1] [http://www.paulgraham.com/spam.html](http://www.paulgraham.com/spam.html)

<comment><USER8> The article has the merit of significantly reducing the size of the original essay, while IMO still retaining two strong messages: 1\. The original (is it?) method used to prevent spam, and 2\. The 'seed' factor, which is expected to make spammers work harder. At mid-page I was thinking "meh, spammers will just have to improve their writing then", but this may not be sufficient thanks to the user-specific seed.

[edit: I didn't realize the original article was from 2002. I agree the article is a bit obsolete at that point.]

<comment><USER9> Modern-day spam is typically generative, and modelling the distribution of "natural e-mail messages" is sadly too naive today. Human beings also understand text through vision, not through bits -- so 1oca1host is just me corrupting the word localhost, but making that inference requires a visual understanding of words. That also gave rise to what is probably a more common spam variant today: the text-embedded-as-an-image type. I've long been of the impression that the only proper way to do text analysis is by vision, a more end-to-end solution as it were.

<comment><USER8> You may very well be true, but then it's a pity that a 2019 article on a 2002 method didn't mention it?

</comment></comment></comment></comment><comment><USER10> Wait did Paul Graham inspire SpamAssassin (the original 'big deal' Bayesian spam filter)?

Cool circa-2002 game for Unix nerds: you have 60 seconds to telnet to port 25 and generate the highest spamassassin score.

<comment><USER11> SpamAssassin predates the article. Not sure it had Bayesian filtering from the start tho.

Paul Graham however definitely championed and popularized the idea of Bayesian filtering.

</comment></comment><comment><USER12> Meanwhile the spam filter at gmail (business account) regularly marks email messages that I send from our own systems (say showing disk space) to our own accounts (and nowhere else) as spam. Also sales lead forms. So they come in and we say 'not spam' and the filter is not smart enough to understand the next very similar email is also not a spam. A human could quite easily see by just the format and the layout (in addition to numerous times marking 'not spam') that it was the not spam.

<comment><USER13> Yeah, I also noticed this.

And I'm pretty sure that some years ago gmail was much better at this.

</comment></comment><comment><USER14> This article is 17 years old ... I must be missing something. Why is it relevant right now?

<comment><USER15> HN has an obsession about Paul Graham.

<comment><USER16> I mean, this is literally Paul Graham's site.

</comment></comment></comment><comment><USER17> I use the word "unsubscribe" to filter out a lot of emails. There are occasional false positives but after combining the above filter with a whitelist of senders it has proven to be very effective.

<comment><USER18> That's why it's now "if you don't wish to receive these emails, click here".

<comment><USER19> Then, as mentioned in the article, the you could filter on the word "click" too.

<comment><USER20> The whole point of these Bayesian filters is that you don't have to spend mental cycles thinking of clever words to filter on. Just mark 'em spam and not spam, the algorithms are plenty good at finding which words are spammy or legitimate without human help.

</comment></comment></comment></comment><comment><USER21> If only we would've reached and saved Usenet in time. A lot of the current web is a bad proprietary replacement of it.

<comment><USER22> Yeah. I suspect a few bayes-based techniques could have auto-moderated most noise out of most Usenet groups pretty effectively.

But can AI stop politicians like Cuomo from censoring unpalatable speech (Usenet/Reddit/Voat) to death?</comment></comment>


Flaky: datatypes for real world quantities - <AUTHOR> http://dimaborzov.com/flaky-hn.html

<comment><USER2> This is a terrible idea. This is a catastrophically bad idea. How do you compare numbers? How do you figure out that 2.2 is less than exp(65)? You have to represent these as numbers at some point in the calculation, and in order to do that, you're probably going to be using either floating point or fixed point, which means it's still trivially possible to construct an error case that suffers the exact same problems normal floating point numbers have. Observe:

        x=1
        for(i=0;i<n;++i)
          x=0.01+sqrt(x)

You can't simplify this, so it will simply loop until it hits the datatype boundary, and then get rounded into oblivion, because the underlying floating point representation will break in the exact same way. The only way to get rid of this would be to use an arbitrary number of bits for precision, in which case... just use an arbitrary precision library instead! This is _EXACTLY WHY WE HAVE THEM_.

Most equations that aren't trivial cannot be simplified. This datatype would only be useful for spoon-fed high school math problems. Furthermore, it costs so much CPU to perform you might as well just use an arbitrary precision library, which will probably be faster and be just as effective at preventing edge cases.

<https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic>

<comment><USER3> Actually, it's a pretty interesting idea. He basically wants to keep track of the last n operations with every given number and take advantage of this history to try to minimize the floating point error. To compare 2.2 with exp(6.5) or anything else you just evaluate the expression, but taking advantage of possible reorderings or simplifications.

Your critique really boils down to:

 _Most equations that aren't trivial cannot be simplified._

but this is not true, just take a look at what Wolfram Alpha or Mathematica can do.

<comment><USER2> If you have an equation in your program that can be effectively simplified, you should have simplified it before writing in the first place. The thing about equations that can be simplified is that 99.9% of the time, they can be simplified _at compile time_.

If you want to write a library to do it for you, great! But don't advertise it as a replacement for floating point number representations, because it isn't.

<comment><USER4> He want more than compile-time simplification. He wants runtime simplification depending on the values encountered at runtime. For example in the quadratic equation.

And, he clearly isn't marketing it as a replacement for floating point. He says: "It is important to note, however, that the goal of the project is to make tools for symbolic calculations, not to create a viable alternative to the floating point." and he talks a lot about estimating numerical error and precision.

<comment><USER3> He says this about SymPy...

<comment><USER4> oops you're right. Nevertheless, he clearly intends to extend rather than replace floating point since one of the goals is to estimate the errors in the floating point calculations, and he rounds.

</comment></comment></comment></comment></comment></comment><comment><USER5> > Floating point datatype is the de-facto standard for real world quantities. > Whether it is a banking account [...]

Is there any bank which uses floating point for accounting?

<comment><USER6> A huge number of ecommerce sites do. (Such as almost every site based on ATG/Oracle Commerce)

Most banking systems predate standardized FP and use fixed decimal representations.

<comment><USER5> I can see them being used by the quants for fast pricing. But really, for accounting? Where do the missing cents go?

</comment></comment></comment><comment><USER7> related: there is a short series of exercises in SICP that explore the idea of building an interval arithmetic library. i.e. numerical values are represented by intervals [a, b] which encode their uncertainty/error:

[http://mitpress.mit.edu/sicp/full-text/book/book- Z-H-14.html...](http://mitpress.mit.edu/sicp/full-text/book/book- Z-H-14.html#%_sec_2.1.4)

Exercise 2.14 and onwards point out that two expressions that are algebraically equivalent for perfectly accurate values stop being equivalent once we introduce uncertainty. This is only for a toy example expression with 2 variables. Suppose we want to solve a linear system of equations in 100s of thousands of variables. Is it tractable to track the uncertainty for all of those variables at once? Will their uncertainties be dependent? ...

<comment><USER8> aye, this matches my intuition: having a lower bound and an upper bound (as rational numbers) on each value means you can:

\- go back and improve if necessary, or otherwise \- express the uncertainty of a comparison

thanks for the link :)

</comment></comment><comment><USER9> Possibly of interest: the Frink programming language has arbitrary precision math and unit of measurement tracking, and has been around for more than a decade.

<http://futureboy.us/frinkdocs/index.html>

</comment><comment><USER10> Interesting take on floating point problem, but it seems as if writer isn't well versed on the centuries old solution of this problem, namely refinement calculations for lin algebra and more general iterated numerical methods for nonlinear systems -- and those are the places where the precision matters, where you are trying to calculate a figure with a given accuracy.

Note however, that solutions to many problems may in a sense 'non-analytic', there may be no finite set of elementary functions on a given rational number which yields the solution.

Also, iterative answers are usually the only viable way to reach solutions, they're usually much faster than the exact solution (or the floating point precision limited solution), and you can always control how good your solution is.

Observation: So in a sense what is practically used may indeed very close to the Kolmogorov complexity of the solutions - the representation as R=IterativeProblemSolve(Problem,ClosestSolution), where we publish the problem and the desired solution! (assumig we are efficiently describing the problem)

</comment><comment><USER11> Floating point is not so bad. Yes, when you need fixed precision, such as in accounting, you should avoid it. But with numerical computations, if you run into problem because of float limitations, you're doing it wrong.

The first rule of numerics is not to compare variables of very different magnitude. His first example has coefficients that differ by almost 200 orders. This example is totally outrageous, but still, what any reasonable person would do is introduce some scaling into the equation.

Yes, you have to think about scales, but you already do that. You never write programs with meters and seconds, you choose scaled dimensionless quantities. And unless you choose the scales very badly, you won't get any problems from floats.

</comment><comment><USER12> Hard to comment without seeing more concrete examples of his approach. But it makes me wonder whether processors are now so fast that, for a large class of numerical problems, the default should be to give up calculational speed in return for eliminating some of the trickiness involved with floating point.

</comment><comment><USER13> How about continued fractions? Unlike floating point, they can represent any rational number in finite memory. Using generators, you can even represent many irrational numbers, like square roots and pi, in finite memory.

Richard Schroeppel and Bill Gosper explored continued fractions in the '70s:

<http://www.inwap.com/pdp10/hbaker/hakmem/cf.html>

<comment><USER10> What's special about representing rationals in finite memory? By definition they can be represented by two finite integers. There are many ways of describing irrational numbers in finite memory if you allow this kind of generalization, e.g. make a datatype to represent equations and numbers as solution to the equations.

</comment></comment><comment><USER14> What we need is an open-source alternative of Mathematica's core language.

<comment><USER15> well, off the top of my head, there's GNU Octave.

<comment><USER9> that'd be matlab not mathematica

</comment></comment></comment><comment><USER16> Maybe it's just me, but saying that something in current use in billions of computers around the globe is . . . somewhat of a stretch of the word "obsolete."

<comment><USER17> In this case "obsolete" may be the relevant term as in Automobile coach builders, meet the Buggy Whip makers. The two did co-exist in the early 1900's so the alternative, "outmoded" didn't happen overnight. But it did eventually happen.

The numbers, in the billions, of course weren't there, but my guess is that the proportions are applicable.

Edit: After reading the article, I _strongly_ disagree this approach is "better" in any sense of the word. More along the lines of using whale oil for the automobile instead of gasoline. Gasoline isn't perfect, but it works. Until we have something better (I.E. Electric), I'll stick to that.

</comment></comment><comment><USER15> floating point will never be obsolete, it is a log scale datatype, and log scale datatypes represent most natural values perfectly.

The only place where the shoe doesn't fit is where you need a minimum accuracy. In that case what you should be doing is using integers to represent your minimum quantifiable unit.

For example, you could represent currency in millicents to give you respectably accurate rounding. Not accurate enough? Microcents then. Now you don't have enough range? Good, you're thinking about your requirements now, floating point DEFINITELY wouldn't of worked.

<comment><USER18> In addition you must prevent overflows.

Microcents with signed long long (64bit) means a maximum value of 2 __63 / 100 / (10 __6) = 92233720368. In words "92 billion", which might not be enough.

<comment><USER6> In environments with exhaustive partitions and automatic 'promotion' (i.e., Common Lisp but probably not Ruby, etc.), your overflow would result in a correctly calculated bignum.</comment></comment></comment>


SDCC – Small Device C Compiler - <AUTHOR> http://sdcc.sourceforge.net/ <comment><USER2> SDCC is the only FOSS compiler for PIC microcontrollers. Microchip's XC8 compiler has a free version that's deliberately crippled (optimizations disabled, garbage instructions added to slow your code down) and a license for the full optimizing compiler costs $1000. SDCC does a decent job, though it has its quirks, and may not support the newer architectural features of the latest PICs.

One reason the Arduino project was so successful is that it was built on a microcontroller platform (Atmel AVR) which, unlike PIC, has a fully open- source GCC toolchain.

<comment><USER3> Is there any reason to use PIC instead of ARM these days? On the low end, 32 bit arm microcontrollers can be had for ~ 0.50 USD in modest quantities (digikey minimum order quantity in the thousands).

It's not like there is a shortage of compilers for the various ARM architecture revisions (though the BSP support may be lacking in the hobby market).

<comment><USER4> There's lots of other factors besides compiler support and cost. There are some PIC devices with extreme low-power states that ARM can't really touch.

It's also pretty common for special-purpose devices to include a small general purpose core. For example the TI CC2541 BTLE module includes an 8051.

<comment><USER3> Good point re: general purpose cores in devices whose primary purpose is other things. I've been spoiled by the ability to choose parts that don't go quite so retro for the CPU in my own designs.

Regarding power, is the difference all that great? some googling shows that there are cortex M3 devices that use 0.3 uA in standby. Do the PICs have some features that make standby mode more useful, or do they have significantly lower power draw in sleep mode?

I've never had to deal with low power draw in standby/sleep mode outside of FPGA-based designs, so I'm curious to know whats out there.

</comment></comment></comment></comment><comment><USER5> I recently used some version of SDCC as a part of the old GBDK. It did produce working binaries, but only after some significant coaxing to avoid internal compiler errors. It might be attributable to GBDK's old SDCC fork, but it really wasn't a pleasant experience and took a lot of guesswork to get things working (separate code into two functions? ICE! reorder two variable names? ICE! nested conditionals? ICE!)

</comment><comment><USER6> Big thumbs up for this compiler!

I've been using it to develop my z80 trs-80 star trek game. I constantly check the code output to ensure it hasn't done something silly, but it all looks good. massively better than writing assembler by hand, and i would say better too.

[https://github.com/voidware/trek14](https://github.com/voidware/trek14)

<comment><AUTHOR> I like a lot your "Precision doubler":

[https://github.com/voidware/dp/blob/master/dp.h](https://github.com/voidware/dp/blob/master/dp.h)

You gave me an idea for multiprecision numbers with variadic templates (like tuple<> with head/tail).

Thank you!

</comment></comment><comment><USER7> What benefit does SDCC have over GCC for most embedded development? And if it's the only FOSS compiler for PICs, why hasn't someone ported parts of SDCC's backend over to LLVM or GCC?

<comment><USER4> It has a few compiler extensions that are very useful for small embedded development, but GCC won't add (eg an "at" keyword to let you place a symbol at a specific address).

As for "why" nobody has done it, it's probably just because nobody has. The targets are mostly 8-bit devices with limited resources and SDCC is good enough. Typically the vendors have their own paid toolchains. I don't really know how well GCC would perform on those targets (although AVR8 uses GCC).

<comment><USER7> Yeah, I can get that. When I was working with SDCC, I really would have preferred GCC or clang - SDCC has some funky quirks that really pissed me off and introduced some weird bugs.

And yeah, AVR8 (and IIRC 16 and 32) have GCC toolchains as well as avr-llvm, which is pretty sweet.

<comment><USER8> >AVR8 (and IIRC 16 and 32)

What's AVR16, may I ask?

</comment></comment></comment></comment><comment><USER9> I used SDCC for a project that targeted an 8051 CPU. Its not fancy but it gets the job done.

<comment><USER10> We also used SDCC for teaching embedded devices. We deployed the compiled hex into simulation software called Proteus - it's a weird combination of schematic capture / pcb design / realtime circuit simulator supporting analog, digital and programmable components.

SDCC worked very well in this environment. Students could easily download it to work from home without any environment dependencies or license issues. Error messages were descriptive. Our customization needs were nicely solved by some compiler flags. All in all it was a good choice.

</comment></comment><comment><USER11> You can use it to hack old credit card terminals: [http://jhallenworld.blogspot.com/2012/08/reverse- engineering...](http://jhallenworld.blogspot.com/2012/08/reverse-engineering- verifone-zon-jr-xl.html)

</comment><comment><USER12> I used SDCC to write C code for an 8-bit home computer that never officially supported C, it was fun:

[http://floooh.github.io/2014/11/09/new-adventures- in-8-bit-l...](http://floooh.github.io/2014/11/09/new-adventures-in-8-bit- land.html)

It was a fun project, but for 'real world code' that needs to fit into a few hundred bytes and needs to be fast, directly writing assembler code is the only choice on 8-bit CPUs.

</comment><comment><USER13> SDCC is also nice for dev on old (80s) platforms like Z80; that's what a lot of retro machine C aficionados use it for.

</comment><comment><USER14> If it's a compiler with Z80 target, has anyone ported this to the Z80 based TI calculators?

</comment><comment><USER15> Remember those silly cheap <$5 picture frames you find in $2 shops, or as a free bonus online sometimes? You probably have one lying around.

If it uses an AX206 chipset, you can flash _whatever code you like_ onto them with an SDCC-based toolchain.

You get a color LCD with at least 128x128 resolution (some cool devices are 320x320), and MENU, LEFT and RIGHT keys for input. Perhaps best of all, they have a bootloader, meaning burning the wrong code into Flash is completely recoverable :D

There are a couple basic firmware images that come with the toolchain - one to let you control the LCD from Linux, and one that dumps CPU registers in real time (for debugging) - so it's very easy to get started.

Vague high-level overview: [http://picframe.spritesserver.nl/wiki/index.php/DPF_with_App...](http://picframe.spritesserver.nl/wiki/index.php/DPF_with_AppoTech_AX206)

SVN repo: [http://sourceforge.net/p/dpf- ax/code/HEAD/tree/trunk/src/](http://sourceforge.net/p/dpf- ax/code/HEAD/tree/trunk/src/)

If you have a device and want to play with this, I recommend cloning the SVN repo and pouring over the readme file inside, which covers backing up your stock firmware, identifying your device model so you know which firmware to build (and if it's an AX206 at all - moment of truth :P), and reflashing. It only takes about 30 minutes to feel like you've read everything thoroughly enough and execute a reflash.

There are some conflicting bits of information and link-rot here and there, but I'll say this: I know zero about low-level device hacking, and I managed to get this installed onto a cheap picture frame I had lying around within a few minutes. I also managed to fully recover from a bad flash run too.

My DPF currently sits on my bedside table with the debug firmware on it (you enable the debug code via a config file change); the sole reason I've done nothing with it (tetris! breakout! space invaders!! :D) is that the buttons on mine are on the back :( (why??? >.>)

So, the project and code actually does do what it says on the tin, and the hardware is _very_ resilient. :D

Note that some picture frames are based on the ST2205u or ST2203u, which use a 6502 core (the AX206 uses a MCS-51 aka 8051 core). This is quite different, with no SDCC toolchain; you'll need to know 6502 asm for these, I think. There does appear to be some LCD-control firmware available for these which you could work from but the AX206 is much easier to start with I think.</comment>


MacOS Unified Log: why, what and how - <AUTHOR> https://eclecticlight.co/2018/03/19/macos-unified-log-1-why-what-and-how/ <comment><USER2> On the one hand, logs seem clearly more capable. On the other, every single change they made was objectively worse when debugging.

I have a multi-process tool, and subprocess logs no longer appear _at all_ (much less in chronological order with parent process messages) so in a separate window I must set up a log stream specially configured to try to dredge those up.

They have this notion of "privacy" in logs now, meaning even the messages you _do_ see will frequently withhold vital details unless you remember to first change settings to show private data.

I have a few side commands and short-cuts in the shell to fiddle all these knobs. It's just annoying, frankly; it's like someone replaced the steering wheel and dashboard of your car with "request steering control" and "request speed info" buttons.

And to top it all off, for like a month their fancy new logs spat out "Month 13" complaints, despite being improved. I couldn't find ANY way to turn those off with the 4,000 new knobs available to me.

</comment><comment><USER3> It's not really clear if the author views this as an improvement. To me, it seems like needless churn - another reason I'd like to get off Mac.

<comment><USER4> IT kind of is... I'm using several Adobe products at work (automating InDesign Server, I know, ewww), so it's windows or mac... running mac for laptop, work laptop is also a mac... my desktop is now a hackintosh.</comment></comment>


Building a lock free continuous ring buffer in Rust - <AUTHOR> https://ferrous-systems.com/blog/lock-free-ring-buffer/ <comment><USER2> Looking at this blog-post more carefully... I'm not convinced that this ring buffer is actually correct unfortunately.

> buffer.write.store(buffer.write.load() + write_len)

This is... an atomic load, followed by an add, followed atomic store.

A TRUE lock-free queue would be buffer.write.AtomicAdd(write_len), (which is a singular, atomic add).

There are many other issues here, but this is the most egregious issue I was able to find. The whole thing doesn't work, its completely non-safe and incorrect from a concurrency point of view. Once this particular race condition is solved, there's at least 3 or 4 others that I was able to find that also need to be solved.

EDIT: Here's my counter-example

        write = 100 (at the start)
        write_len = 10 for both threads.

        |</comment><comment></comment><comment></comment><comment></comment><comment></comment><comment>-----|
        |   Thread 1      |   Thread 2      |
        |</comment><comment></comment><comment></comment><comment></comment><comment></comment><comment>-----|
        | write.load (100)| write.load (100)|
        | 100+write_len   |                 |
        | write.store(110)| 100+write_len   |
        |                 | write.store(110)|
        |</comment><comment></comment><comment></comment><comment></comment><comment></comment><comment>-----|

        write = 110 after the two threads "added" 10 bytes each

Two items of size 10 were written to the queue, but only +10 bytes happened to the queue. The implementation is completely busted and broken. Just because you're using atomics doesn't mean that you've created an atomic transaction.

It takes great effort and study to actually build atomic transactions out of atomic parts. I would argue that this thread should be a lesson in how easy it is to get multithreaded programming dead wrong.

\</comment><comment>---

For a talk that actually gets these details right... I have made a recent submission: [https://news.ycombinator.com/item?id=20096907](https://news.ycombinator.com/item?id=20096907) . Mr. Pikus breaks down how atomics and lock-free programming needs to be done. It takes him roughly 3.5 hours to describe a lock-free concurrent queue. He's not messing around either: its a dense talk on a difficult subject.

Yeah, its not easy. But this is NOT an easy subject by any stretch of the imagination.

<comment><USER3> The article is discussing an exclusive-writer, exclusive-reader ring buffer. Interleaved writers is intentionally not considered.

> A common strategy to reduce the amount of coordination that needs to happen > between the two threads (writer, reader) is to associate each coordination > variable (pointer) with a single thread that has exclusive write access to > it.

<comment><USER2> > reduce the amount of coordination

Interesting premise, but it doesn't hold up to scrutiny.

1\. They have three shared variables.

2\. Those three shared variables are being falsly shared in that data- structure.

        struct ContiguousAsyncBuffer {
          buf: *mut u8,
          len: usize,
          read: AtomicUsize,
          write: AtomicUsize,
          watermark: AtomicUsize,
        }

Look at that struct, all of the atomics are inside the same 64-byte cache line!! That's the worst sharing possibility imaginable!

3\. Therefore: the dumb-and-simple "Mutex / Spinlock" would actually have less sharing (share only a ONE variable: the mutex), without any false-sharing of various atomic variables.

\</comment></comment></comment><comment>---

I kid you not: a "lock/unlock" queue probably performs better than the atomic thing they did here (and the atomic-thing they're doing doesn't even work correctly).

<comment><USER4> You keep on stating that the their queue doesn't work but you have yet to provide any correct arguments or evidence that it doesn't work.

The only argument you provided was simply incorrect as the article is only concerned with a single reader and writer.

You are right that adding some padding might improve performance.

<comment><USER2> Using a spinlock / mutex would improve performance if we're only talking about 2 threads. That's the main problem. Spinlocks are also much, much, much easier to think about.

Frankly, the only reason why this implementation "works" is because they're taking advantage of SeqCst, and the article spends absolutely no time talking about why SeqCst is the cornerstone of this implementation.

They actually don't need to use atomics at all when restricted to 2 threads. They just need the seq-cst. Atomics entirely are irrelevant in the 2-thread case.

\</comment></comment></comment><comment>----

In any case, code like:

> buffer.write.store(buffer.write.load() + write_len)

This is horribly, horribly, horribly bad code. This is bad, really bad, no one should be encouraged to write code like this.

Yeah, it ends up being correct because of SeqCst and the very specific assumptions of the blog post. But is that really a victory worth talking about?

This kind of code should NOT be encouraged. The reason why its "correct" is incredibly subtle and complicated. Its incredibly difficult for me to even put it to words why this seems like it'd work... without giving a ton of links to various memory-consistency talks and papers.

<comment><USER5> I'd love to see a competing version with benchmarks.

I'm not saying you're wrong. But your making a lot of strong arguments without any evidence. Is 3 atomics on the same cache line a legit problem? I don't know! But you're gonna have to prove negative behavior for me to integrate that knowledge into my workflow.

<comment><USER2> > Is 3 atomics on the same cache line a legit problem?

This is a commonly known problem called false sharing. [https://en.wikipedia.org/wiki/False_sharing](https://en.wikipedia.org/wiki/False_sharing)

To be fair: I don't know how these particular atomics work, maybe they're all on their own cache lines, and 192 bytes are used up for those three atomics so that things are done properly (unlikely, but possible). But atomics in my experience usually assume the "external" programmer figures out the buffering issue to prevent false sharing.

2\. These are atomics declared to be SeqCst memory ordering. That means the L1 (and probably L2) caches are flushed every time you read or write to them on ARM systems. (x86 has stricter guarantees and almost "natively" implements SeqCst, so you won't have as many flushes on x86). The cache must be flushed on EVERY operation declared SeqCst. Its absurdly slow, the absolute slowest memory model you can have.

3\. Well-written spinlocks are absurdly fast. Benchmark them if you don't believe me. The assembly in x86 is

        Lock:
        while (AtomicExchange(spinlock, true) != false) hyperthread_yield(); // loop until you grab false.
        acquire_barrier(); // Prevent reordering of memory

        Unlock:
        release_barrier(); // Prevent reordering of memory. NOP on x86 but important in ARM / POWER9
        spinlock=false; // Don't even need an atomic here actually

Literally one assembly instruction to unlock, 3-assembly instructions to lock (the atomicexchange + loop) + hyperthread_yield if you wanna play nice with your siblings (reduces performance for you, but overall makes the whole system faster).

From a cache-perspective, the spinlock will play nice with L1 cache (if a thread unlocks, then locks again before a new thread comes in, it all stays local to L1 and no cross-thread communication occurs).

So pretty much every aspect of the hypothetical spinlock implementation is faster in my mind. I don't really need to benchmark to see which one is faster.

EDIT: At bare minimum: because the Spinlock will be properly written using Acquire / Release half-barriers, they will be ABSOLUTELY faster than SeqCst Atomics. You'll need to use Acquire/Release Atomics if you want to "keep up" with the Acquire/Release based Spinlocks.

<comment><USER5> > I don't really need to benchmark to see which one is faster.

I know that iterating an Array is radically faster than iterated a LinkedList. But I also know this because I've seen the difference first hand. Countless times over the years in fact. I even have a bit of a gut feeling for how much slower it can be.

This case I don't have the same level of experience. I'm sitting in an airport on my tablet right now. So I can't throw any quick benchmarks together.

Suffice to say I very much would like to see an actual for reals comparison. Because I haven't dealt with this before and even if I'm convinced one way is faster seeing is believing! Performance benchmarks are almost always surprising.

Edit: from Reddit here is a different spsc-ringbuffer that may be more to your liking! [https://github.com/polyfractal/bounded-spsc- queue](https://github.com/polyfractal/bounded-spsc-queue)

<comment><USER2> If you have spare time, the Pikus talks at CPPCON talk about the performance hits associated with various primitives.

[https://www.youtube.com/watch?v=9hJkWwHDDxs](https://www.youtube.com/watch?v=9hJkWwHDDxs)

This is the one you want, with benchmarks associated with everything. Of course, benchmark on your own system too, and learn hardware performance counters (!!). This sort of stuff gets into nanosecond-level measurements, so learning to use the hardware profiler of your CPU really, really helps to see these details.

Honestly, because of how intricate the L1 / L2 caches can be on a modern system... learning hardware performance counters while you're measuring benchmark code / benchmark tests like this is helpful.

</comment></comment></comment></comment></comment><comment><USER6> Although dragontamer's complaints are mostly correct, I think he's being a little uncharitable and is largely missing the point.

Yes, writing lock-free code that's generic, that supports many-to-many reads/writes, and that's correct on all architectures is hilariously hard, and most people should not try to implement these from scratch at work. Other approaches can be more performant, and can have acceptable trade-offs for most use cases.

Are there issues with this one? Maybe. As dragontamer stated multiple times, this stuff is pretty hard to reason about.

HOWEVER, this ring buffer was designed to run on embedded systems. As usual, the constraints are often a little bit different when you're writing software for a microcontroller.

As an example, let's imagine you have periodic bursts of data coming in on a serial port at 2 Mbps, and your microcontroller is running at 32 MHz. Also, your serial port only has a 4 byte hardware buffer, and the cost of missing a byte is... I don't know, sending an endmill through the wall.

You can absolutely make this work, and you can even formally verify that you'll always meet timing, but you're going to have a really hard time doing this if you also have to analyze every other piece of code that will ever try to acquire that lock. A single-producer, single-consumer, lock-free queue with fixed message sizes can be implemented correctly in about 20 lines of C. It has a lot of annoying constraints, and you still have to use atomics correctly, and you still need a memory barrier, and don't even think about resetting the queue from either thread, and... (etc).

But if you're careful, a queue like this can make an otherwise impossible task relatively manageable. I can no longer count the number of times a construct like this has saved a project I was involved with.

Would it automatically run correctly and at full performance on a Xeon running Linux? Fuck no. But that's not the point.

The desirable quality of lock-free queues for embedded systems is correctness, not performance.

<comment><USER7> Can you give the 20 lines of example code? Would really love to see some modern atomics code.

<comment><USER6> Okay, not quite 20 lines, but something like this:

[https://gist.github.com/ohazi/40746a16c7fea4593bd0b664638d70...](https://gist.github.com/ohazi/40746a16c7fea4593bd0b664638d7017)

I've dressed it up to look like C11, but vendor specific macros from your microcontroller support library are more common. I think you can relax some of the memory ordering too, but I don't remember the details off-hand.

Also, sometimes you can have a modified version of queue_push / queue_pop where a DMA handles the memcpy and then you only have to update the pointers in the cleanup interrupt (along with configuring the next or next-next DMA if the queue isn't full / empty).

<comment><USER8> The atomic_signal_fence in queue pop/push seems suspicious. Unless you are doing something like asymmetric fences or actually synchronizing with signal handlers you probably want atomic_thread_fence. Still I'm not sure why you want a fence at all there. Publishing is done by the atomic_store to queue_rd and wr which already include (I'm being fast and loose here) the equivalent of a seq_cst fence.

<comment><USER6> The reason you want a barrier there is to make sure the memcpy and the pointer update don't get reordered so the other thread doesn't have a chance to access that block before it's ready.

You don't actually need any synchronization with the other thread, which is why I _think_ this can work instead of atomic_thread_fence. But you could be right, anyone using this should check this carefully.

Edit: I think you're right. If it is needed, it should be a thread fence. I'm not 100% clear on whether the pointer update takes care of this, so it may not actually be needed.

<comment><USER8> The block is 'published' when the store to the write pointer is performed. That's a store release which will have an implicit barrier _before_ the store.

<comment><USER6> Okay yeah, you're definitely right. I didn't realize that the stdatomic load/stores were by default seq_cst. The libraries I'm familiar with have macros for standalone atomic reads and writes, but you have to place any barriers manually. If you were using a library like that, you'd place them in between the memcpy and the pointer update, but here you get that for free.

</comment></comment></comment></comment></comment></comment></comment><comment><USER9> >This is the story of how Andrea Lattuada (PhD student at ETH Zurich) and James Munns (from Ferrous Systems) designed and implemented (two versions!) of an high-perf lock-free ring-buffer for cross-thread communication. _If any of those words look scary to you, don 't fret, we'll explain everything from the basics._

This is not the message I want to see introducing such a complex topic. Writing correct lock-free code is _incredibly_ hard, and you're _not_ going to get it right or even understand it from a single post. I've done a bit of reading on this subject, and I'm not even sure that it's possible to write a correct lock-free queue (of which this is a variant) in a non-garbage collected language without some pretty substantial trade-offs regarding memory management.

<comment><USER2> Pikus does it. I made a post about it. [https://news.ycombinator.com/item?id=20096907](https://news.ycombinator.com/item?id=20096907)

The talk is 3.5 hours, about as long as you'd expect one to be for "writing a concurrent lockfree queue". Its an incredibly difficult topic, but I'm convinced that Pikus's implementation is actually correct.

Although, maybe there's a subtle bug somewhere. And Pikus is REALLLY stretching the definition of a queue to make his implementation work. (This queue may sometimes function like a stack, but that's okay because there's no way for the end programmer to figure it out without a global lock)

\</comment></comment><comment>---

EDIT: Oh, I guess you wouldn't consider it "truly lock free", because he has a global lock in the case of the rare situation of a full queue. He uses double- checked lock pattern for that case (and causes an expensive, but temporary, global lock on the data-structure) and basically says "This situation only happens once per hour, so its probably not bad".

So Pikus's implementation is "lock free mostly", but still falls back to a global spinlock in exceptionally rare corner cases.

<comment><USER9> Oh, that's actually a different lock-free talk from Pikus than I expected. I haven't it watched yet. Thanks!

I probably wrote my original comment a little too quickly. Yes, it's possible to write useful mostly lock-free data structures, but it's hard enough that I consider anyone claiming to have done so in a way that beats the equivalent locked structure (as you pointed out above) to be making an extraordinary claim that requires extraordinary evidence and serious consideration of the difficulty involved.

<comment><USER2> > I probably wrote my original comment a little too quickly.

Nah. Anyone who actually understands this subject recognizes that a truly lock-free concurrent queue is probably one of the most difficult problems in all of Comp. Sci.

Even if you're using absolutes, its basically warranted because of the difficulty of the problem. No one will blame you for talking about how hard this problem is, even with a bit of hyperbole being used

</comment></comment></comment><comment><USER10> I implemented such a buffer in 2006. It was used for fast message passing from user space to the kernel. When a message was too large to fit at the end of the circular buffer, a zero-length message was placed into the remaining space; that indicated "wrap to the beginning". It's so obvious, it must have been implemented numerous times by others before me.

If I were to implement the same thing again, I would just split the messages and use scattered writes ( _struct iovec_ ) to process them. I cannot remember exactly, but I think the only reason the messages were linear was just for the kernel thread to be able to write them out in a single call.

Oh wait, now I remember; I think the buffers were linear due to the production side: sprintf being used to produce some of the message payloads, and that requiring a linear buffer. But of course it's possible to support both wrapped messages and the "tail space not used" indicator.

<comment><USER11> I was wondering about having a special message to indicate the end of the buffer while reading the article, so thanks for pre-emptively answering my question!

Another thing I was wondering about is using a simple buddy allocator with the ring buffer being just a list of pointers. There would be a second ring buffer to send memory back to the producer to be freed, and you would statically allocate enough memory so fragmentation doesn't affect the particular application---you know each message has a limited lifetime, for instance. (The allocator would not be shared between different ring buffers.)

Then again, I don't see any benefits to doing this.

</comment></comment><comment><USER12> You can make wrapping writes look contiguous by mapping the same memory twice, one after the other. This is done in slice-deque such that the entire buffer can be viewed as a contiguous slice, regardless of the start/end positions.

[https://crates.io/crates/slice-deque](https://crates.io/crates/slice-deque)

<comment><USER13> This trick may break ordering and cache aliasing rules on many architectures. If you're dipping into this kind of thing, it needs per-architecture whitelisting.

<comment><USER14> I'm not sure about the ordering part, but about "cache aliasing rules" \- can you give some details? This situation can be trivially set up via mmap, so if that breaks it would seem to be a problem?

I understand that aliasing is an issue when it comes to hardware design, but the practical need to support systems that allow this to occur means that all major architectures I'm aware of support transparent V->P aliasing, either by having their caches physically indexed, _effectively_ physically indexed like VIPT or some strategy where V is used to look up the way in L1 but misses due to aliasing will be resolved in the L2 (i.e., aliasing "works" but is slow), or some other similar strategy.

I would be curious what systems don't work this way.

Note that I'm talking only about data - systems definitely have all sorts of rules about modification of instruction-containing pages.

</comment></comment></comment><comment><USER15> Also important, not using a power of two sized ring is leaving lots of optimization on the table.

<comment><USER16> Eh, maybe/maybe not. This implementation requires a family big boy CPU with a really MMU; I'd be willing to bet that most of the extra latency of the divides are hidden in the memory access latencies.

<comment><USER17> There are two implementations described in this blog post and one of them is specifically designed to run on microcontrollers.

</comment></comment></comment><comment><USER18> Reminds me of the LMAX architecture.

Slides of a talk I gave about LMAX

[https://www.slideshare.net/Stephan.Schmidt/lmax- architecture...](https://www.slideshare.net/Stephan.Schmidt/lmax-architecture- jax-conference)

</comment><comment><USER19> What is considered the bible on lock free programming?

<comment><USER20> I don't think there is one, yet. 'Multiprocessor Programming': [https://www.amazon.com/Art-Multiprocessor-Programming- Revise...](https://www.amazon.com/Art-Multiprocessor-Programming-Revised- Reprint/dp/0123973376/) has some algorithms, though.

</comment></comment><comment><USER21> I'm guessing this still uses locks, but at the CPU/cache level instead of inside the algorithm.

<comment><USER22> I've always thought "lock free" was a misnomer for this kind of thing because they use multi-stage atomic instructions which obviously require some kind of implied locking. I'd probably call them "non-blocking".</comment></comment>


Anomalyzer – An Anomaly Detection Package - <AUTHOR> http://www.getlytics.com/blog/post/check_out_anomalyzer <comment><USER2> I'm not a statistician, which is why I really like this kind of approach. It feels "FiveThirtyEight" trustworthy to me – a weighted average of different opinions.

The claim that it "dynamically adjusts the weight of each algorithm according to the amount of information it contains" is a bit hyperbolic, though. The "weight" function is explained in the code this way:

"If either the "magnitude" [or] "fence" methods don't have any probability to contribute, we don't want to hear about it. If they do, we upweight them substantially."

Regardless, this is unquestionably a great foundation to build into your own systems. Perhaps not as turn-key as the blog suggests, but still a wonderful contribution.

</comment><comment><USER3> Has anyone played with Anomalyzer yet? I'd like to get the anomaly probability for every data instance of a CSV but it's unclear to me if this is possible. I want to run it on the Numenta Anomaly Benchmark dataset ([https://github.com/numenta/NAB](https://github.com/numenta/NAB)) to see how it compares to other anomaly detection algorithms.

</comment><comment><USER4> Looking at your examples, seems like this is a changepoint package more than anomaly detection.

There's a fair amount of user input here (still) - picking weights and thresholds is a nontrivial task.

<comment><USER5> Fair point.

If you're interested in the changepoint detection use cases, we have a package for that, too. :)

[https://github.com/lytics/impact](https://github.com/lytics/impact)

</comment></comment><comment><USER6> Super cool. Now I can organize a statistical hierarchy of anomalies and assign to appropriate workers!

<comment><USER7> You could also set up a statistical hierarchy of workers to blame for you anomalies.

<comment><USER6> touché</comment></comment></comment>


Ask HN: REJECTED. Would you be willing to contract-to-hire? - <AUTHOR>

If a potential software engineering candidate has  interviewed with you and you found that this person  was passionate about what it is that you're doing, but after tossing a couple of puzzles and technical questions at them, and not feeling that they're quite where you need them to be, would you be inclined to offer a contract-to-hire position if they asked (given that you'd enjoy working with this person)?
Do you think this is a decently good idea? Should a candidate ask?
Any big/well-known start-ups or companies willing to do this? <comment><USER2> It depends on the size of the company and the types of questions you are asking. Larger companies move slower and are more apt to hire people of all skill levels. Smaller companies need rockstars that will sling great code fast.

Depending on the questions, you may be asking things that don't apply. How much did the puzzles apply to your every day coding tasks? Some people don't do well interviewing or at puzzle questions but can still churn out some great finished products. You won't know until you actually try them out in the position.</comment>


Show HN: A universal iOS app for creating and sharing pixel art - <AUTHOR> http://itunes.apple.com/us/app/pixelup/id548876143

<comment><USER2> Looks nice. Going to install now. Hope you have updated the app for the new iPhone :)

<comment><AUTHOR> Thanks! Next update will take care of the new iPhone :)</comment></comment>


Autodesk Stingray Game Engine - <AUTHOR> http://stingrayengine.com/ <comment><USER2> Attempting to register for access takes you to a form that requires you to have an "Autodesk ID" without any obvious way to obtain one - it does say that existing Gameware customers can get access. Thus continues the very trend that makes me dislike Autodesk: a highly corporate, private, limited-access, secretive suite of tools that are only available to a closed club of very high paying, deeply invested customers who are locked in to a pipeline comprised of only Autodesk tools. It just feels so proprietary and exclusionary. I still remember my parallel port dongle for 3D Studio Max back when I was locked into that tool set and the many times I had to fight to make it work to earn the privilege of using tools I had already paid thousands of dollars for.

Yuck.

<comment><USER3> Pretty much this; it's like they've got 90% sales and marketing and business people running the show and the software devs are just sticking around because Stockholm Syndrome.

<comment><USER4> Actually, I took a tour of their SF office (across from the Ferry building) and it seems like a really cool place to work. If anyone gets the chance, I'd check out the little museum they have there which is open to the public. I had always just associated Autodesk with the old 2D AutoCAD software, but they're actually doing really interesting research at the company. I was really impressed. One example I saw was simulations relating to self-assembling machines/structures. And their engineering and industrial design influences make it a nice art/science mixture.

Although not necessarily intended for kids, it's a place I would have loved to visit as a 8+ year old kid.

</comment></comment></comment><comment><USER5> I'm having a hard time seeing the market for this. Most indies aren't using Maya or 3DStudio Max because the price is too high. Modo and blender are much more popular in my experience. Then shops big enough to afford them tend to have a custom workflow built in already.

My source: Could be completely wrong and is based purely on personal data. I help run a local indie game development meetup and have been involved with 3 others and only a few people were using Maya or 3DStudio Max. Mostly because of pricing. However of those working with 3D assets the majority of them are working with Blender or Modo with Unity and Unreal as the primary engines. One or two scenekit/source sdk/cryengine people thrown in there.

<comment><USER6> > Most indies aren't using Maya or 3DStudio Max because the price is too high.

Unless you define indies strictly as amateur/hobbyist I seriously doubt this. All the 3d guys i know (freelancers, small interactive studios, independent developers etc. - none affiliated to a mayor publisher) use Maya or 3D Studio Max.

It's the same as with the Adobe Suite or MS Office - once you consider labor costs, licenses become a second thought if you use something professionally and earn money doing it.

That being said, I don't really see this having a big market either, nobody seems to have any major issues integrating with unity or unreal for now.

<comment><USER7> I haven't paid much attention to Maya since Autodesk bought it, but people seemed pretty excited when the price dropped from $7,000 to $2,000. If the other comment about pricing is accurate, it sounds like Stingray is effectively bundled with Maya LT at no extra charge.

<comment><USER8> That was in 2002, right?

Yeah it hasn't gone down much since. The absolute cheapest price is a $1,470 annual subscription. A perpetual license will cost you $3,675.

I wish we had competition in that space. Maybe if Maya hadn't have sold out, we'd have something like the current price war between Unity and Unreal, which is great for games and game developers.

</comment></comment></comment></comment><comment><USER9> This was previously the Bitsquid engine. Really nice engine hope Autodesk can take the tooling to the next level!

<comment><USER10> Well that makes it more interesting. I've always been impressed with the stuff written up on the BitSquid dev blog over the years.

[http://bitsquid.blogspot.co.uk/](http://bitsquid.blogspot.co.uk/)

<comment><USER11> Yeah, they are really conscious on performance which is one of the worst parts in Unity.

</comment></comment></comment><comment><USER12> Phew. That's a market I wouldn't want to enter.

I wish them the best of luck - and I love some of Autodesk's tools - but I don't immediately see why I'd choose this over Unity or Unreal.

I hope they integrate the renderer into Motionbuilder, though. In 2015, the quality of render it's possible to pull from that tool is just embarassing.

<comment><USER13> From watching the video the two main points seem to be the seamless integration between other Autodesk tools and this one and how you don't need to be a big programmer. Maybe also the live preview.

(I don't know if this is the case with Unity etc. as I am not a game developer).

<comment><USER14> The visual scripting is provided by Unreal in terms of Blueprints natively, and Unity has a widely popular GameMaker package.

</comment></comment></comment><comment><USER15> It's probably a case of "innovator's dilemma' but I don't understand why all company making 3D software for industry haven't try to enter this market twenty years ago (maybe they is too much technical difference that I'm not aware of). It's seems too late now, they haven't a huge technical advantage any more. But competition is always good, so good luck to them !

<comment><USER16> Companies start orbiting the same market as Autodesk and Autodesk acquires them. That's been their strategy for 25 years starting with Generic CADD. #DStudio and Maya were acquisitions Autodesk didn't kill off.

The only notable exception is Sketchup. Google bought it instead, just as it went from MVP to software product line. Conveniently for Autodesk, Google pulled the critical feature out of the entry version after a year or two (DXF/DWG support), let development on the professional version languish, and eventually ejected it as a drifting hulk after Revit gained enough traction for institutions to start requiring it as a delivery format for construction designs despite Revit's file format being closed proprietary.

</comment></comment><comment><USER17> Try hitting 'esc' on this page...

<comment><USER18> That is extremely weird. Is that standard behavior for squarespace sites?

</comment></comment><comment><USER19> I like how they talk about "changing the way games are made", then go on to describe exactly the process that Unity and Unreal provide. So actually just playing catch-up to the "way games are made."

</comment><comment><USER20> Great marketing. Now how do I get it? Where is the big shiny buy/try or download link? I thought maybe the marketplace? Nope. Then I tried going to autodesk.com and I scrolled to the footer and went to the store. I did a search: [http://www.autodesk.com/store/search?q=stingray](http://www.autodesk.com/store/search?q=stingray)

The upper funnel is serious broken here.

<comment><USER21> Might want to start here: [http://www.autodesk.com/campaigns/stingray](http://www.autodesk.com/campaigns/stingray)

<comment><USER20> maybe that's why... Not even for sale yet: [http://www.autodesk.com/products/stingray/buy](http://www.autodesk.com/products/stingray/buy)

"Stingray will be available for purchase on August 19."

</comment></comment></comment><comment><USER22> One: Why does it seem all the text is in caps?

Two: Why would we want a engine with Maya or 3DStudioMax interoperability? Most indie developers would not be able to afford Autodesk products because they are so pricey. The only people I know who use Autodesk in the gaming industry are those who make AAA games. If you want to contact the least common denominator, then you need to make some changes to the way you do things.

<comment><USER23> It's not meant for hobbyists/indie developers.

</comment></comment><comment><USER24> People are wondering what the advantage of this is. It's worth noting that Autodesk have not updated their Scaleform plugin to work with Unity 5. I was pretty annoyed, and it seems like this could be the reason why.

Unity's UI got better recently (in 4.6+), but Scaleform is still leaps-and- bounds above almost anything on the market.

That, combined with Autodesk Navigation - another very powerful tool they previously charged a lot of money for (pricing for that was even on-demand only), means there's genuine reason to consider this.

The obvious downsides are the lack of free access/assets that you get with Unity, that Unity/Unreal have huge communities and years of YouTube tutorials. But that might come in time.

Perhaps the claims about performance and ease are exaggerated, but maybe they're not. I've worked with Unity for a while, and it certainly isn't perfect. There are some clunky, unintuitive things going on. Don't get me wrong, Unity is a fantastic tool, and our company wouldn't be what it is today without it, but this atleast warrants a look at, for me :)

</comment><comment><USER25> Both Unity and Unreal have free tiers, but from the site it looks like Stingray is $30/m I suppose the seamless integration pitch is an appealing angle, but I'm surprised for a new engine there wouldn't be at least a time- limited free tier.

</comment><comment><USER26> "[...] to make sure your games looks amazing".

Please note the bad collision detection at 0:51 when the player walks through the cube, right as the speaker says that.

Lol.

</comment><comment><USER27> Thanks but no thanks Autodesk. Why do I feel like Autodesk is starting to take it's cues from Oracle?

I've been working on a side project in Unreal Engine 4, which is amazing, but you'll notice that the majority of Epic devs work in Maya. Autodesk realized there was opportunity to make some money, and finally released Maya LT subscription for devs, but there are still a ton of import/export and other pipeline issues. I mean Autodesk owns the FBX format but can't get a good pipeline mechanism going for it? Now that I see this, it totally makes sense. They saw what the Epic guys were doing, probably even trolled their codebase for ideas, said "Hey, we can do the same thing but make it proprietary and cost a shit ton, just like all our other stuff, and make tons of bank! All we have to do is make sure our tools work with our tools best and everything else is subpar, and it will force devs who want those features into our camp!" Look at the damn interface, it looks almost identical in layout to UE4!

On a similar note, as a sysadmin with Autocad users, and the most recent quote I got for a single new sub license was $4k+, I am now investigating migrating to open source solutions that can perform everything we need without being licensed into the ground. Not every company has $20k just sitting around for license upgrades...

Edit: I understand my tone is negative, but in this case I think it's warranted. I would appreciate discussion instead of just a downvote please. I also took out the needlessly negative last paragraph.

</comment><comment><USER28> I wish them the best of luck but without a majot title tied to shipping with this I'm dubious.

Without a clear vision of features needed feature creep can really set in. Also different engines are built for different needs and a catchall engine ends up being not too great at anything.

<comment><USER29> I think Unity shows that there is a place for an easy to use cross platform 3d engine.

</comment></comment><comment><USER19> I saw nothing about games on that page. It was a lot about 3D rendering, but nothing about actual interaction.

<comment><USER13> You need to watch the video which has all the details.

<comment><USER19> So they continue the trend that is my main gripe about Unity and Unreal: they lock everything up in unsearchable, unskimmable videos.

</comment></comment></comment><comment><USER30> Pricing?

<comment><USER31> quick google led me to [http://www.engadget.com/2015/08/03/autodesk- stingray/](http://www.engadget.com/2015/08/03/autodesk-stingray/) \- which quotes $30/month

<comment><USER32> It also includes a copy of Maya LT.

</comment></comment></comment><comment><USER33> no download?

> AND C++ SOURCE CODE, AVAILABLE FOR AN EXTRA FEE

not a good idea to get developers.

<comment><USER34> Yeah, that surprised me too, considering that Unreal Engine is free (until you ship) _including_ source code, which is hosted on github (behind a free registration).

</comment></comment><comment><USER35> I wonder if they know about Steve Irwin</comment>


Observing Ultra-High Energy Cosmic Rays with Smartphones [pdf] - <AUTHOR> http://crayfis.ps.uci.edu/paper.pdf To sign up: http://crayfis.ps.uci.edu/ <comment><AUTHOR> To sign up: [http://crayfis.ps.uci.edu/](http://crayfis.ps.uci.edu/)

</comment><comment><USER2> arXiv link: [http://arxiv.org/abs/1410.2895](http://arxiv.org/abs/1410.2895)

</comment><comment><USER3> This is way better than my idea of looking in peoples' propane tanks.

<comment><USER4> I'd love to hear the theory behind that?

<comment><USER3> I can't help you much with theory, sorry. I'm a hardware type. The gist of the idea is that propane is good for making particle detectors[1]; and since there are propane tanks distributed fairly widely, then one ought to be able to observe lots of cosmic rays from within them. The first trouble was figuring out a way to build enough detectors, cheaply enough. I had hoped to come up with something simple that could be installed without too much trouble. Most of the good detector ideas would require the tank to be empty when the detector was installed, so retrofitting existing propane tank installations would be a super slow process. There are a lot of other problems with the idea and we had other ideas to pursue at the time so we didn't go very far with it.

[1] Bubble chambers, spark chambers, flash chambers, drift chambers / tubes, RPC's,</comment></comment></comment>


Ask HN: Feedback from Pet-Owners Please? Pet Transportation (Uber for Pets) - <AUTHOR> Would you as a pet-owner use a transportation service to take your pet from and to salon, pet-care, pet-sitting or anywhere else while you are busy with your things?<p>How much is there need for such service? <comment><USER2> My vet provides concierge service, if you want it.

They'll even come out to your house and do health checkups, etc... at your home.

But generally speaking, I love my cats, and I wouldn't want them being taken somewhere by some stranger, unless there were truly extenuating circumstances.</comment>


Attraction Inequality and the Dating Economy - <AUTHOR> https://quillette.com/2019/03/12/attraction-inequality-and-the-dating-economy/ <comment><USER2> I wonder what studies there are on what features women find attractive in order of priority. How many of those could men generally do something about?

How easy/hard would it be for a male generally to increase their attractiveness through effort - sufficient enough to compete with the existing top 20%? Or is that not possible - due to genetic fitness (or maybe environmental vars only marginally in their control - diet as children etc)?

Assuming that men COULD increase their attractiveness to compete with the EXISTING top 20% of men - would the size of the top cohort that 80% of women compete for increase? Or not? I.e. are women looking for a particular level of minimum quality that won't change much over time? Or if that 20% figure remains constant - that their desire in this respect is a relative value; relative to the overall quality of mate choices available currently.

Getting down to the brass tax questions I'm building too.

Does that 80/20 figure of women chasing men amount to a cultural fact that men are lazy in terms of trying to appear attractive? Do men find more women attractive - not because they are less choosy, but because women put more effort into being attractive? Or are women just choosy and men easy?

What drives female choosiness? If that 20% figure stays constant no matter what men do - then one explanation might be that mate choice for women is highly status driven. But something must mitigate it generally right? Outside of the tinder abstraction - women settle for less than the top 20% all the time. Don't they?

<comment><USER3> Intuitively it seems that it should be possible. Physical fitness, confidence, kindness, empathy, social standing, even appearance: these things can all to a large extent be improved through effort.

Facial attractiveness seems extremely important to both genders, and is rather difficult and expensive to change. But certainly someone with a merely average face could achieve overall attractiveness by pumping enough points into the above areas.

<comment><USER4> It seems like the study discussed skewed in terms of the dataset was sites that are picture-based primarily and thus generally perceived as geared towards hook-ups. This could also be interpreted that guys are more open to casual sex with whomever and women tend to be already compromising by agreeing to casual sex therefore looking for a higher threshold of attractiveness?

</comment></comment></comment><comment><USER5> Recently started using dating apps and also read the book 'Dataclysm', so this is a timely article. I can confirm it's all true - men are treated like second class citizens on these apps because that's just the way it is. Very average or even ugly looking women will get hundreds of messages, some of them from very attractive men, no matter what they do, so they don't do much of anything. A man with no bio, only one so-so picture, and who doesn't respond in a timely manner has literally zero chance but I see girls act that way all the time. Very commonly you see girls with bios that are nothing but a list of requirements - "6 foot, works out, nice, is funny, no hookups, follow me on Instagram if you want to talk."

I don't think there's anything we can or should do to change but it is a raw deal for guys. Also note that apps like Tinder seem very artificial and surreal (e.g. like they don't actually matter) and I do believe this skews behavior.

</comment><comment><USER6> I'll just point out that attractiveness changes quite a lot over time, as well as the importance people give to it.

Maybe whatever calculations they're doing should take age into account?

</comment><comment><USER7> Is it valid to apply the Gini coefficient math to dating as they do?

> On a list of 149 countries' Gini indices provided by the CIA World Factbook, > this would place the female dating economy as 75th most unequal > (average—think Western Europe) and the male dating economy as the 8th most > unequal (kleptocracy, apartheid, perpetual civil war—think South Africa).

<comment><USER8> Why wouldn't it be?

</comment></comment><comment><USER9> Interesting, though I do think the author is somewhat callous. There is something distinctly human, I think, about love and pair bonding and both the idea of "love at first sight" as well as the tale of "Beauty and the Beast". In my experience, there are certain women of varying attractiveness levels who seem to like me just for being me, rather than because I possess an extraordinary degree of some single quality like strength or intelligence (which would assume we strictly follow polygyny).

Of course, the desire for polygyny exists, but to assume that that is all there is to "mating" is somewhat Hobbesian. Then again, the inequality w/r/t men is somewhat inherent across time keeping in mind the "average man" gives the life vests to women & children, charges across the front into the enemy's machine gun nest, and toils the fields for their master. Hell, if you lost the war you became a eunuch and lived the rest of your life a slave. So I don't think this inequality is anything new.

Ultimately, though perhaps there's still lots of inequality in the "dating economy", I think it's better in our society than it has ever been. Most anyone can work to get in shape, or pursue their hobbies. There's no caste structure, and though some people have it easier than others (resources from parents or genetics), it's more than possible with dedicated effort to change oneself because that seems to be something people struggle hard to do. Additionally, there's more variety in our culture than ever before. Women and men can be attractive for different reasons, and so there's many groups people can fall into. There's intelligent people, athletic people, social people, creative people, spontaneous people, mysterious people, etc. Instead of there just being one group -- royalty ala Madame Bovary -- there are many different groups you can choose to be in which nets you much more opportunity than ever before.

I'm glad I was able to think through this and come out of it with an honest, optimistic take; it's too easy -- at least for me -- to be nihilistic when you see an article like this

</comment><comment><USER10> The subset of people who go on swipe left style dating sites are not a random slice of the population.

</comment><comment><USER11> This really does poke a few holes in the equity of outcomes view. Interestingly it also pokes a few holes in the unrestrained capitalism view. As we've seen society in the past restrain individuals and produce more equitable outcomes.

We've seen via enforced monogamy a society with more equitable outcomes. Was it better or worse?

<comment><USER12> It's subjective of whether it was better or worse.

We better get sex robots quick or who knows what's going to happen when more guys are more frustrated.</comment></comment>


The Industrial Design of Lenovo's X1 Carbon - <AUTHOR> http://blog.lenovo.com/design/developers-on-the-x1-carbon-industrial-design

<comment><USER2> Pics: [http://www.theverge.com/2012/5/15/3021177/lenovo- thinkpad-x1...](http://www.theverge.com/2012/5/15/3021177/lenovo- thinkpad-x1-carbon-press-pictures#3361548)

There's a few things of interest:

      - chiclet, backlit, 6-row keyboard (same as X1)
      - new, thinner connector breaking backwards compatibility
      - 1600x900 IPS
      - no ethernet, requires dock or USB dongle
      - no HDMI
      - 2x USB 3.0, 1x USB 2.0, 1x Mini DisplayPort, SD reader
      - embedded 3G

Like Apple, they ditched ethernet and old power cords for slimmer designs.

I personally do not like the chiclet keyboards, but Lenovo has switched to them across the entire Thinkpad line.

</comment><comment><USER3>
      THE THINNEST 14" ULTRABOOK™.
      THINKPAD X1 CARBON
      Less than 3 pounds
      Carbon fiber construction
      Embedded 3G connectivity
      Lenovo RapidCharge
      X1 CARBON AVAILABLE AUGUST 2012

August? Why announce it now? As if the literally 40 or 50 different models of laptop on the Lenovo website aren't already confusing enough...</comment>