Fly.js: New generation build system - <AUTHOR> https://github.com/flyjs/fly

<comment><USER2> While I love the idea, seeing `fly-*` packages makes me sad, although I understand the reasoning. Grunt had the same problem, and Gulp does to some extent, however Browserify and Gulp had the right idea where they allow you to use the direct Browserify package without requiring a wrapper. Those wrappers lag behind the actual library typically, and have their own quirks and debugging which is too much congnitive overhead at times.

That said, this is really interesting way of tackling a build system. I love the use of `exports` and generators make a lot of sense for this sort of control flow; I wrote a "block" system for Wordpress that used generators to allow you to render the blocks in a loop inside a template, pause execution of said loop and render more of the template, then continue on. Basically insertion points for completely dynamic layout and contents.

<comment><USER3> @girvo

I am sorry I missed this post.

You are not required to create packages to use Fly! You can simply pass your transformer function to `Fly.prototype.filter` and be done with it. I think plugins should be true thin wrappers to whatever utilities you are trying to incorporate into your build task.

Compare this to gulp where you sometimes need to use vinyl and other abstractions, plus stream wrappers and other deps.

<comment><USER2> Thanks for the update bucaran! If that's the case, I'm definitely going to dive deep in it; that's exactly what I've been hoping for in a next-gen build- tool (WebPack just doesn't do it for me)!

</comment></comment></comment><comment><USER4> Say what you will about the usefulness or redundancy of yet another build system, I really enjoy the way the succession of JavaScript solutions have explored different means of control flow.

I'll upvote this mostly for the clever use of exports and (ab)use of generators.

<comment><USER5> can you upvote me? i do clever usage of basic OS and node.js environment.

my build system does the same as that Flyfile and add source maps to my coffee files, looks like this: [http://pastebin.com/BtegzqVX](http://pastebin.com/BtegzqVX)

You could argue my polvo.yml file has more lines in it and it's less customisable compared to a script, but still i believe my .yml config is very organised and i can hook up any script to happen afterwards by appending a line to my beautiful makefile.

Not to say, with the "setup" target you could even install node.js or fly or whatever you need before even being able to execute fly.

<comment><USER6> Maybe share a little more? From what I see, it's basically a YAML-formatted bash script, but I suspect there's more to it, right?

<comment><USER7> It appears to be a makefile.

EDIT: or at least, for me, this yaml-formatted bash script is functionally indistinguishable from a simple makefile.

</comment></comment></comment></comment><comment><USER8> I'm glad people are pushing the envelope on JS build tooling, and not giving in to the "we need to freeze the toolspace now" contingent. I feel like the mainstream build tools have been interesting, but nobody has got it all figured out yet.

One question, if this is ES6, then why:

        exports.foo = function* () {}

...instead of:

        export function* foo() {}

    ?

<comment><USER9> The first snippet uses the CommonJS [1] standard (a way to import packages into a JS file that is used by Node, webpack or browserify for example).

The second snippet uses ES6 modules [2]. Babel actually transpiles those ES6 modules into CommonJS modules when used in a Node.js environment (which is the case with a build tool).

Since even IO.js doesn't support ES6 modules for now and you're likely to use a build tool in order to use babel, you shouldn't use ES6 modules in a build file.

[1]: [http://www.commonjs.org/](http://www.commonjs.org/) [2]: [https://developer.mozilla.org/en- US/docs/Web/JavaScript/Refe...](https://developer.mozilla.org/en- US/docs/Web/JavaScript/Reference/Statements/import)

</comment></comment><comment><USER10> Not trying to sound like a stick in the mud, since my need for Javascript build systems is modest and currently satisfied by make (think Bootstrap, jquery, uglify). After all, dependency management is a deep problem.

What is the primary advantage over make? I imagine it looks much easier to read for a novice than make, but there are probably much better reasons than this one.

<comment><USER5> i also use make, it fits really well with coffee/stylus/jade + zsh/iterm2|tmux stack...

anything different than this seems to become very messy super fast, specially compared to make files

not to say, using identantion kills a lot of stuff people use this days, like js linters and whatnot.

not saying this tools are not useful in specific circumstances, which i can happily say i never faced.

*with a "setup" target you could even install node.js or fly or whatever you need before even being able to execute fly.

</comment></comment><comment><USER11> since i switched to using webpack for bundling, i've pretty much stopped using gulp/grunt completely.

I just found there's very little I needed them for that couldn't be resolved using a makefile or package.json scripts.

I legitimately love gulp though, because it finally let me grok streams.

</comment><comment><USER12> Having used gulp and grunt, I just use shell scripts now. Why bother?

<comment><USER13> Ideally, as a means of abstracting and controlling changes between your build and deploy steps and the third party tooling. Bash scripts are either too fragile for sufficiently complex applications, and therefore unlikely to be reusable. Additionally, if the script is sufficiently complex, then you have an additional complex component that you have to maintain yourself. For many projects, this is a non-issue, but for others, it can be quite the ordeal.

<comment><USER14> Who said anything about bash scripts? There are other shell scripts in the sea. Also, shell scripting is much more universal, so you can use the same infrastructure to manage your web servers, your database servers, etc. A language-specific build system means that when you need to start adding components made in other languages, you need to reinvent a lot more tooling that should have been universal to begin with.

<comment><USER15> > Who said anything about bash scripts? There are other shell scripts in the > sea. Also, shell scripting is much more universal[...]

I guess it depends a lot on your infra, but wouldn't (ba)sh be the most universal shell? so if shell = bash, then "shell script" = "bash script"

<comment><USER16> It would. I use fish shell here, yet I prefer writing my build tasks with plain JavaScript. Fly seems to be a thin abstraction to accomplish the same. Now, the most striking advantage is support for generators/co-routine style for async stuff and also promises right from the get go.

</comment></comment></comment></comment></comment><comment><USER17> Cool, but how does this meaningfully expand on the JavaScript ecosystem? Or more succinctly, "Why not Grunt?" What features does this provide to differentiate itself from other, similar tools?

People have already gotten tired of the JavaScript framework/build system/distribution tool bang. Improvements need to be more than incremental before people will choose to learn new APIs and be able to find new package ecosystems.

<comment><USER18> You should be comparing this to gulp, which, like fly, prefers code over configuration.

Gulp uses streams, this uses generators. Some folks may like the look and feel of generators more than streams.

<comment><USER17> The point I'm trying to make is: Gulp and Grunt exist, and have strong ecosystems. It's cool that this uses a swanky new ES6 feature. But is that really a big enough step up, that people should stop using what they're using and use this instead?

If it came with a set of modules for other packages so people could at the very least try the demo version before they buy into it, and it really is that much cleaner and more powerful, then I think people could really get behind it.

The trick to making a successful JS package nowadays is marketing, honestly.

<comment><USER15> Grunt existed when gulp was new, and it had a pretty strong ecosystem. Gulp was an alternate that solved the same problem in a different way, and it got pretty popular. Because of it, the next version of Grunt is totally different and uses ideas from Gulp.

I find it disappointing how some people have such an allergic reaction to others trying something new. If you don't like it, don't use it.

<comment><USER19> I don't think he's allergic to others trying something new, I think he's just saying that _the most important information for them to provide_ when doing so is "how is my approach different to/better than the existing tools?"

Which is a valid point, IMO. When there already multiple widely-used tools that do X, marketing your new tool as "Does X!!!" isn't very compelling in itself.

</comment></comment></comment></comment></comment><comment><USER20> "Fly is a build system for Node based in ES6 generators and promises that aims to be simple and elegant to write and extend"

If an objective is for it to be simple to write and extend, why use two shiny new features that most programmers will be unfamiliar or inexperienced with?

<comment><USER21> The theory is that those shiny new features are simple to write and extend, regardless of most programmers' familiarity or experience with them. I don't necessarily agree with that theory in this case, but familiarity is too often conflated with simplicity, when in reality there is a more nuanced interaction between the two.

</comment></comment><comment><USER22> I wonder sometimes what it would be like if we didn't keep re-inventing things. Other than portability, why are any of these better than a Makefile? Most of these tools have a corresponding bin command you can run in a Make task.

<comment><USER23> I guess we'd be stuck with Make. I can't say how happy I am that that isn't the case.

<comment><USER22> What do you like about the JS build systems more?

<comment><USER24> I think it's pretty similar to why people use autoconf, Cmake or the like. If you are building something of any real size or complexity, with a lot of 3rd party dependencies, then maintaining makefiles is a serious PITA (and I say that as someone who has used make extensively in their career).

So why not use autoconf or Cmake, then? Well, why would I want to write and maintain scripts in M4 when I can do it in javascript (the language I'm actually programming in)? And again you get into the configuration vs code question. Why should I rely on configurations files and learning how a complex tool works when I can write what I want to do in a scripting language (not-so- coincidentally the language I'm actually programming in)?

In fact, in our shop for various projects we use makefiles, shell scripts, rake and gulp/webpack. It's _nice_ to use a tool that is set up for the idiosynchracies of the language you're programming in. We could make do with just one (probably rake since we do mostly ruby coding), but I can tell you with certainty that it would be more work than the varied ecosystem that we have.

</comment></comment></comment></comment><comment><USER25> It might be worth mentioning that Gulp 4 can use ES6 if the config file is named "gulpfile.babel.js".

<comment><USER26> The version on npm is 3.9.0

<comment><USER27> Gulp 4 is still 'beta'. That trick works with gulp 3 too though.

</comment></comment></comment><comment><USER28> So this is next generation only because it uses generators instead of callbacks?

</comment><comment><USER29> [https://www.youtube.com/watch?v=lVXzyaovsMc](https://www.youtube.com/watch?v=lVXzyaovsMc) It is over.

</comment><comment><USER30> Working with Javascript as become heavier,slower and more complicated than Java. Sure you can automate code compilation(because that's what it is), but you still end up with grunt/gulp/fly builds that takes a minute or more... not really a write/refresh workflow and it doesn't make it more enjoyable than working with compiled language X or Z.

<comment><USER31> Usually the tools I use have finished execution (triggered by a save) before I even left the editor. It's much better in practice than it sounds in theory.

</comment></comment><comment><USER32> Wondering what would be the status message when the build fails: "Your fly is open" :o)

</comment><comment><USER33> Here we go again..

</comment><comment><USER34> This looks super slick. Very edgy javascript build tool ;)</comment>


Canonical's Snap: The Good, the Bad, and the Ugly - <AUTHOR> http://thenewstack.io/canonicals-snap-great-good-bad-ugly/ <comment><USER2> The technical criticisms here are not really directed at Snap, but at the trade-offs inherent to the sandboxed-application packaging model in general.

Speaking as day-to-day desktop Linux user, a working sandboxed-app model would be a BIG improvement over rpms and debs. I would LOVE to be able to install any version of any application, or multiple versions, independently of OS and library versions, without having to compile from source code, grapple with conflicting dependencies, etc.

Are there any F/LOSS alternatives to Snap that are as widely used and tested? If there aren't any, Snap is really our "least worst" alternative.

<comment><USER3> As a Linux user since many years, I like very much the traditional package management. I think the efforts should be put on reliability and hardware handling. I have migrated from 14.04 LTS to 16.04 recently. I am using a NAS drive. After my do-release-upgrade -d, internet was not working anymore because of systemd circularity problem. I had to learn how to create systemd configuration files to describe remote filesystem mounts.

The focus when clicking on chrome did not work anymore ([http://askubuntu.com/questions/760654/cick-to-focus-is- not-w...](http://askubuntu.com/questions/760654/cick-to-focus-is-not- working-16-04/789056#789056)).

When my computer enters in sleep mode, I can wake it with a press on enter. The next time, it enters in sleep mode, I can not wake it up anymore.

I have fixed the two first issues and worked around the third one. I dream ubuntu becomes more used, but these kind of issues is blocking.

<comment><USER4> I agree that it should get easier, from release to release, to upgrade, but I am not surprised by the bugs you encountered. On the plus side, the first 'really stable' Xenial release is due soon [1] though I can't say that would guarantee your bugs will be squashed, even then - however, it is important to log them [2] to make sure they get some attention.

1: [https://launchpad.net/ubuntu/+milestone/ubuntu-16.04.1](https://launchpad.net/ubuntu/+milestone/ubuntu-16.04.1) 2: [https://help.ubuntu.com/community/ReportingBugs](https://help.ubuntu.com/community/ReportingBugs)

</comment></comment></comment><comment><USER5> This unfortunately reads like a hit piece with no information of Snap at all. It's like the author did not even install Snap raising questions about the premise and purpose of the article. Where is the good, bad and ugly?

For instance branding Ubuntu initiatives like Snap or Mir as 'NIH' and leaving Redhat supported ones like XDG, Flatpak, Systemd etc is itself an act of politics and manipulation.

This leaves little room for informed discussion. Linux is heavily politicised with tons of vested interests and thousands of folks and projects sponsored by or in the employment of various players.

Maybe its time to stop tiptoeing around the politics and let it out in the open so there can be more informed discussion and less of the simplistic PR driven fantasy narratives like 'fedora is independent but Ubuntu is not' that this article pushes.

</comment><comment><USER6> This piece is only about politics, which is the usual drama: most players have an NIH-attitude and we'll end up with three different standards. No one is helped except for news outlets who can proceed to construct a nice dramatic 'he said, she said' story.

It would be more interesting to see an in-depth technical comparison of Linux app container implementations, so that an outsider can make an informed choice.

<comment><USER7> Politics are quite important to do right and politics is different from NIH. The article notes two important things:

1) Canonical wanting to do big announcements. This causes problems if you want to work with communities. They'll try and work and get support, but one person per distribution isn't the same as working with the entire community. So when the announcement implies that there's broad support, the communities feel like it is a big lie. That'll destroy the willingness to cooperate.

2) Canonical likes to keep control. E.g. the CLA. Canonical has special rights nobody else will have. Companies don't like this at all, it changes the working together into helping a competitor. It doesn't make business sense. Canonical tries to solve things by e.g. saying you keep the copyright, but that is just ignoring the actual issue. This CLA has been an issue for various Canonical projects for many years. An "we might change this" I don't trust. Similarly, Canonical rolled this out while the code only supports the Canonical proprietary app store. Someone else now made a open/free source (not sure which) store, but at the moment the experience quite assumes just one app store.

Those two things together make people want to refrain from spending time (doesn't matter much if they're paid or not).

Note: I'm biased and I like Flatpak as well as AppImage. I don't see the problem in having multiple standards. Canonical is IMO very good at having a great Ubuntu experience. They're (again IMO) terrible at doing cross distribution work due to reasons explained above.

<comment><USER8> I too am leaning toward Flatpak. I expect it, like other products from Red Hat (systemd, pulseaudio) will eventually be the winner in the end.

</comment></comment></comment><comment><USER9> That didn't really give any details about what is good, bad or ugly about Snap.

</comment><comment><USER10> This is again more political bullshit. I know exactly what is going to happen. We are again going to have 3 different ways to package containerized applications and someone is going to come along and create another `fpm` but this time for containerized applications. I'm going to go back to pretending that `deb` and `rpm` don't exist and my packaging format is `fpm`.

<comment><USER11> [https://xkcd.com/927/](https://xkcd.com/927/) "How Standards Proliferate" :P

</comment></comment><comment><USER12> "Snap is the equivalent of static linking". So why not statically link? Encouraging software to work with static linking would be helpful for unikernels also.

With delta compression, I think my weekly updates on Arch are at least 200MiB, not even counting particularly large packages. Over a month, nearly half the system is replaced. For static linking (or equivalent) to be practical for those of us with limited bandwidth connections there would need to be some excellent cross-binary delta compression. In some situations it is useful, but for a general purpose system I think shared libraries make more sense.

OpenPandora's PND system is another example of prior art. [http://pandorawiki.org/Introduction_to_PNDs](http://pandorawiki.org/Introduction_to_PNDs)

</comment><comment><USER13> > CoreOS and Red Hat are sponsors of The New Stack.

</comment><comment><USER14> Is it correct that I'll need to login with an Ubuntu One account to install a Snap package?

<comment><USER10> Of course not. That wouldn't make any sense. Do you need to log into any account to install rpm or deb package?

</comment></comment><comment><USER15> systemd a superior solution ?

Guh.

If we had not systemd and had kept it simple stupid, there would be no need for snap: \- you compile the application in static (à la windows) \- and you do a chroot (or as they call it a namespace).

Ksss, I am wrong, I see it.

But then, when you make a multi-tiers architecture, how do you make stuff communicate? Well, easy, web services.

But how do you know where they are? How do you print? How do you register PlayMediaKey as a way to start your application? How do you make sure the «right application» can set the time (ntp/system preferences) while other applications are kept away?

Guh ....

registry base? Autodiscovery? You need a bus? An IPC?

And what of the mess of Xorg? How do I prevent applications to see or intercept informations they should not see?

Most engineers have troubles with a basic group/permission model already and OSX/AD have proven that a more complex schema based on a complex namespace often in practice results to poorer results.... how do we make access secured?

Oh! you still have the "one application in foreground has all rights"... the kind of tablet model à la iOS. But then, we are losing the advantage of multitasking... like listening to music while writing or playing games.

So back again in square one of being confined BUT able to cooperate.

JAVA and its JVM was a way to answer this problem: let's forget all of this and control at the application layer of the JVM.

But then, how do you talk to hardware?

java or not, application needs to know about the hardware, but we have no fixed address for HW devices (minor/major nodes are long gone, and PCI/USB vendor id are not pointing to a single HW target since long)

So maybe we could have a virtual HW that talks to the real HW with a translation in the middle ? (VMware, Xen...)

Ho! But I want to make sure I develop for a single target!

Well, good luck unifying games dev in a single image while making sure the screensaver don't override it, while not preventing security applications to do emergency locks... and still having the right level of acceleration...

And then, the world of confinment is biting his tails always asking itself the same questions.

For the old persons, let's just accept that easy image deployment could be like on Amiga/C64/amstrad &al: a unique HW, with a single application. You jump to org and execute the ASM in single mode. Problem solved.

But the more we expect from easy to code with cooperation (wouldn't it be ridiculous to put printer/HD/SD driver in a text application, network/audio/video driver in a browser) the more our apps are dependent from an ecosystem that is a moving target.

Basically there can be no easy confinement (application snapshot) without a unified abstraction of HW and services as well of their properties whereas the complexity of OS is growing (more HW, more protocols, more "required dependencies" à la systemd).

Basically confined image deployment on heterogeneous system/HW is a chimera unless you confine yourself to very basic tasks that requires no dependencies (like mono post calculus in FORTRAN using stdin/stdout).

We are just in the hell of the dependencies. And I don't think there is any silver bullet for this situation. This problem grows more than linearly in complexity as a cross product of all the potential differences in the configuration space.

Let's forget about chimeras.

The complexity is dooming the costs model of application development. As the HW/OS landscape is splitting in different direction with legacy systems still needing updates, development has to face the world of a constant progress/obsolescence where devs are told to forget about past platforms to be hype, and customers have the need to keep their legacy systems in production.

Sometimes there is no solutions to a problem.</comment>


Three MySpace Execs Departing To Start New Company (Leaked Memo) - <AUTHOR> http://www.techcrunch.com/2009/03/03/three-myspace-execs-departing-to-start-new-company-leaked-memo/ <comment><USER2> It looks like: "Myspace's lose is SV's gain". :)</comment>


Flavors of SIMD - <AUTHOR> https://zeuxcg.org/2019/02/17/flavors-of-simd/ <comment><USER2> I find that modern c++ compilers can do a pretty good job of auto- vectorization, given that the code is "vector-friendly" to begin with. But writing code in that style is a bit of black magic with lots of trial and error. I wish compiler vendors would publish "style guides" for this purpose, or at least a collection of best practices.

<comment><USER3> Hmmm, I feel like I've been waiting for a compiler to get clever enough to auto-vectorize my code since MMX was new. It never seems to happen. I guess I need that style guide.

For example, here's a hello-world type SIMD problem: auto-vectorize a simple alpha blending pixel painting routine.

      struct Pixel { unsigned char r, g, b, a; };

      // Draw a horizontal row of alpha blended pixels into a scan line.
      // Assume clipping is already done.
      void hline(Pixel *scanline, int startIdx, int len, Pixel c) {
        len &= 0xfff0; // Let the compiler assume that the length is always a multiple of 4.
        int invAlpha = 255 - c.a;
        for (int i = 0; i < len; i+=4) {
          Pixel &dest = scanline[startIdx + i];
          dest.r = (dest.r * invAlpha + c.r * c.a) >> 8;
          dest.g = (dest.g * invAlpha + c.g * c.a) >> 8;
          dest.b = (dest.b * invAlpha + c.b * c.a) >> 8;
        }
      }

And here is GCC 8 _not_ auto-vectorizing it: [https://godbolt.org/z/zPZL-J](https://godbolt.org/z/zPZL-J)

Is this the kind of thing you think should be auto-vectorizable by the compiler? If so, any idea how to persuade the compiler to do it?

<comment><USER4> There are a few issues impeding vectorization that I see:

1\. The memory loads are not stride 1. They're stride 12, effectively.

2\. You have i8 -> i32 -> i8 operations going on. Mixed size conversion is generally problematic for vectorization.

3\. You're storing 3 bytes of every 12 bytes. The compiler cannot generate extra stores, so it has to introduce masked stores. That's expensive.

The optimal vectorized code for this sort of algorithm is probably an unroll- and-jam: load 4 pixels, shuffle the vectors into r/g/b/a vectors for computation, do the computation, and then shuffle them back into r/g/b/a vectors for storage. This requires some code rewriting--inserting a dummy dest.a = dest.a * 1.0; might convince the compiler to store, although it could well eliminate the store before vectorization.

This sort of thing is why you end up needing a more specialized language for vector codes, such as ISPC.

<comment><USER3> > The memory loads are not stride 1. They're stride 12, effectively.

Stride 16, no? Anyhow, that's a bug. I shouldn't have put the +=4 in the loop iteration increment. Once I fixed that and added a dummy set of dest.a, then I get auto-vectorization. Woo-hoo. See the link I posted in my reply to tomsmeding.

</comment></comment></comment></comment><comment> Const-me > It's not immediately clear how to make this use SIMD… unless you use > gathers.

Gathers are slow.

With SSE2, you only need 2 instructions to check for duplicate indices. First _mm_shuffle_epi32 to "rotate" the triangle [a,b,c] into e.g. [b,c,a], second _mm_cmpeq_epi32 to do per-lane comparison between the original and rotated.

Similarly, with AVX2, same approach can be used to check 2 triangles at once.

For best result, unroll the loop into batches of 4 triangles (8 for AVX), and use 128/256 bit loads.

</comment><comment><USER5> > unfortunately, the use of SIMD can make the code less portable and less > maintainable

Unfortunately general purpose processors aren't getting any faster, but they are getting more specialized. At some point in the future package managers for OSS May have to do LLVM compilation on the machine just to specifically target the bits and baubles of the specific architecture it's running on.

<comment><USER6> Good GPU (SIMD) code is written in a very, very different manner than good CPU code.

Case in point: NVidia has 32 x 32-bit shaders per L1 cache / Shared Memory (a Symmetric Multiprocessor, or SM). Each SM can run 32-warps at a time, for an effective 1024 "shader threads" per L1 cache.

In contrast: CPUs have 1-core, with 2-way SMT. That's 2-threads per L1 cache. IBM has a Power9 CPU with 8-way SMT for 8-threads on one core, but that's as far as you get with traditional CPUs.

Effectively: GPUs are memory-constrained. Not memory-bandwidth constrained btw (GPUs have a TON of bandwidth), but literally memory constrained. Each shader only has ~500 bytes, probably less, that it can access efficiently (more if you have "uniform" data that can be shared between shaders). And maybe 2MB total per shader before you run out of RAM entirely.

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

GPU code is innately parallel, so any memory allocation you do is multiplied by a thousand fold, or more. Vega64 needs at least 16384 work-items before it has occupancy 1 per vALU (64 compute units, 4 work queues per compute unit, 64 vALUs per queue)... and needs x10 work-items for max occupancy (a total of 163840 work-items in flight).

If you have max occupancy 10 and allocate 16-bytes per work-item, and you just allocated 2.6MB of data on the GPU. I'm not kidding. You run out of space very quickly on GPUs.

While GPUs struggle with this multiplicative problem per work-item, CPUs have a ton of memory. That's 32kB of L1 cache typically available per thread (64kB per core, but typically you have two threads per core thanks to Hyperthreading).

That's the core of GPU vs CPU programming IMO. Dealing with the grossly constrained memory conditions of the GPU environment.

<comment><USER4> > In contrast: CPUs have 1-core, with 2-way SMT. That's 2-threads per L1 > cache.

Comparing GPUs and CPUs are tricky. What you want to compare is not the number of logical threads that can be independently scheduled [1], but the number of simultaneous FMA units you can access. If you have an AVX2 processor, that's 2 FMA units each processing 8 lanes of 32-bit values, or a total of 16 lanes per L1 cache. AVX-512 has 32 lanes due to the wider vectors.

[1] The independent scheduling of a GPU thread is also a bit of a lie. GPU threads are closer to maskable lanes of a wide vector, rather like the mask vectors of AVX-512.

<comment><USER6> > Comparing GPUs and CPUs are tricky

I agree it is tricky, but my point in the above post is not to compare processing girth, but instead to compare memory-allocation. If you are aiming for occupancy 10 on Vega64, every 32-bit DWORD you allocate will allocate a total of 655,360 bytes.

Yes, this code, a simple 4-byte allocation in OpenCL:

        __private uint32_t foobar;

This code just allocated 655,360 bytes on Vega64 (assuming worst-case Occupancy 10 per queue). While this following OpenCL code:

        __private uint64_t wow;

Just allocated 1.25 MB. By itself. The single line of code. The total amount of memory used adds up surprisingly quickly on GPUs. This is IMO the biggest issue with GPU programming, the absurdly small amount of memory you're expected to work with per shader.

</comment></comment></comment><comment><USER7> A few thoughts:

* This might be a good candidate for a compute shader, the swizzle abilities of shaders make quite a few of the things they are doing much easier as does the faster memory connections GPUs (usually) have.

* The committee is actually looking at potential ways to handle this [http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2018/p110...](http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2018/p1101r0.html) has been proposed. There is also a lot of discussion about support for GPUs in a standard way, but I haven't seen any proposals myself.

<comment><USER8> iirc the domain this guy is working in, is one where the GPU is going to be busy with rendering, so he may prefer to keep this on the cpu. But you are right that any time you turn to SIMD, you might be able to turn to the GPU and get a much biggger win.

<comment><USER7> So what I'm somewhat curious about is if this isn't an argument for heterogeneous GPU usage. Schedule this on an iGPU while the main GPU is busy. The main downside, as I alluded to above, would be memory bandwidth unless there is a good on die cache for the iGPU or it has dedicated memory. That said with a multi-gpu setup you might also have another card you could use.

The other thought I have is that it's very difficult to keep the GPU 100% saturated in my experience. If the vertex count is high enough to make the PCI-e transition worth it (and it would seem to be), then you can potentially cycle steal a bit on the main GPU. This will potentially slow down the main render but speed up the overall. This would be particularly true if you can rebind the resource back for use in the main render pipe.

<comment><USER8> All ideas that can work in certain situtions. As GPUs get more like CPUs and CPUs get more like GPUs things will just get fuzzier I imagine.

</comment></comment></comment></comment><comment><USER9> One option which I have not seen mentioned here yet is to use a platform independent API with a platform optimized implementation. i.e. if your operations can be expressed in terms of BLAS primitives, then ATLAS can give you a good part of the benefit of hand optimized code, without much of the hassle: [http://math-atlas.sourceforge.net](http://math-atlas.sourceforge.net)

<comment><USER10> Yes, that's important for portable performance, but not with ATLAS. Unless it's improved since I last tried, it's generally slower than OpenBLAS (or BLIS, by extension) and doesn't do dynamic dispatch on the micro-architecture like OpenBLAS and BLIS -- currently on x86_64 and also aarch64 with OpenBLAS. (To deal with small matrices (on x86_64 only) you want libxsmm backed by OpenBLAS or BLIS.) From previous experience I'd guess BLIS' new generic C micro-kernel for GEMM will beat ATLAS with recent GCC vectorizing it. Note in the case of GEMM, the most important part of BLAS, vectorizing is only really relevant after you've restructured it.

</comment></comment><comment><USER6> Some thoughts on my experiments with SIMD Programming:

1\. AVX2 is good, but tedious to use manually. The difficulty problem with AVX2 is that it is SIMD of SIMD: Its 2-way SIMD of 128-bit. Going "across" the lanes of the 128-bit bunches can only be done with rare instructions... or through L1 cache (write to memory, then read back in another register).

2\. "#pragma OpenMP SIMD" seems to be the most portable way to attempt to "force" autovectorization. Its compatible across GCC, CLang, and ICC, and other compilers. Visual Studio unfortunately does NOT support this feature, but VSC++ has well documented auto-vectorization features.

3\. If you are sticking to Visual C++, its auto-vectorization capabilities are pretty good. Enable compiler warnings so that you know which loops fail to auto-vectorize. Be sure to read those warnings carefully. [https://docs.microsoft.com/en-us/cpp/parallel/auto- paralleli...](https://docs.microsoft.com/en-us/cpp/parallel/auto- parallelization-and-auto-vectorization?view=vs-2017)

4\. If you keep reaching for the SIMD button, the GPU Programming model seems superior. If you must use a CPU, try the ISPC: Intel's SPMD Program Compiler ([https://ispc.github.io/](https://ispc.github.io/)) so that your "programming model" is at least correct.

5\. If a huge portion of your code is SIMD-style, a dedicated GPU is better. GPUs have more flops and memory bandwidth. GPUs have faster local memory (aka "shared memory" on NVidia, or "LDS" on AMD) and faster thread-group communications than a CPU. Know how amazing vpshufb is? Well, GPUs will knock your socks off with ballot(), CUDA __shfl(), AMD Cross-lane operations and more ([https://gpuopen.com/amd-gcn-assembly-cross-lane- operations/](https://gpuopen.com/amd-gcn-assembly-cross-lane-operations/)).

6\. To elaborate on point #5: GPUs simply have better gather/scatter capabilities. The GPU's "shared" or "LDS" memory (just 64kB or so) is very small, but provides arbitrary gather/scatter capabilities across "lanes" of GPU SIMD units. They even support relatively efficient atomic operations. Yes, even vpshufb seems relatively limited compared to what is available on GPUs.

7\. Raw AVX2 assembly seems "easy" if what you need is a 128-bit or 256-bit register. For example, if you are writing Complex-Doubles (real+imaginary number), then it is very straightforward to write 128-bit SIMD code to handle your arithmetic. But if you are writing "true SIMD" code, such as the style in the 1986 Seminal Paper "Data Parallel Algorithms" ([https://dl.acm.org/citation.cfm?id=7903](https://dl.acm.org/citation.cfm?id=7903)), then stick with ISPC or GPU-style coding instead.

8\. Be sure to read that paper: "Data Parallel Algorithms" to get insight into true SIMD Programming. GPU programmers already know what is in there, but its still cool to read one of the first papers on the subject (in 1986 nonetheless!)

<comment><USER10> I can't comment on the GPU comments, but you may be better off leaving the vectorization to gcc than using the simd pragma. On haswell, it uses avx2, but not fma, so you loose a factor of two on GEMM, for instance. The GCC manual also gives an example for the ivdep pragma.

<comment><USER11> Would not that be just a question of missing improvements?

If I recall correctly, OpenJDK can use FMA thanks to Intel contributions.

<comment><USER10> I don't see how openjdk is related to the openmp pragma. GCC has no problem using FMA if you just let it, avoiding the pragma which simply says "simd".

<comment><USER11> I understood that GCC auto-vectorization wouldn't do it currently, and hence gave an example where auto-vectorization does make use of it, assuming I remember Intel's session at CodeONE correctly.</comment></comment></comment></comment></comment>


Show HN: Emacs Anywhere v1.0 Release - <AUTHOR> https://github.com/zachcurry/emacs-anywhere/blob/master/README.md <comment><USER2> Open an issue on github if you have a feature request!

Star it on github if you like it :)</comment>


Logamediate Inflation by Tachyon Field [pdf] - <AUTHOR> http://arxiv.org/pdf/1503.06231.pdf

<comment><USER2> It's better to link to the abstract at arxiv.org rather than directly to the PDF. In this case, that would be: [http://arxiv.org/abs/1503.06231](http://arxiv.org/abs/1503.06231)

The abstract page lets the reader see what the paper is about before downloading the whole PDF, and if there have been revisions will contain a link to latest one.</comment>


A simple virtualenv for Go - <AUTHOR> https://github.com/ChuckHa/goenv

<comment><USER2> I was interested when I saw the project name, but this appears to be:

        mkdir -p pkg bin src
        export GOPATH="`pwd`"
        export PATH="$GOPATH/bin:$PATH"

Only what I typed there is shorter and safer than the committed code.

That's... simple, yes.

[https://github.com/ChuckHa/goenv/blob/master/goenv](https://github.com/ChuckHa/goenv/blob/master/goenv)

<comment><AUTHOR> Awesome, I won't pretend to be a bash expert. Any interest in opening a PR?

<comment><USER2> Naw, just go ahead and commit that if you like. That's too much easier to be worth the fork/checkout/commit/push/pull request cycle work in this case.

<comment><USER3> Understandable - but it's pretty easy to do small modifications like that using Github's edit feature. Everything but the editing itself is pretty much hidden away.

<comment><USER2> Did not know that. Thanks!

</comment></comment></comment></comment></comment><comment><USER4> This seems to copy a bad design decision from virtualenv. Please see [https://gist.github.com/datagrok/2199506](https://gist.github.com/datagrok/2199506)

<comment><AUTHOR> I implemented the suggestions in this gist on a new branch here:

[https://github.com/ChuckHa/goenv/tree/inve](https://github.com/ChuckHa/goenv/tree/inve)

I'm not sure I like it better though because it unsets $PS1 and other variables that get set in .bash_profile.

</comment></comment><comment><USER5> I'm actually a little confused by go's global approach, which ultimately gives rise to the myriad of solutions listed in the comments here. Am I missing some go-centric way of thinking?

<comment><AUTHOR> I think the documentation about go workspaces is just a simple approach and it's expected the community will eventually settle on a way to manage this in a non-global fashion.

I'm guessing everyone wants something slightly different and it would be pointless for Go to have One Way hence all the alternatives here.

<comment><USER6> What makes the recommended approach in the workspace documentation "global"?

</comment></comment></comment><comment><USER7> Very nice. A little while back I wrote something similar for those who use the fish shell. You can find that here, if you're interested: [https://github.com/zackkitzmiller/gofish](https://github.com/zackkitzmiller/gofish) (Pull requests also welcome)

</comment><comment><USER8> There's already a `goenv` [https://github.com/wfarr/goenv](https://github.com/wfarr/goenv), that I've been using for a bit. Also can do go version management.

<comment><AUTHOR> Thanks for pointing this out, I hadn't found it.

</comment></comment><comment><USER9> The approach we've taken at work is, each project has its own src/pkg/bin tree under the checked-in root, and we just set GOPATH. Simple and easy.

<comment><USER10> This seems like a very reasonable approach. Thanks!

</comment></comment><comment><USER6> It's too simple. PATH grows with each use of the tool.

<comment><USER11> Depends on your perspective. For a tmux or screen user, this would seldom, if ever, be a concern. Even for those that don't use tmux or screen; why add more code and complexity to solve what amounts to a (arguable) workflow disfunction (i.e. endlessly switching projects in a single shell window/pane). I mean, I'm sure it happens, but this is your trade-off for simplicity.

</comment></comment><comment><USER12> I'll throw my hat in with all the other contenders in here. I've written a tool called goat which wraps around the normal go utility and sandboxes it to a directory, as well as providing versioned dependency management.

It's very simple and easy to use (there's only one new command), and adding it to a project requires no changes to existing code. We've been using it where I work and it's been very effective.

V1 is going to be released soon, check out the current version at [https://github.com/mediocregopher/goat](https://github.com/mediocregopher/goat)

</comment><comment><USER13> It's also work checking out glp: [https://github.com/cespare/go- localpath](https://github.com/cespare/go-localpath) I've been using it quite happily in several projects.

</comment><comment><USER14> I recommend gvm which installs and manages go versions. If you want per project workspace, create a pkgset for each. Linking the current directory to the current workspace (pkgset) is something like this.

        # active workspace
        gvm pkgset use some-workspace

        # links current directory to some-workspace/src/github.com/you/foo
        gvm linkthis github.com/you/foo

This is more flexible as it allows a common work-in-progress project to be linked to many workspaces.

</comment><comment><USER15> Another option is to use direnv ([http://direnv.net](http://direnv.net)).

Just add this to your .envrc in your project's folder:

        PATH_add bin
        GOPATH="$PWD"

The environment is automatically loaded or unloaded whenever you enter or leave the directory.

EDIT: Disclaimer, I'm the main author of direnv

</comment><comment><USER16> I've been using Gobrew: [https://github.com/grobins2/gobrew](https://github.com/grobins2/gobrew)

It would be nice to standardize this a bit. I'm sure other Go devs I work with use something different (I homerolled for awhile but I've been really pleased with Gobrew).

</comment><comment><USER17> The fact that go even needs this is a sign that it's current package manager is making all of the exact same mistakes as Python.

<comment><USER18> The fact that somebody's built it does not imply that it's generally needed, or even useful.

</comment></comment><comment><USER19> neat idea, and some neat feedback already from folks. while i'm just getting started using go (like the features, can't quite say i'm enamored with the syntax) i like the virtualenv paradigm and glad to see it ported to other languages.

</comment><comment><USER20> Genuine curiosity: In practice, which Go packages that people use require conflicting versions, necessitating a use for this tool?

In my experience, Go developers are generally good about building against updated versions of packages. Combining that with the fact that binaries are all compiled and statically linked (as opposed to dynamically linked or interpreted), I can't remember ever running into the problem where packages X and Y (that I both need) each depend on different versions of Z.

A big advantage of virtualenv in Python isn't relevant here: the ability to specify a specific version of Python (not just 2 vs. 3, but minor versions as well). With Go, you should _always_ be using the most recent version[0] of gc or gccgo, as there is no reason not to.

[0] (If you are someone who actually needs two different versions of the Go gc compiler installed on your system, you're probably on the core dev team, which means you already know what you're doing and already avoid these tools for other reasons.)

<comment><USER16> In my case I've been using the excellent goandroid ([https://github.com/eliasnaur/goandroid](https://github.com/eliasnaur/goandroid)) to develop Android apps with Go and the NDK.

It's kind of a pain jumping around distributions manually, which is why I use Gobrew to manage my goandroid Go environment and my normal Go environment.</comment></comment>


Ask HN: How to overcome the feeling that everything has already been done? - <AUTHOR>

I remember clearly that when I first built a "site" in Front Page (maybe in '98) I thought to myself: "ONCE I REALLY LEARN THIS I CAN DO ANYTHING!!!111".
15 years later and I'm a web developer with a lot of free time looking for any opportunities, and I just can't get myself to build anything, because every single idea seems to be already done.
I know people used to say this decades ago, and I know there's always room for innovation,  or improving existing things, etc. But I just can't get motivated enough.
Any tips for getting excited about projects, knowing that there's a 99% chance the thing you are working on have already been built or is currently being developed in a much better way for at least other 30 companies?
Any books or articles related to this are welcome. <comment><USER2> I recommend you take a look at Rob Walling's blog: [http://www.softwarebyrob.com/](http://www.softwarebyrob.com/)

He also runs the Microprenuer Academy that focuses on helping and promoting one-person startups. His key advice: focus on a niche industry or audience.

For example, a few years ago I had this great idea of building a task management app. I quickly discovered there were dozens of them, Asana, Producteev, Flow, Trello, etc. Using his advice, I could have focused developing a task app for a particular industry, say industrial engineers, architects, investment advisors, etc. His point being that specific industries have very specific needs, and one-size-fit-all, general purpose apps rarely targets those needs.

Bottom line, think about what kinds of app you'd enjoy building, social media, news, productivity app, game, whatever, then cross breed it with some underserved market. Example: LinkedIn + Oil and Gas industry = oilpro.com

<comment><AUTHOR> thanks!</comment></comment>


Antimatter-catalyzed deuterium fusion propulsion - <AUTHOR> http://www.nextbigfuture.com/2016/10/positron-dynamics-near-term-work-to.html <comment><USER2> I don't get how the cubesat drive is supposed to work.

You can trigger fusion with antiprotons because the antiproton is negatively charged and more massive than an electron. The antiproton takes the place of an electron but has a smaller orbit so the hydrogen nuclei get closer together and are more likely to fuse. It is just like muon catalyzed fusion.

Positrons however are positively charged and can't take the place of electron also they are the same mass as an electron so they aren't going to get any closer.</comment>


Google gives 10% raise across the board  - <AUTHOR> http://news.yahoo.com/s/ap/20101110/ap_on_hi_te/us_google_raises

<comment><AUTHOR> There is text of the memo at BI: [http://www.businessinsider.com/google-bonus- and-raise-2010-1...](http://www.businessinsider.com/google-bonus-and- raise-2010-11#ixzz14uG2u8Dk)</comment>


Common C++ Gotchas - <AUTHOR> http://vickychijwani.me/cpp-gotchas/

<comment><USER2> #3 should really say make _public_ base class destructors virtual

#6 sometimes you actually will want an A(A&) constructor... for example, if you have constructor overloaded with a greedy template argument.

#8 objects returned by value will also bind to an rvalue reference

#9 Remember in C++11 there's also new T{};

#10 isn't absolutely correct either, dynamic_cast can actually be used in some circumstances where static_cast or implicit casting could have been used.

        struct A {
        };

        struct B: A {
        };

        int main() {
            auto b = new B();
            auto a = dynamic_cast<A*>(b); // fine
        }

<comment><USER3> #3 should really say "make polymorphic public base class destructors virtual."

There are reasons why you might want to use public inheritance that have nothing to do with run-time polymorphism.

<comment><USER4> I haven't touched C++ in years. Why would you ever make a non-virtual destructor? Isn't it totally up to the user of a class if they choose to inherit from the class?

It seems like, if you're not providing a virtual destructor, you force users into delegation rather than inheritance, and that will catch some % of developers who aren't on the ball. They'll have leaks...

As far as i know (old info) there's no such thing as a "final" class, so anybody can inherit even if you don't want them to.

<comment><USER5> Having any virtual member functions, unless the compiler can devirtualize it, will hurt both space usage (since you now need a per-object vtable) and cache performance (since destruction now has to go through an indirection every time, instead of being a globally visible function).

You have the `final` specifier since C++11 to state a class cannot be inherited from, but this notion of "You really shouldn't inherit from this class." has been around since classical object orientation has, C++ just couldn't express it as a language.

So if your class currently isn't being inherited from, make your public dtor nonvirtual. If and when it needs to be a base class, then the author can modify your class to have a virtual dtor, or use composition (which is often the superior alternative). If source code is not available, then composition it is. I would advise against making it virtual "just in case", that's premature pessimisation.

<comment><USER6> > per-object vtable

You mean per-object vtable _pointer_? Or per- _type_ vtable?

<comment><USER5> Per object vtable pointer, yes.

</comment></comment></comment></comment></comment></comment><comment><USER6> Why are you using delete so often in C++...? 'delete' should be rare in your code.

<comment><USER7> Why shouldn't you?

You don't always have control over the code you are writing, an example that comes to my mind quickly is ffmpeg.

<comment><USER8> How does ffmpeg relate to this, isn't it written in C?

<comment><USER9> He may be talking about interfacing with C code of that nature. (You can still localize most of your new/deletes in to the wrapper classes though)

</comment></comment></comment></comment><comment><USER10> It's not only C++ that has problems with throws out of destructors or similar logic. How about Common Lisp:

[http://clhs.lisp.se/Issues/iss152_w.htm](http://clhs.lisp.se/Issues/iss152_w.htm)

"The ambiguity at issue arises for the case where there are transfers of control from the cleanup clauses of an UNWIND-PROTECT. ..."

It is not clear what exit points are visible when the cleanup-forms (morally similar to C++ destructor calls) are invoked. Are the exit points that are skipped torn down all the way to the control transfer's target, or is the tear-down interleaved with the unwinding.

<comment><USER11> The real answer, as far as I can tell, is "Don't use exceptions in a program that's too important to crash."

<comment><USER10> Right, and to that end, don't use a CPU that traps illegal instructions, divisions by zero, pointers to unmapped pages and so on. Those are all forms of exceptions.

</comment></comment></comment><comment><USER12> I wrote C++ code for about 10 years before moving over to C#. I still like C++, but posts like this make me remember why I don't miss it. It's so baroque.

</comment><comment><USER3> #1 should really say, "Avoid new and delete." new and delete are for experts. The average C++ programmer should go nowhere near them. If heap memory is used internally by a class that was written by someone who knew what they were doing, then fine. Use your std::vector. But new and delete are huge red flags in code.

<comment><USER13> It's fine to use new as long as you're immediately sticking the result in a smart pointer. But yes, delete should be very very rare in modern C++ code.

<comment><USER14> With std::make_shared, and the addition of std::make_unique in C++14, you shouldn't ever need to use new for this purpose either.

<comment><USER3> It depends. The trick to using new correctly is to put it in a function whose sole purpose is to immediately store new's result in the smart handle. I.E. You're writing a function that's analogous to the make_unique function.

You might need to do this if you're implementing your own smart handle or writing a factory function for a class with a private constructor (make_unique will not work).

Off the top of my head, I can't think of any good reasons to use delete.

<comment><USER15> If your handles are pointer types, you should _still_ use unique_ptr, you just need to give it a custom "deleter". (Of course you should probably still encapsulate this in a function like make_xxx() just to avoid the potential mistake of not supplying the correct deleter everywhere.)

</comment></comment></comment></comment></comment><comment><USER16> #5

> If you'll tolerate my hypocrisy for a moment, here's my suggestion: try to > avoid putting the const at the beginning like that

Or you could not do that, and put const in the least ambiguous place, and since you rarely have a 'type* const _' it works very well just using:

        const type*

for pointers to const types, and

        type* const

for const pointers to types, and entirely unambiguous.

</comment><comment><USER17> > Option 1 is bad because: (a) it involves an unnecessary copy constructor > invocation

Shouldn't rvalue move semantics kick in and prevent the copy?

<comment><AUTHOR> Agreed. I'll add a note. There's still the slicing though.

<comment><USER18> For slicing, the general rule in C++ is _whenever you have a value object, polymorphism does not apply_. A value object is always whatever its compile- time type is - after all, it's just a value, it can't represent some other "thing" that's off in some other memory space. Polymorphism only applies with pointers and references.

Remember this rule and the throws behavior makes perfect sense, as do a lot of other C++ gotchas.

</comment></comment></comment><comment><USER19> I would actually revise #1 to be to always use a smart pointer for heap- allocated objects. C++11 is 3 years old now after all.

</comment><comment><USER20> Selection messed up in your website: [http://imgur.com/YuowMEm](http://imgur.com/YuowMEm)</comment>


"If you're outraged by accidental breaches, you'd better sit down" - <AUTHOR> http://benlog.com/articles/2010/05/14/if-youre-outraged-by-accidental-breaches-youd-better-sit-down/ Ben Adida on the recent privacy breach disclosures:<p>"If you're shocked, outraged, writing lengthy TechCrunch posts about these developments, you probably don't understand computer security very well, and you'd better sit down with a stiff drink, because these issues are the tip of the iceberg." <comment><USER2> I hope we're really close to a Responsibility tipping point in regards to online security, by which I mean a general acceptance by internet users that they, not the site they visit, must take primary responsibility for their online security.

This doesn't remove any responsibility from my bank, paypal, Facebook etc. But until the average person hears about a potential breach of their privacy and thinks "What can I do differently to prevent this happening again?" then breaches are going to be fodder for sensational journalism and outraged users... neither of which helps solve the problem.

I will make a division between some core security - like my credit card details on Amazon - and peripheral security - like my photos on Facebook. This latter type will tip over first, and I hope it's soon.

<comment><USER3> But what _could_ I do differently to prevent my bank, or employer, or sites I shop at, or anybody else, from leaking my data? Isn't it pretty much their responsibility to make their site work properly? It's my responsibility to not get taken in by phishing scams, sure, but what am I supposed to do about a bank accidentally losing a CD with accounts on it, or getting their database server compromised?

If anything, I'd suggest it should tip over into the other direction, with much stricter liability and penalties for those sorts of information breaches. If somebody promised something and failed to deliver it, that's a pretty classic case of fault. Now if, on the other hand, they said up front that they might make my data public if they felt like it, then that's another story.

In Facebook's case, it feels a bit like the flip-side of their recent proposal to make TOS legally enforceable. Perhaps make 'em legally enforceable in both directions, then, as a real contract with obligations on both parties?

<comment><USER4> I agree. Other than trying to avoid phishing scams and using sensible passwords there's not much that the user can do to improve their digital security, especially in the era of cloud computing where much of what goes on from a software perspective is not within the user's realm of responsibility.

</comment></comment></comment><comment><USER5> The thing about the Yelp/Facebook bug is that it demonstrates how some of these features have pretty fundamental problems. Facebook gave Yelp full access to their API in a way that meant that any XSS holes in Yelp would result in a breach for Facebook. Yelp had an XSS hole.

Keeping a large site free of XSS is really, really hard (especially if you don't have an escape-by-default policy baked in to your template layer). Ensuring your partners are free of XSS is even harder.

</comment><comment><USER6> It seems to me that the major problem is that there is no gradients in security.

With my online bank I am forced to go trough the same tedious process whether I want to check my balance or transfer money.

I think that is part of the problem in getting users to care about these matters.

My own thinking on this is "The Ghost Protocol" peer 2 peer negotiation where trust is build over time rather than defined by a login. This wont be happening anytime soon but the username/password approach isn't going to cut it moving forward IMHO.

</comment><comment><USER7> The world is not as black and white as this article suggests.

"We do not know how to write secure software."

100% secure? No, perhaps not. But we know a few things that could be done much better than they are today.

For one thing, you can't leak information that you don't have. Companies today tend to default to grabbing more information for their databases and keeping it around indefinitely. We need much stronger data protection laws than most countries have today to counteract this.

For another thing, "pushing the envelope and releasing features as quickly as possible to outpace your competitors" is not an excuse for not running a decent software development process. Seriously, Google was collecting that data for _three years_ and no-one had looked at any of it and thought something was wrong? The cost of phishing and identity theft even in purely economic terms are already significant, and those costs are rising and don't take into account the more important human suffering aspect. A statutory fine of, say, $10,000 per individual per negligent breach should focus the attention a little more on getting basic testing right and doing something about problems before they happen, and a little less on trying to infringe everyone's privacy faster than any competitor can.

As I have noted before, such a level of fines would be an unacceptable risk for many businesses and they would probably have to stop collecting and retaining personal information at all. I have no problem with this, as long as the negligence criterion is applied sensibly. Most companies _don't_ need to store a lot of data about us, and those for whom it is an important part of their business model can learn to take reasonable steps to prevent abuse.

<comment><USER8> As much as I would like to see this, without a stable industry consensus on best practices, there is insufficient foundation for a legal definition of negligence.

<comment><USER7> An alternative possibility is that evidence of "reasonable" behaviour would be heard on a case by case basis in court, and case law would start to show the minimum standards expected. Some practices may be more hype than substance, and anyone alleging a problem because something was not done would presumably have to justify why that action should have been taken. On the other hand, I think you would find a lot of consensus and evidence-based argument in some areas of security, and there is really no excuse for not following those practices if you're in the business of managing sensitive data.

<comment><USER8> If we are going to shift responsibility from attackers to the attacked, there needs to be a clear and reasonable way for security non-experts to ensure that they are doing their due diligence, and for non-experts in the legal system to be confident that they aren't.

For now, any clown can come along and tell someone that they are secure, and another clown can verify that the first clown is an official certified non- clown. It may be perfectly obvious to you that these people are incompetent, but to the non-expert it ultimately comes down to your word vs theirs. Even the clowns may not have an objective way of knowing that they are clowns.

Without an authoritative standard that provides a root of trust to non- experts, everything falls apart. That standard requires consensus, which requires a critical mass of competent experts, which requires the state of the art to keep up with demand and change, which is not going to happen in the field of security any time soon because there is too much demand, too much change, and it's just too damn hard.

<comment><USER7> > If we are going to shift responsibility from attackers to the attacked, > there needs to be a clear and reasonable way for security non-experts to > ensure that they are doing their due diligence, and for non-experts in the > legal system to be confident that they aren't.

I'm sorry, but I don't entirely agree with that. I think if you deliberately take on a role that is potentially damaging to others, such as collecting large quantities of personal data, then to some extent the onus has to be on you to be competent in how you protect that data.

The whole premise of using words like "reasonable" in statutes and then developing case law over time is that you can't always predict every single possibility in complete detail ahead of time, and sometimes you have to make a judgement in the circumstances of a particular case about whether someone's actions were reasonable.

This problem isn't specific to IT security, of course. After all, any time you employ a new member of staff as a company, you are to some extent trusting that they (and perhaps their references) have been honest in their representations to you during the recruitment process. And yet, we still have businesses with employees, even though it is an uncertain world, and for the most part this works fine anyway.

> Without an authoritative standard that provides a root of trust to non- > experts, everything falls apart.

I respectfully disagree. It doesn't take a big, formal spec to understand that you should hold sensitive information behind a secure access mechanism, and that sensitive data should be protected to avoid leaks in transit or on disposal of hardware.

If someone doesn't understand and follow these basic principles, then perhaps handling sensitive data is not a good career choice for them or their business. I would have no problem with a legal action against an organisation that compromised, say, many people's bank credentials, by leaving them on an unencrypted USB stick on a train.

Arguing about whether a certain state-of-the-art or controversial security process or tool was necessary and whether failing to use such a thing was negligent is for courts to consider, based on the testimony and possibly expert statements from both sides. If anything, this process and a reasonable burden of proof on the prosecution seem more sensible to me than trying to reduce a fast-moving field like IT security to a fixed checklist that might be obsolete within days of completion.

<comment><USER8> The things you describe are reasonable in general, but break down under the extremes of present day security, software development too. The problem is that _most_ people who think they can do it, can't. That is, most professionals will take on more challenging problems than they are practically qualified for. If the bulk of an industry can't judge its own competence, customers and courts have no chance of doing so. And yet this is increasingly a requirement for doing business at all. You can't simply tell people to stop using computers.

If you can't define "reasonable" for the purposes of writing a law, it's a good indication that people won't know what it means when they try to obey the law. You can't make laws that nobody knows how to follow.

</comment></comment></comment></comment></comment></comment><comment><USER9> The chat bug was pretty stupid, how on earth did they manage to create a bug like that (seriously, it amazes me)! Seems like they have an awful authentication system - these things should be checked over before going online.

</comment><comment><USER10> This is right on the money.</comment>


"Screw it, I'll make my own" – The story of a new programming language - <AUTHOR> http://breuleux.net/blog/my-own-language.html <comment><USER2> > There is a bit of a catch-22 in language design where the more a language is > used, the clearer it becomes which parts of it are problematic and should > change, but the harder it gets to actually change them. To hone a language > you must use it, but applications require that a language's features remain > stable, robust, set in stone, and therefore as imperfect as they were at > that moment. Furthermore, the more delays are suffered in fixing flaws or > plugging holes, the more likely it gets that a dependency is fostered upon > them. The options you do not explicitly and insistently leave open, tend to > close and seal themselves before you know it.

This rings very true. I look at Ceylon and the features I'm most jealous of are things that Scala would and should _just do_ , except for the need to retain compatibility with 10 years of existing applications and libraries, so instead they're enhancement proposals for the version after the version after the next version, and in the meantime we get by with macros that more-or-less cover the most important use cases. And Scala is relatively young as languages go - its warts are nothing to those of, say, C++. Sometimes I wonder if language design can only advance by new languages killing existing languages - past a certain point it seems impossible to change a language in the ways that it needs to be changed to become good.

<comment><USER3> A nice solution was used during development of the Go language: a tool for _code rewriting_ (it was called "go fix"). It allowed the language authors to quickly and easily transform large swaths of code in the standard library, and also let everybody execute the same transformations in any third-party code. Thus enabling rapid and extremely painless iterations. [I'm consciously simplifying the story a bit to make it shorter and more concise, but I'm not hurting the core message I believe.]

<comment><USER4> I think that's a neat idea. I've thought about it, but I've never used Go personally and I wasn't sure just how much it would help. I imagine it works best for languages with good static properties/tools for code analysis.

<comment><USER2> I think the important cases are the ones that you can't fix by hand - the ones where you're removing a dangerous idiom.

</comment></comment></comment></comment><comment><USER5> Nice story. I have similar feelings about my own attempt, Runa ([https://github.com/djc/runa](https://github.com/djc/runa)), in particular about just how large a language (ecosystem) has to be in order to be viable to a few more people.

Still, just the journey is quite interesting. It makes you understand other programming languages and their tradeoffs better, and I'm now much less afraid of parsers and lexers and so on. :)

</comment><comment><USER6> > it is still unsettling when you feel like you can't participate in > discussions about programming languages without indulging into self- > promotion

Ahem, cough, cough, er, ...

</comment><comment><USER7> Curious. Are there examples of programming languages that allow spaces in identifiers? Obviously, it would need to be designed for that.

I'm against the case-sensitive nature of some programming languages, and file systems for that matter. While it makes sense in a computing context (faster), you invent a new mode, just for the computer..

(Fortran was probably case-insensitive because upper-case letters were used first, and when lower-case letters were introduced, care was taken to neatly map them into the character set bit-wise, so one could simply clear the sixth binary digit to turn a lower-case letter into its upper-case equivalent, then continue the string comparison.)

Of course, with Unicode, you need a more complicated check, or you could just ignore Unicode in the language itself for identifiers, yet allow it in literals, data types, etc.

<comment><USER8> Case-sensitivity makes sense because it enforces uniformity of code. Case insensitivity only matters when you want to write identifiers differently at different locations. The only place where I see this could be useful is when you use a library that uses a different convention.

The IMO better way to solve this is to set a convention for your programming language and enforce it with the compiler (at least with warnings).

<comment><USER7> As you say, it's about conventions, but with a case-Sensitive system you are more likely going to HAVE TO enforce naming conventions, because there's a distinction now. Otherwise you'd write "MidiPort"/"MIDIPort"/"midiPort" or what have you.

Keep in mind we wouldn't need to care about enforcing case in a style guide, if case didn't matter, because there are no distinctions, and you'd be more inclined to write it the natural way; no camelCase to overrule ambiguation in writing "MIDI Port" as midiPort, or MidiPort, MIDIport, etc.

Case-sensitivity only creates unnecessary dissonance, and leads to clever uses of that system, adding even more choice; and as we know from The Matrix, the problem is choice. ;)

So if we keep it closer to how we would normally read and write words, I think there would be less dissonance about that aspect of programming, or naming files for that matter.

<comment><USER8> > Keep in mind we wouldn't need to care about enforcing case in a style guide, > if case didn't matter, because there are no distinctions

You would still need it to get uniform code. Spaces vs. tabs also doesn't matter but it's still in almost all style guides.

</comment></comment></comment></comment><comment><USER9> In Racket, you can use "-" and "?" in variable names and I love it.

<comment><USER8> x-y and x - y meaning different things seems like a great source of errors to me

<comment><USER4> It depends on a couple of factors. Personally I always write subtraction as "x - y", so I never have any issues. Also, if undeclared variables are a compile- time error, the compiler will (probably) complain loudly about "x-y". So you can fix that quickly and easily, it's not too bad.

The one error that might be problematic depending on the language's semantics is if you write something like "x.y-z" intending to subtract "z" from "x.y", but in fact you are going to get the "y-z" property of "x". I must say that in Earl Grey you'll unfortunately end up with "undefined" as the result of that expression (saner languages would raise an exception on a missing property). I have never had that issue in practice, but then again, I always space subtraction.

<comment><USER10> I don't have a problem with "x - y" and approve of hyphenated names if you can't support spaces within names.

I had initially jumped to the conclusion that your language would use a postfix notation and be more influenced by Forth than LISP. This is because I assumed it's name alluded to the way that Captain Jean Luc Picard would program his replicator.

</comment></comment></comment></comment><comment><USER11> > I chose to compile Earl Grey to JavaScript

Some programming languages generate code much deeper down the abstraction stack, e.g. Haskell generating machine code, whereas others generate code to a much shallower depth, e.g. most languages generating JavaScript. A language generating lisp code from some syntax could even be shunting code _up_ the abstraction stack.

How deep does the generated code need to be down the stack for some syntax to earn the name "programming language"?

<comment><USER12> If you look at the code, and can't identify it as language X, then it probably deserves a new name.

<comment><USER13> This sounds pretty similar to the definition of a species.

If two organisms of appropriate gender can't reproduce with each other, then they probably aren't the same species.

If code from two samples can't be interspersed, then it's probably not the same language.

<comment><USER14> Under that definition, Perl and Python have finally merged, given Perl 6's Inline::Python. Peace at last!

I'd probably go with a definition more like "mutual intelligibility" like for natural languages, but that doesn't seem right either. Sometimes I have to turn on the subtitles for British TV.

<comment><USER15> Yeah, under that definition everything that supports FFI has merged into a massive unholy mess with C. I guess if it can't be "natively" compiled/interpreted as the same language without inlining or including, I'd say it's a different language.

</comment></comment></comment></comment></comment><comment><USER16> None of the languages I typically use allow hyphens in identifiers, but I find that kebab-case to be the easiest on the eyes.

<comment><USER17> heck, even COBOL '75 (maybe even '68) allowed hyphens in identifiers.

</comment></comment><comment><USER18> It's not surprising that changing a language would be difficult. It does, after all, include a software component, and pretty much all large software projects suffer the same. It can be easy to change minor technical details, but a deep, far-reaching design decision is very often fixed in place. Even with a good test-suite, that kind of change is rarely undertaken. At least in my experience.

I suspect we've all worked on software that you would desperately love to change something fundamental in the design but no matter how painful leaving it alone is, it is preferable to live with the pain than to tear it all down.

I've known a few writers for example that say they wish they could change their characters, but it's too late. I wonder if that's analogous.

</comment><comment><USER19> Very interesting account of your experience. I've been toying with the my ideal programming language for some time and am interested. You bring up a good point about people favoring the styles of their most recently used language. For that reason I worry that any language I'd create would merely be a combination of languages I've used previously and not something original. I'm excited to take a look at your work.

</comment><comment><USER20> Well that's the problem that needs solving all right.

Yet again today I have a Python project that is already (at 200 lines!) obviously massively compressible if I had macros.

Maybe I can get there by returning functions & building up the functionality that way, but it feels like I'm trying to scratch that spot in the middle of my back, where I can't quite reach.

<comment><USER20> Rapid prototyping is this alternating process of building stuff up and then boiling it down. The building up is easier in Python, but the boiling down is easier in Lisp.

Sure would be nice to have both on tap.

</comment></comment><comment><USER21> Unfortunately, I can't say this is unexpected: [http://breuleux.github.io/earl-grey/repl/](http://breuleux.github.io/earl- grey/repl/)

<comment><USER22> Are you looking for [http://breuleux.github.io/earl- grey/repl.html](http://breuleux.github.io/earl-grey/repl.html) ?

</comment></comment><comment><USER23> I'm curious, would it have been easier to change design decisions if you hadn't bootstrapped it?

<comment><USER4> Probably a little, but I don't think it would have made a big difference. It takes a certain amount of code before it becomes clear that the design has a flaw, and it's going to be the same amount of effort to adapt it, whether that code is in the compiler or elsewhere. A bootstrapped compiler just requires a bit more boilerplate in the transition.</comment></comment>


Leadership skills come from expert knowledge, not interpersonal skills - <AUTHOR> http://papers.ssrn.com/sol3/papers.cfm?abstract_id=1158980 <comment><USER2> Would be nice if we could read the article and not just the excerpt. Since I'm taking a certificate course on Management & Supervision through my employer, this is stuff I'm really interested in. Nothing in the abstract says that interpersonal skills aren't necessary and I find it hard to believe that's true.

<comment><USER3> I had the same problem. You have to click the "choose download location" link. Here's a mirror: s3.amazonaws.com/2008/nba_paper.pdf

In short, an NBA coach who has never been an NBA player will tend to have a worse W-L record than a coach who has played in the NBA. And NBA allstars who become coaches have the best coaching records. From the paper: "For the typical team, the difference between having a coach who never played NBA basketball, and one who himself played many years of allstar basketball, is approximately six extra places up the league table."

Which is interesting, but yes, let's be careful when drawing conclusions and generalizations. To that end the paper said "our findings may be relevant to a range of high-performance workplaces where the employees are experts." The researchers merely found some data that suggested a coach's past performance as a player was positively correlated to his W-L record as a head coach. The paper did not conclude that interpersonal skills were irrelevant to a coach's record, nor did it conclude that interpersonal skills mattered less than playing skills. The researchers did not interview any people or even define terms like leadership, interpersonal skills or expert knowledge. They did milk 8 seasons' worth of Sporting News though, their primary source.

</comment></comment><comment><USER4> "Our data come from 15,000 professional basketball games."

That's really all you need, isn't it? 15,000 basketball games out to tell us exactly how leadership skills in all areas come from.</comment>


Rethink Robotics shuts down - <AUTHOR> https://www.theverge.com/2018/10/4/17935820/rethink-robotics-shuts-down-baxter-sawyer-robot-cobots <comment><USER2> Isn't making a robot that looks like a human to replace a human's job a bit like making a mechanical horse to fulfill our transportation needs?

Having worked with robotics for years I can say the amount of setup work that goes into installing fully-functional hardware and software and getting a robotic process running smoothly is enormous. The basic idea is that everything, the robot, all the hardware, all the firmware/software, the end- effector, the workpieces, the sensors, etc. is rigidly-defined and over-spec'd so that with all the tolerance stackup and after all the integration and process debugging work you set it and DON'T CHANGE IT for as long as possible. The chaos that ensues from one little component changing it's behavior can be enormous.

The notion of "smart" robots that you can just slap down or that can just handle all sorts of unknowns and adjust themselves to changes to me always seemed like a really, really big challenge, maybe not as challenging as a driverless car but definitely more of a "general AI" problem.

I'm sure someone has coined the term but there must be some kind of "uncanny valley" of intelligence: a little intelligence (e.g. the PID controllers that actually run robots) is great, a lot of intelligence (fully-blown general AI) is great (if you can get it), but what's in the middle may not be worth the while. Getting the answer correctly 99% of the time doesn't work if you need 99.9% success rate.

From an investment standpoint I would be looking for companies with a REALLY specific well-defined problem that "medium AI" could solve rather than someone who's claiming to take medium AI and apply it vaguely/generally.

I guess that's my take away from this: work on specifying the problem before you work on the solution.

<comment><USER3> I see current AI to be like donkeys, and the middling AI you speak of as chimps. There's a reason we domesticated donkeys and not chimps.

The autopilot feature of Teslas is a lot like a donkey. It mostly handles itself but is stupid and needs a lot of monitoring. Using autopilot feels a lot like sitting on a cart and pulling the ropes on the donkey every once in a while.

<comment><USER4> imagine the chaos that would have ensued in the ancient world if donkeys could pull carts at over 80mph.

</comment></comment></comment><comment><USER5> It's not that the concept is a failure. It's that Rethink, the company, is a failure. Universal Robotics in Denmark is doing something very similar, but they have over 25,000 installed robots and distributors in 50 countries. They also have a robot arm that is a nice piece of mechanical engineering, and retains its precision over a very large number of cycles.

The coming thing is robots as a service, paid by the hour. Hirebotics offers that. They own the robots. They set them up. They fix them. You pay them for each hour of use, like an employee.

Vision for robots today works well for semi-structured situations. If you know what the parts look like, and can see the parts and target location reasonably well, you can probably get a vision system to guide a robot arm to put things where they're supposed to go. The fixturing no longer has to be so rigid that a robot can do the job blind. The systems that do this are often just convolving a stored image of the target against a camera image of the area that contains the target. This is 1970s technology, but we have enough cheap compute power now to make it work fast.

</comment><comment><USER6> I have been working with the Sawyer arm for the past few months and it's a really nice piece of hardware - far better than the Universal Robots arms that it competes with, while being a similar price. The software is also far ahead of the crappy 2000's era interface of the UR arms, and they have a nice ROS- integrated SDK for people who want to go farther with it. I was really disappointed to see them shut down as we were hoping to buy several more in the next few months.

</comment><comment><USER7> I was an intern at Rethink (back then, Heartland Robotics) 2010~2011, it was an exciting place to work at. There were ~10 employees when I joined, and ~40 when I left.

One of the early product mistaked they made was focusing way too much on low- cost. They compromised many necessary performance specs (repeatability, speed etc.) just to be able to make the robot out of plastic. They eventually pivoted to their second generation robot, Sawyer, which was made out of casted metal components. This gave the robot much better performance but I guess that it was too late.

<comment><USER8> I would really love to hear why performance specs you mention are still necessary for robotics applications. Repeatability and speed certainly seem useful industrial robotics applications, but low cost also seems critical to enabling broader use of robots. I am particularly interested in the possibility that modern algorithms (e.g. deep reinforcement learning) can compensate for not having completely repeatable behaviors from a robot by using sensory feedback to create behaviors that reliable despite their variability. Additionally, materials with higher elasticity (e.g. plastics instead of metal) might allow some previous impossible efficiencies, e.g. by storing potential energy in the links and then releasing it at the right time. Is it just too soon for these sorts of approaches?

<comment><USER9> Compromise on stiffness and rigidity in a servo system means the thing jitters about like a squirrel on speed. Robots need to be smooth, and there's precious little you can do in your controls to compensate for system instability. Precision comes along almost for free once you have that rigidity.

They didn't get the basics right. Special sauce on top needs to have a solid foundation.

And that's why I have an Aubo robot in my conference room today, and why I was able to tune in a 250kg payload 1995-vintage ABB on Tuesday, while these guys are shutting down.

<comment><USER10> > and why I was able to tune in a 250kg payload 1995-vintage ABB on Tuesday

What does that mean?

<comment><USER11> ABB is a major supplier of industrial robots, so I assume the poster meant installing/setting up a used 1995 model capable of handling 250kg.

<comment><USER12> Or tune in a 250kg payload on such a robot - I can imagine the motion programming might have to be tweaked to swing right. I don't know what such a heave payload might be - maybe some heavy part to be welded.

</comment></comment></comment></comment></comment></comment><comment><USER13> Two bridges into a down round on their series E, these guys have been bleeding money for years. The VCs gave them ten years to find a sustainable path and they just never took off. This is just how it goes. It's probably for the best, and 10 years in any venture is a fair shot.

</comment><comment><USER14> I work in robotics field and I always thought that collaborative robots were cool in trade show booths but beyond that they had limited use. I've not seen many of these things used in our industry (semiconductor) or any other friends who work in various industries.

ABB lead the campaign on these as if they are going to revolutionize manufacturing lines where humans & machines will work together. That never happened just like 3D printing never shook the world as it promised it would.

<comment><USER15> > "just like 3D printing never shook the world as it promised it would"

Additive orthopedics are a pretty big deal to people who need, say, an ankle replacement.

And it's way too soon to say something like that, at least absent a "yet" modifier.

<comment><USER16> While 3D printing found home on a value adding niche, it's still far away from what could be done with the technology.

<comment><USER17> Honestly, the biggest thing holding 3D printing back seems to be lack of broad access to co-op hackerspaces with top-of-the-line machines.

And I don't mean in SF. I mean in Small Town, Kansas, sponsored by the local high school, library, and whoever else.

Buying one for home use is a dalliance for the upper middle class. But democratized access to technology would be far more effective.

Sharing an actual structural, metal 3D printer seems so much more useful than having 20x plastic-only home machines.

<comment><USER18> Of course, there's always Shapeways.

</comment></comment></comment></comment></comment><comment><USER19> Kind of sad to see them shut down. Been following them since the Baxter robot came out. Unfortunately, the current market just does not have a high demand for highly flexible robots. Most of the fully automated lines are highly specialized lines. Company invest hundreds of millions, with the expectation of maintaining the line for years. It's usually simpler and cheaper to use standard actuators with multiple stations rather than a complex robotic arm. However, the couple of applications from Universal Robotics and Kuka is pretty cool to see.

</comment><comment><USER20> Sad to see them go. I spent just under a year there ~2 years ago doing embedded systems, right before some big layoffs, and I really had a great time there.

It's a great group of people, and I wish them all the best. Judging by the amount of recruiter calls and emails I got today after the news broke (apparently working off my old resume!), I think these folks will land on their feet!

</comment><comment><USER5> The trouble with the thing was that about all it could learn was how to pick up something from one place and put it somewhere else. That's useful, but there are already lots of other robots which do that, including ones with fast vision systems.

Baxter robot, finding and picking up simple un-oriented objects and moving them.[1] Slowly.

Festo robot, finding picking up simple un-oriented objects and moving them.[2] Fast.

[1] [https://www.youtube.com/watch?v=9T91R-TPXwg](https://www.youtube.com/watch?v=9T91R-TPXwg)

[2] [https://www.youtube.com/watch?v=aH_t_1-tl40](https://www.youtube.com/watch?v=aH_t_1-tl40)

</comment><comment><USER21> I sold Baxter and Sawyer robots. They were shit. The creators had no idea about market fit. You're selling this thing to controls and automation engineers who are familiar with programming on PCs and pendants. ReThink had this ridiculous face for "emotional feedback" that forced you to also do all your programming there. It was clunky and kinda cheap (Sawyer was upgraded, and more solid). Baxter was slow with terrible repeatability. And it did not come with native ports for external controls or communication. There was no way to integrate with an existing automated system, no digital IOs or Ethernet. You had to get a third party distributor to manufacture at their panel shop and jury rig something together for extra cost.

Not to mention that UX was terrible and clunky and not intuitive. It's suppose to be easy to use, easy to program, that anyone can just role it up to an existing operators position and teach it in five minutes and you're up and running. Wrong.

As mentioned, the only interface was the obnoxious swivel screen, and the only programming controls were... dials with a push button, one located on each arm and one on the back. Yes, you had to scroll through menus and across pages to select and modify programs in endlessly confusing menus that literally made you regret ever getting involved with the company.

Yes, it had some nice collaborative safety features built in, some patented titanium s joints that flexed for safety like tendons yet maintained nice accuracy.

But no one cares about your fancey safety features if it's nearly impossible to use, and fails to seamlessly integrate into existing systems.

This is a classic mistake. Build something epically fancy, but totally worthless to 90% of the people that would use it, because it just doesn't play well. Learning curve is too high. It's not plug and play/ fails to understand industry compatibility requirements, or it's too niche.

Because I sold these things, I quickly learned they were terrible.

However, Universal Robots were on the right track from the get go. They were coming from the industrial automation world, they understood market fit. They made a device that was easy to use, intuitive, that leveraged existing programming methods and incorporated some collaborative programming technology in tandem. Maybe their gear mechanisms weren't as safe, but they passed all the requirements, so what did it matter in the end? Fancy safety joints were NOT the most important selling point for collaborative robots. Reducing downtime to increase output and profits is, and that means easy integration and quick programming. Not to mention UR was just a robot arm, and not this wacky monstrosity of a machine and wheeled based (which was optional for ReThink but not really). And UR was super compatible. It was basically like conventional single arm robot with servos slowed down and given fancy torque feedback algorithms and some sensors for safety and tracking.

The guys who started ReThink were out of their depth. Just some academics who had some success making commercial robots who expected an entire industry to conform to their fanciful dreams of robots with dopey emoting faces working along side their human comrads.

Just pissed money away.

And the thing is, they were one of the first, and positioned to be one of the best. Collaborative robotics is a massively growing field as humans and machines work in ever closer proximity.

But ReThink totally choked. Had the wrong design engineers, with no industry experience. They failed to understand industry needs and existing automation culture and prevailing systems infrastructure.

This company is a classic case study on how to completely botch the opportunity of a lifetime because of failing to understand existing market fit.

</comment><comment><USER22> Interesting that one of the top articles today is about finding the Apple II LOGO source code. One of the authors of the code is Patrick G. Sobalvarro, who also happened to be president of Rethink.

</comment><comment><USER23> >Rethink will now be selling off its intellectual property and patent portfolio...

Hopefully they sell to someone who intends to put them into practice and not some troll so these patents don't become another toxic ip spill the industry will spend the next 20 years navigating around.

</comment><comment><USER24> Aaaw. That's Rodney Brooks' company! I warmed up to the crazy old coot, thanks to his recent series of articles on AI and machine learning [1]. It's very unfortunate that his company tanked.

I hope he starts something new, soon.

____________

[1] [https://rodneybrooks.com/blog/](https://rodneybrooks.com/blog/)

That's a treasure trove of knowledge on AI with a generous dose of personal, um, perspective, but from a gentleman who has a very, very long career in the field. Do read his stuff if you fancy yourself "knowledgeable about AI".

</comment><comment><USER25> A related article is at [https://news.ycombinator.com/item?id=18143815](https://news.ycombinator.com/item?id=18143815).

</comment><comment><USER26> Wow they had a lot of positions open before they closed, was always tempted to apply. Sad for the Boston robotics scene and the larger commercial robotics industry.

</comment><comment><USER27> What companies will scoop up all the talent that was there? Can anyone speculate about what Rodney Brooks will do next?

</comment><comment><USER28> How do they compare to Boston Robotics. My understanding they were pursuing different use cases. Former is more about doing repetitive work and latter is more to do movement and carrying stuff. Although Rethink's robot look much primitive to Boston's robots, however may be what they're trying to achieve is much more complicated?

<comment><USER29> Boston Dynamics is focused on building free-moving legged robots.

ReThink was focused on building industrial robots (think robot arms) that can easily be trained/retrained to do a wide variety of tasks and that can co- exist with humans (torque sensors tell them when they've hit something unexpected and tell the arm to stop before it crushes you). The idea was that smaller manufacturing settings could use them side by side with human workers, and that a single arm could be retrained frequently as tasks change over time. This is compared to traditional industrial robots which have to be completely cordoned off from humans lest they run into them, and which require extensive programming to execute a new task.

<comment><USER28> Thanks for the explanation.

</comment></comment></comment><comment><USER30> Sad news. It's one of those things that will eventually take off -- and not too far in the future. So to me it just goes to show that today's markets are very sub-optimal, overly favoring short-term returns.

</comment><comment><USER31> A CEO's job is to set the overall vision, recruit amazing talent, and make sure there's money in the bank.

If a company wants to change the world, they can't forget #3. In fact it's probably the most important because #1 and #2 are not possible without #3.

So, how does one raise $149.5M and fail? The Fatal Pinch.

[https://avc.com/2010/08/what-a-ceo-does/](https://avc.com/2010/08/what-a-ceo- does/) [http://www.paulgraham.com/pinch.html](http://www.paulgraham.com/pinch.html)</comment>