Securing your API: a modern alternative to CSRF tokens - <AUTHOR> https://mixmax.com/blog/modern-csrf <comment><USER2> Why make an extremely complicated set up, with many edge cases, all to save yourself from a single token?

        - Privacy extensions often times block referrer headers.

        - POST requests are usually necessary.

        - Open redirects are common bugs, and getting your website to initiate one can be a problem.

        - Disabling CORS also relies on you killing crossdomain.xml, which you might overlook.

Instead you can just roll out CSRF tokens.

Having rolled them out myself many times. You probably want to use a library if you aren't a cryptographer or security person:

        expiration_time_of_1_day || hmac_sha256( secret_key, { expiration_time_of_1_day, user_id })

I've seen other people mention SameSite cookies, but we aren't near a time when browsers all support them. Don't get fancy preventing CSRF. It's a stupid bug.

<comment><USER3> Not to be That Guy, but: your sample will reuse the same token over and over until it expires, which is how you get the BREACH attack.

In Django 1.10, we switched the CSRF token generation to use a consistent _base_ value, but to combine it in a reversible way with a randomly-generated per-request nonce. CSRF verification then consists of recovering the base value and checking it; this lets you have a longer-lived "token" without sending the same value in every request/response cycle.

<comment><USER2> You're wrong. If this is generated every time the page loads you get a new token each time. OR you have to transmit a god awful amount of data on the same page.

When I work for a company that accepts GBs of data over the same TLS connection on a single page, I'll worry about breach and only generating a CSRF token every time a page loads.

<comment><USER3> From the sample code provided I was assuming the value would not update on every request (since, if you were changing the expiration timestamp on every request you'd have a bit more work to do than you've shown here -- and either way the sample you've provided isn't a great way to generate the token).

<comment><USER2> I've generated this exact token at several companies and it's worked great.

An expiration of one day is not 86400 it's unix_time()+86400, to clarify. It's not stored in the users session and is completely stateless. It's great!

It has every property a csrf token needs

\- per user

\- not guessable or forgeable

\- expires

Since it is stateless it doesn't require db lookups which can be an additional benefit. If you complain that it lacks the ability to be revoked I challenge you to find a single instance of people revoking csrf tokens.

</comment></comment></comment></comment></comment><comment><USER4> I used to prefer the origin/referer approach to blocking CSRF because it can be done upstream of the application server (or in a middleware), transparent to developers who often get these things wrong.

However there's been enough referer spoofing browser bugs lately that I'd rather have the extra safety (and complexity) of CSRF tokens. Just 3 months ago Edge had (another) referer spoofing bug: [https://www.brokenbrowser.com/referer-spoofing-patch- bypass/](https://www.brokenbrowser.com/referer-spoofing-patch-bypass/)

<comment><USER5> And another one on slide 33: [https://speakerdeck.com/filedescriptor/exploiting-the- unexpl...](https://speakerdeck.com/filedescriptor/exploiting-the- unexploitable-with-lesser-known-browser-tricks)

There are plenty of middleware-like solutions that can add solutions automatically too. And if you fail closed, you will always notice in testing and can add tokens where they are missing.

<comment><USER6> Interesting. But in both these cases (yours and @arkadiyt's) these vulnerabilities only affect GET requests right? In which case—though we would love to lock down GET requests, to prevent DOS attacks, and because GET routes _might_ in some cases modify state—the impact is pretty limited.

I (one of the co-authors of the post) would also characterize our approach as "skating to where the puck will be". I'm sure that browsers will patch these bugs, the Edge one was fixed quickly. Our product only nominally supports the latest - 1 versions of Chrome and Safari. This is of course a luxury not available to all developers.

<comment><USER5> Almost no one ever gets hacked through web app bugs at all, let alone CSRF, so in the end this doesn't really matter.

I still wouldn't recommend this as a solution though, since it's been broken repeatedly.

<comment><USER7> Man oh man I used to think the same but I took infosec training.

That taught me little. I held onto the belief hacking a target by website is only for really dumb victims.

Then I started reading Bug Bounty reports on HackerOne and BugCrowd and was terrified at people doing account takeovers with CSRF attacks on oft overlooked functionality in no name sites like Twitter or FB.

That humbled me real quick.

As an aside, FB has to put a stupid interactive prompt to not open the browser JS console unless you type a key code. In an era where people will misguidedly copy paste into that, it is real brazen to believe token stealing and other CSRF vectors are not footholds and do not really happen.

I presume I just misunderstood you, but I wanted to go on the record for those on HN secretly believing this position and call them nuts.

<comment><USER5> Are you FB or Twitter or on a similar scale?

Also, bug bounties are not representative of real attacks.

I've written my own share of complicated exploits, but from an actual defense perspective... that's not how people are getting hacked IRL. It's all word macros and sqlmap.

</comment></comment></comment></comment></comment></comment><comment><USER8> I can't shed the feeling that CORS is just piling more crap onto crap; this seems just way too complex. On one hand, I'm somewhat glad that I don't work on web things and don't have to deal with it, and on the other hand I'm scared of the many web developers are not (sufficiently) aware of the range of possible vulnerabilities and thus not protecting them.

</comment><comment><USER9> They tried to propose a simple modern solution but after reading the article it does not look simple and works much worse than traditional approach with tokens.

And of course it would be better if browsers would not make cross-origin requests unless permitted by server.

<comment><USER6> Hi @codedokode, I'm one of the authors of the post. There's a lot of background material at the top but if you skip to the use of our new module (direct link: [https://github.com/mixmaxhq/cors- gate/#usage](https://github.com/mixmaxhq/cors-gate/#usage)) I think you'll find it simpler in both code and infrastructure than a typical CSRF setup. [https://github.com/expressjs/csurf](https://github.com/expressjs/csurf), for instance, requires you to lock down every API both server-side and client- side, and by default requires session middleware; whereas with cors-gate you can register it once, server-side, before any API routes.

</comment></comment><comment><USER10> I guess the modern part here is the use of the Origin header, but in all honestly this feels really flaky in comparison to using a CSRF token. I'd argue that SameSite cookies are a better 'modern' alternative than this (for a majority of use-cases), especially because of all the edge cases that have to be dealt with for this approach (Origin not being sent, falling back to Referers, policies for those...). It feels like a giant hack.

Also, I really don't get the relevance of the refutation of "Use only JSON APIs" \- it's a fixed bug that seemingly only impacted Chrome anyway? The second point is that preflights are expensive, which might have some weight - but e.g. Twitch seem to cope okay with these preflights and I think a lot of browsers do cache them for a short period of time now anyway.

I'll be sticking to CSRF tokens plus SameSite cookies (for where the browser supports them). The only issue I can see with SameSite is that JS can still send requests (with no credentials), but I'm not convinced this is a credible DoS vector.

</comment><comment><USER11> I do this in one of our business' apps. It does strict checking of the Origin and Referer headers when it receives a POST request. We only support modern browsers, and doing this instead of using CSRF tokens feels modern and clean.

I'm paranoid though, so at the last minute, before shipping the first public version of the app, I added a traditional CSRF token check in addition to the Origin/Referer check. I guess it's a layered defense?

</comment><comment><USER12> I don't really like the word secure next to CORS; you're relying on the browser to be secure... which it is not.

<comment><USER6> You can trust the browser itself (not application code, but the native code) to issue the appropriate headers. If you could find a way of compromising that, it would be a vulnerability wayyy beyond the scope of our protection.

(Caveat: browsers may not implement the specs completely/bug-free yet, as we cover in our post. But we fully expect they will, and in the meantime our module supports fallbacks. This approach is "skating to where the puck will be".)

Non-browser clients can spoof these headers, but the risk then is DOS, not clients leveraging the user's credentials—which is the primary focus of CSRF protection. It's nice that our method can prevent browser-based DOS attacks, but that's by no means complete DOS protection.

<comment><USER3> _If you could find a way of compromising that_

CVE-2011-0696 (the Django version of a bug that _did_ affect several major things) is what happens when you find a way of getting the browser to make a cross-domain request with custom headers.

(the underlying issue there was a combination of a bug in Flash, and the semantics of the HTTP 307 status code)

</comment></comment></comment><comment><USER13> On the same topic of CSRF prevention, we also recently wrote about the dangers of using Content Types for security -- [https://medium.com/@longtermsec/chrome-just-hardened-the- nav...](https://medium.com/@longtermsec/chrome-just-hardened-the-navigator- beacon-api-against-cross-site-request-forgery-csrf-690239ccccf)

</comment><comment><USER14> > Firefox will not send the Origin header with any same-origin requests (bug)

Am I the only one very surprised to hear this? In 2017?

Is there any reason browsers shouldn't just send origin headers along with all requests? Why the exceptions?

<comment><AUTHOR> Well, it's a bug. It absolutely should send the origin header, but it doesn't ¯\\_(ツ)_/¯

<comment><USER14> I see that it's unclear, but my second set of questions was related to how chrome and safari don't send it for requests caused by img tags.

</comment></comment></comment><comment><USER15> The author admits that this solution won't work for "older" browsers. Which browser versions specifically?

<comment><USER16> [https://caniuse.com/#feat=cors](https://caniuse.com/#feat=cors) and hit "show all"

TL;DR - evergreen browsers, mobile browsers (except for images), IE 11+, and IE 8+ partially supports it

<comment><AUTHOR> For our specific solution, we also rely on (partial) support for Referrer- Policy: [https://caniuse.com/#feat=referrer- policy](https://caniuse.com/#feat=referrer-policy)

</comment></comment></comment><comment><USER17> What a well-written, insightful article! You have outdone yourself good sir

</comment><comment><USER18> What stops a user from writing a simple HTTP client to spoof the header?

<comment><USER19> Then that user can only 'hack themselves'. CSRF is a security vulnerability is because you can do a HTTP request on behalf of someone else, on someone else's browser, in someone else's session/security context.

</comment></comment><comment><USER20> Isn't JWT a modern alternative to CSRF tokens?

<comment><USER21> It's not. If you think it is you probably store JWT unsafely instead of in an httpOnly secure cookie.

<comment><USER22> Why do you think storing JWT in secure cookie is only secure solution?

</comment></comment></comment><comment><USER23> If I were to drop CSRF tokens (which work reliably) I would go directly to Origin verification. No Referer. Something in the middle is worst of both worlds.

<comment><AUTHOR> I'm curious about your comment. We (attempted) to address cases where we needed to infer the Origin from the Referer due to incomplete browser support. What about using both makes this necessarily worse, when the use of the Referer is really only a temporary bandage for said incomplete support?

<comment><USER23> Worst because it is neither proven as tokens which are used for decades already nor as convenient as simply whitelisted Origin and you even offer an extra dependency. Are those scenarios without Origin important? Like ff for form request - you can use xhr there and drop referer support entirely.

<comment><AUTHOR> You're right, support for cross-origin form POSTs isn't important for us. What is important, however, is same-origin requests, and Firefox doesn't send the Origin header with those. For us, the Referer serves its most important role by indicating where those requests originate from.

 __EDIT __: when Firefox _does_ start sending the Origin header, we may drop the Referer - we 'll see.

<comment><USER23> Just checked, indeed no origin on same site. It sucks, this makes origin barely reliable.

</comment></comment></comment></comment></comment><comment><USER24> Thoughtful article!

<comment><USER25> Thus said the "Co-founder & CTO @Mixmax" ;)

<comment><USER24> :-D</comment></comment></comment>


Facebook Updated Product Terms - <AUTHOR> https://www.facebook.com/business/m/one-sheeters/updated-product-and-technology-terms <comment><USER2> Let me tell you, I didn't even know the "Custom Audience" ad feature even existed on FB until yesterday. In fact I'd somehow missed seeing the ad preferences screen entirely, so I spent some time on that yesterday looking at all the data categories FB has put me in (rather terrifying in and of itself) and saw the bit about "advertisers who submitted your contact information" or whatever it says, and I was like WTF is this?

Here's what disturbs me so much about this — dozens and dozens (possibly hundreds) of companies that were listed there for me I have _never_ interacted with, many of which I'd never even heard of. So obviously these companies purchased third-party email lists, which themselves might have been purchased...who knows...the point is I never directly consented to any of these companies having my email address. BUT, now that they do, they are able to use those lists to target ads to me directly on FB. I consider that spam. If I get unsolicited emails from marketers, that's spam. Therefore, if I see unsolicited ads on FB due to them targeting me directly through my email (or phone number?!), that's spam!

I feel like the vast majority of FB users, and possibly many of the current critics of FB in the media or in government, aren't even talking about this horrible spam problem. In my opinion, Custom Audience is simply evil and should be obliterated from the FB ad platform.

<comment><USER3> Holy shit. I knew about the custom audience feature (a company I used to work for used it to target existing customers with promotions), but I had no idea how many different companies have submitted presumably my email address to target me.

The most surprising to me was numerous entries in that list from almost all of the local state chapters of "Americans for Prosperity" (a David Koch and Karl Rove production). I'm curious which list they used to get my email address.

</comment></comment><comment><USER4> Going to reprint here for those that are shy about visiting the facebook.com domain:

      Effective Date: May 25, 2018. To view the current Custom Audience Terms, click here

      Custom Audiences Terms

      Facebook's custom audiences feature enables you to create an audience using your data such as email addresses and phone numbers. When using Facebook's custom audiences feature, your data is locally hashed on your system before you upload and pass such data to Facebook to be used to create your custom audience (the "Hashed Data"). Without limiting any agreement between you and Facebook, by clicking "I accept," passing to Facebook the Hashed Data, or using custom audiences or advertising, you agree to the following:

      You represent and warrant, without limiting anything in these terms, that you have all necessary rights and permissions and a lawful basis to disclose and use the Hashed Data in compliance with all applicable laws, regulations, and industry guidelines. If you are using a Facebook identifier to create a custom audience, you must have obtained the identifier directly from the data subject in compliance with these terms.

      If you are providing Hashed Data on behalf of an advertiser, you must upload the Hashed Data directly into the advertiser's advertising accounts. You agree to use only that advertiser's own data to create custom audiences and not to augment or supplement the data with other data except as expressly authorized by Facebook. You represent and warrant that you have the authority as agent to the advertiser to disclose and use such data on their behalf and will bind the advertiser to these terms.

      You represent and warrant that the Hashed Data does not relate to data about any individual who has exercised an option that you have, directly or indirectly, committed to honoring or provided to opt out of having that data disclosed and used by you or on your behalf for targeted advertising. To the extent an individual exercises such an opt-out after you have used data relating to that individual to create a custom audience, you will remove that data subject from the custom audience.

      You instruct Facebook to use the Hashed Data for the matching process. Facebook will not share the Hashed Data with third parties or other advertisers and will delete the Hashed Data promptly after the match process is complete. Facebook will maintain the confidentiality and security of the Hashed Data and the collection of Facebook User IDs that comprise the custom audience(s) created from your Hashed Data ("your custom audience(s)"), including by maintaining technical and physical safeguards that are designed to (a) protect the security and integrity of data while it is within Facebook's systems and (b) guard against the accidental or unauthorized access, use, alteration or disclosure of data within Facebook's systems.

      Facebook will not give access to or information about the custom audience(s) to third parties or other advertisers, use your custom audience(s) to append to the information we have about our users or build interest-based profiles, or use your custom audience(s) except to provide services to you, unless we have your permission or are required to do so by law.

      Facebook may modify, suspend or terminate access to, or discontinue the availability of, the custom audiences feature at any time. You may discontinue your use of the custom audiences feature at any time. You may delete your custom audience(s) from the Facebook system at any time through your account tools.

      You may not use the custom audiences feature unless you are an advertiser (or an agency acting on behalf of an advertiser), Ads API or Custom Audiences API partner, a data partner uploading an advertiser's audience on behalf of that advertiser, or have obtained express, written permission from Facebook.

      You may not sell or transfer custom audiences, or authorize any third party to sell or transfer custom audiences.

      A note to EU and Swiss data controllers: To the extent the Hashed Data contains personal data relating to an individual who resides in the European Union or Switzerland, the parties acknowledge and agree that for purposes of creating the custom audiences, as described above, that you are the data controller in respect of such personal data, and you have instructed Facebook Ireland Limited to process such personal data on your behalf as your data processor pursuant to these terms and Facebook's Data Processing Terms, which are incorporated herein by reference. You hereby acknowledge and agree that Facebook, Inc. may act as a sub-processor for and on behalf of Facebook Ireland Limited for the purpose of fulfilling Facebook Ireland Limited's obligations under these Custom Audiences Terms. "Personal data," "data controller," and "data processor" in this paragraph have the meanings set out in the General Data Protection Regulation (Regulation (EU) 2016/679).

      These Custom Audiences Terms and, to the extent applicable, the Data Processing Terms, govern the provision by you of Hashed Data to us and your use of the custom audiences feature, and your use of custom audiences for advertising. They do not replace any terms applicable to your purchase of advertising inventory from Facebook (including but not limited to the Facebook Advertising Guidelines at https://www.facebook.com/ad_guidelines.php), and such terms will continue to apply to your ad campaigns targeted to your custom audience. The custom audiences feature is part of "Facebook" under Facebook's Terms of Service (https://www.facebook.com/legal/terms, the "Terms"), and your use of the custom audiences feature (including your use of data) is deemed part of your use of, and actions on, "Facebook." In the event of any express conflict between these Custom Audiences Terms and the Terms, these Custom Audiences Terms will govern solely with respect to your use of the custom audiences feature and solely to the extent of the conflict. Facebook reserves the right to monitor or audit your compliance with these terms and to update these terms from time to time.

      Last Modified April 4, 2018

<comment><USER5> And here it is without the annoying formatting that makes it very annoying to read on mobile devices...

########################################################################################################

Effective Date: May 25, 2018. To view the current Custom Audience Terms, click here

Custom Audiences Terms

Facebook's custom audiences feature enables you to create an audience using your data such as email addresses and phone numbers. When using Facebook's custom audiences feature, your data is locally hashed on your system before you upload and pass such data to Facebook to be used to create your custom audience (the "Hashed Data"). Without limiting any agreement between you and Facebook, by clicking "I accept," passing to Facebook the Hashed Data, or using custom audiences or advertising, you agree to the following:

You represent and warrant, without limiting anything in these terms, that you have all necessary rights and permissions and a lawful basis to disclose and use the Hashed Data in compliance with all applicable laws, regulations, and industry guidelines. If you are using a Facebook identifier to create a custom audience, you must have obtained the identifier directly from the data subject in compliance with these terms.

If you are providing Hashed Data on behalf of an advertiser, you must upload the Hashed Data directly into the advertiser's advertising accounts. You agree to use only that advertiser's own data to create custom audiences and not to augment or supplement the data with other data except as expressly authorized by Facebook. You represent and warrant that you have the authority as agent to the advertiser to disclose and use such data on their behalf and will bind the advertiser to these terms.

You represent and warrant that the Hashed Data does not relate to data about any individual who has exercised an option that you have, directly or indirectly, committed to honoring or provided to opt out of having that data disclosed and used by you or on your behalf for targeted advertising. To the extent an individual exercises such an opt-out after you have used data relating to that individual to create a custom audience, you will remove that data subject from the custom audience.

You instruct Facebook to use the Hashed Data for the matching process. Facebook will not share the Hashed Data with third parties or other advertisers and will delete the Hashed Data promptly after the match process is complete. Facebook will maintain the confidentiality and security of the Hashed Data and the collection of Facebook User IDs that comprise the custom audience(s) created from your Hashed Data ("your custom audience(s)"), including by maintaining technical and physical safeguards that are designed to (a) protect the security and integrity of data while it is within Facebook's systems and (b) guard against the accidental or unauthorized access, use, alteration or disclosure of data within Facebook's systems.

Facebook will not give access to or information about the custom audience(s) to third parties or other advertisers, use your custom audience(s) to append to the information we have about our users or build interest-based profiles, or use your custom audience(s) except to provide services to you, unless we have your permission or are required to do so by law.

Facebook may modify, suspend or terminate access to, or discontinue the availability of, the custom audiences feature at any time. You may discontinue your use of the custom audiences feature at any time. You may delete your custom audience(s) from the Facebook system at any time through your account tools.

You may not use the custom audiences feature unless you are an advertiser (or an agency acting on behalf of an advertiser), Ads API or Custom Audiences API partner, a data partner uploading an advertiser's audience on behalf of that advertiser, or have obtained express, written permission from Facebook.

You may not sell or transfer custom audiences, or authorize any third party to sell or transfer custom audiences.

A note to EU and Swiss data controllers: To the extent the Hashed Data contains personal data relating to an individual who resides in the European Union or Switzerland, the parties acknowledge and agree that for purposes of creating the custom audiences, as described above, that you are the data controller in respect of such personal data, and you have instructed Facebook Ireland Limited to process such personal data on your behalf as your data processor pursuant to these terms and Facebook's Data Processing Terms, which are incorporated herein by reference. You hereby acknowledge and agree that Facebook, Inc. may act as a sub-processor for and on behalf of Facebook Ireland Limited for the purpose of fulfilling Facebook Ireland Limited's obligations under these Custom Audiences Terms. "Personal data," "data controller," and "data processor" in this paragraph have the meanings set out in the General Data Protection Regulation (Regulation (EU) 2016/679).

These Custom Audiences Terms and, to the extent applicable, the Data Processing Terms, govern the provision by you of Hashed Data to us and your use of the custom audiences feature, and your use of custom audiences for advertising. They do not replace any terms applicable to your purchase of advertising inventory from Facebook (including but not limited to the Facebook Advertising Guidelines at [https://www.facebook.com/ad_guidelines.php](https://www.facebook.com/ad_guidelines.php)), and such terms will continue to apply to your ad campaigns targeted to your custom audience. The custom audiences feature is part of "Facebook" under Facebook's Terms of Service ([https://www.facebook.com/legal/terms](https://www.facebook.com/legal/terms), the "Terms"), and your use of the custom audiences feature (including your use of data) is deemed part of your use of, and actions on, "Facebook." In the event of any express conflict between these Custom Audiences Terms and the Terms, these Custom Audiences Terms will govern solely with respect to your use of the custom audiences feature and solely to the extent of the conflict. Facebook reserves the right to monitor or audit your compliance with these terms and to update these terms from time to time.

Last Modified April 4, 2018

<comment><USER4> I'm never sure the best way to format this stuff on HN. Most other sites allow you to "quote" content using the > character, but HN doesn't seem to have support for that at all.

<comment><USER5> Yea HN seems to be one of the only sites that provides a way to post code verbatim and not a way to make quoting stand out.</comment></comment></comment></comment>


Show HN: Proxino - optimize and monitor your javascript - <AUTHOR> https://www.proxino.com

<comment><USER2> I'm going to repost this here because it actually tells me why I'd want to route all my JS through a third party, and I had to click through the blog link below to find it:

[http://blog.proxino.com/post/8388203148/catching-the- worlds-...](http://blog.proxino.com/post/8388203148/catching-the-worlds-bugs- instrumentation-via-proxy)

"At Proxino, there's one question I receive with uncommon frequency: why the proxy? After all, we only ever (at the moment) handle exceptions for you, and so there is curiosity. Is it really necessary, my customer will ask. He considers, perhaps, that the proxy is some clever ploy, a small glimpse at our plans for world domination. A lovely thought, if only it were so. Developers in particular have a tendency to believe that what Proxino does can be done dynamically. They are mistaken.

In a general sense, what Proxino does is a form of global exception handling, a way to catch every exception that occurs within your Javascript. To their credit, our customers correctly suspect that some approximation of this can be achieved dynamically. For it certainly can. Here is a naive first pass attempt at such a global handler, no proxy required:

window.onerror = function(e){ console.log(e) }

Unfortunately, window.onerror does not work in every browser, nor on every piece of code. It will fail to catch some exceptions raised by elements of jQuery, and other similarly complex libraries. It's a simple one-liner, and it sort of works. But quite often, sort of is not enough.

With a bit more care — and a lot more code — a clever programmer can find dynamic work arounds for most browsers and most popular libraries. However in the general case, a global exception handler constructed dynamically is something of an elusive, asymptotic state. You are simply not going to get there. And this brings me to my point. Proxino is not interested in most. We want to catch, and tell you about, everything that goes wrong in your Javascript. Enter the proxy.

When a request reaches proxy.proxino.com, we lookup your existing code, parse it into AST form, and walk down the tree inserting special try/catch blocks within each function definition, as well as around the file itself. We then serve this instrumented file to your users, and handle every exception that occurs. Naturally, we have optimized this process for speed (with caching, etc.) but this guarantees us — and more importantly, you — complete code coverage. You will know about every exception.

Dynamic approaches are incredibly convenient in some ways, but in the general case they simply don't work. And so there is a Good reason for the proxy. Hope this helps."

<comment><USER3> Hmm— I wonder how that works with exception-handling code. It'd be a pain in the ass to get notifications for normal behavior.

They must have thought of this, and it'd easy enough to ignore functions that are already inside `try` blocks, but it's strange that it's not mentioned.

<comment><USER4> I haven't looked at it yet, but perhaps they rethrow exceptions. This will mess up line numbers in stack traces but otherwise should behave similarly to original code.

</comment></comment></comment><comment><USER5> This was originally posted 2 weeks ago before their name change from Taazr to Proxino. For original discussions on the site: <http://news.ycombinator.com/item?id=2833945>

</comment><comment><USER6> Any indication of what you get out of this service? I know the fundamentals, but the site's sneak-peek content consists of a TextMate screenshot and documentation. That's all push - what's the pull?

</comment><comment><USER7> This is really cool, and exactly what I need.

Consider me signed up.

</comment><comment><USER8> You can do this pretty easily without a third-party by just using window.onerror, and then doing an ajax request to log it.

<comment><USER9> Not necessarily -- window.onerror isn't fully supported by some browsers and libraries:

[http://blog.proxino.com/post/8388203148/catching-the- worlds-...](http://blog.proxino.com/post/8388203148/catching-the-worlds-bugs- instrumentation-via-proxy)

<comment><USER8> Yeah and just as easily you can put a try/catch around your code and do the same ajax logging.

<comment><AUTHOR> Sure, that is possible if you want to spend the time wrapping every function in your code with a try/catch block. Most people don't, and so we provide automatic code instrumentation. You can't just wrap your js file in a single try/catch.

<comment><USER10> I understand why you'd rather not provide this as a standalone tool, but I'd much rather run such a tool as part of my existing compilation process than use your proxy service.

</comment></comment></comment></comment></comment><comment><USER11> Am I reading the docs correctly...put your secret key in the client side script block?

<https://www.proxino.com/docs/getting_started>

<comment><AUTHOR> Secret is a misnomer; it is actually a public key.

<comment><USER12> Many APIs call it a _client key_ or a _client ID_. That makes a lot more sense than _secret_.

I suggest that Proximo change it in their API and in their docs.

<comment><AUTHOR> Noted. We will change it soon. Thanks!

</comment></comment></comment></comment><comment><USER13> I'm interested, but before I continue I'd like to see screenshots or a demo so I can get a feel for the product.

</comment><comment><USER14> What happens if Proxino goes down?

<comment><AUTHOR> Your scripts will load from local urls. More details on this can be found in the docs: <https://www.proxino.com/docs/getting_started>

<comment><USER15> Does that work for CoffeeScript files? Looking at proxino.js, it doesn't appear to work for it. If you could have a version that included the CoffeeScript compiler, I'd be very likely to use this.

<comment><USER15> After signing up I received an email asking if I had any questions. I asked this one, and they responded that they don't support it yet, but they're working on it.

</comment></comment></comment></comment><comment><USER16> Is it not proper to spell JavaScript with a capital J and S?

<comment><USER17> Either Javascript or JavaScript is acceptable.

<comment><USER18> What do you think of Jquery?</comment></comment></comment>


SQLite Code of Conduct - <AUTHOR> https://www.sqlite.org/codeofconduct.html <comment><USER2> Of course it is satirical but I think people forget that the CoC's that been gaining traction lately are themselves a response to a real problem.

Yes, some CoC's may be fodder for satire and criticism because they cross the line when it comes to being excessively dogmatic. However, these things exist because online communities have been beset by hordes of assholes for a very long time. Many people feel excluded or are dismissed just because some jerk manages to wield a measure of virtual power.

It would be a mistake to move in the reverse direction now and abandon CoC's. If they're not working, perhaps change them or try something else, but the problem needs to be addressed.

<comment><USER3> What problem? We didn't need CoC for 20 years, why do we need it now?

<comment><USER4> because software development has become a professional enterprise, and with that people develop standards on how to interact with each other in large and small organisations, rather than just winging it in a garage.

Anyway, "we didn't need X then, why do we need X now" is an absolutely atrocious argument. Because demands and communities change obviously, and with them how we conduct and organise our communities and organisations.

</comment></comment></comment><comment><USER5> It is not obvious that this is satire. Mr Hipp (main contributor) links his homepage at [http://www.hwaci.com/drh/](http://www.hwaci.com/drh/). From that page, he links his wife (Mrs. Wyrick): [http://www.hwaci.com/ggw/index.html](http://www.hwaci.com/ggw/index.html). She has among her interests: [http://www.hwaci.com/ggw/allerton.pdf](http://www.hwaci.com/ggw/allerton.pdf) "Church Music Resources".

As mentioned elsewhere in this thread: SQLite is "Open-Source, not Open- Contribution". In that context, an openly religious CoC does not seem out of the question.

<comment><USER6> We don't need to rely on this circumstance. We can point directly to Hipp's own words: [https://twitter.com/DRichardHipp/status/1054360847319994368?...](https://twitter.com/DRichardHipp/status/1054360847319994368?s=19)

</comment></comment><comment><USER7> Note that SQLite is, in it's own words, "Open-Source, not Open-Contribution". SQLite does not accept patches from the public.

See [https://www.sqlite.org/copyright.html](https://www.sqlite.org/copyright.html)

Looking at the commit history for the project, all of the commits for 2018 have been from just three people (with 98% of those coming from just two of those).

</comment><comment><USER8> This is a lovely piece of satire given the prevailing obsession with silly CoCs all around.

<comment> julian-klode CoCs are not silly, they solve very important and real problems.

<comment><USER8> CoCs on their own solve exactly nothing, they're just a tool that's supposed to enable project leadership to solve certain issues more effectively. Whether they actually serve that function is an open question since the practice is still fairly new. I haven't seen any meaningful evidence one way or the other (feel free to provide some).

While I'm sympathetic to the argument that sufficiently large projects should, on average, benefit from some degree of formalization of behavioral norms (whether you call it a code of conduct or something else), the recent trend of insisting (often abusively) that every open source project, however small, should adopt this practice is silly, annoying and has obviously caused a backlash in some parts of the open source community, hence this thread.

<comment><USER9> > since the practice is still fairly new

"in tech". The CoC we're discussing here exists - as CoC - for Millenia.

An even older example would be the [https://en.wikipedia.org/wiki/Hippocratic_Oath](https://en.wikipedia.org/wiki/Hippocratic_Oath), which might have been more appropriate as an example of a "code of work conduct", but "I swear by Apollo the Healer, by Asclepius, by Hygieia, by Panacea, and by all the gods and goddesses" might rub some people the wrong way, including, in this case, sqlite's author.

<comment><USER8> I'm specifically talking about open source communities. I think the context of these social structures (spontaneous organization, lack of traditional coercive motivators (money, enforcement mechanisms, social pressure), the fact that many people are pseudonymous, the fact that most projects are effectively tyrannies, etc.) makes them sufficiently distinct from the classical examples you list to make any direct comparison very difficult.

</comment></comment></comment></comment></comment><comment><USER10> While we often confuse religion with the practices of the idiots fawning over politicians here in the US, there is beauty to be found in the wisdom of the ancients on occasion.

</comment><comment><AUTHOR> "1\. First of all, love the Lord God with your whole heart, your whole soul, and your whole strength."

</comment><comment><USER11> Hell, I'm a Muslim and I'd sign on to this CoC without hesitation.

</comment><comment><USER12> > 66\. Do not love quarreling

I'm seeing a problem here.

<comment><USER13> Yeah, us Sparrow-keepers are OFFENDED !

</comment></comment><comment><USER14> What has God to do with SQLite?

<comment><USER15> Best I can tell is satire

<comment><AUTHOR> Dangerous not to make that more clear if true.

<comment><USER16> Isn't the whole point of good satire that it's not immediately evident whether it's a joke or not?

Regardless, I don't see how this satire could be considered dangerous.

<comment><USER17> > _Regardless, I don 't see how this satire could be considered dangerous._

Watch the twitter mob forming outside the window!

<comment><USER7> You can watch the mob forming in realtime. [https://twitter.com/search?q=sqlite&src=typd](https://twitter.com/search?q=sqlite&src=typd)

> "I hope there are discussions at REDACTED today about whether featuring > SQLite on their front page is consistent with their values."

> "The message is clear: if you're concerned about diversity, decency, and > inclusiveness, stay well away from the SQLite project."

> "I wonder if SQLite Consortium member organizations @mozilla, NDS > association, @BentleySystems, @expensify, @business were consulted on this > move."

> "This is the as > __*le:[https://en.wikipedia.org/wiki/D._Richard_Hipp](https://en.wikipedia.org/wiki/D._Richard_Hipp) > … (thanks @weigandtLabs for finding that out). He _is_ the main SQLite dev. > And that's the community he's building. So SQLite is now dead -- or, at > least, it should be."

<comment><USER17> Pathetic. I am not a user of twitter precisely because I have no interest in reading those sort of reactions. But I am strangely fascinated by this continuous stream of 1st degree, knee jerk reactions, it's kind of like watching shit flowing out of a bull's ass...

</comment></comment></comment></comment></comment></comment></comment><comment><USER18> pure awesomeness

<comment><USER19> I agree. I'm enjoying so much the reaction...

</comment></comment><comment><USER20> That's a joke, right? Right?

</comment><comment><USER21> Bad bad man. Goofy documents shall only get the benefit of the doubt if they're brought in by postmodernists.

</comment><comment><USER22> Dang why is this flagged?

Also as a muslim, it's very amusing to me that there are people who are fighting for me without my asking them and yet them telling me and other muslim it's bad.

It's hilarious what the politically programmed noise-makers think of themselves.

<comment> atom-morgan "Politics* isn't allowed on HN"

*right-leaning

</comment></comment><comment><USER15> WTF? Please tell this isn't for real.

``` This rule is strict, and none are able to comply perfectly. Grace is readily granted for minor transgressions. All are encouraged to follow this rule closely, as in so doing they may expect to live happier, healthier, and more productive lives. The entire rule is good and wholesome, and yet we make no enforcement of the more introspective aspects.

Everyone is free to use the SQLite source code, object code, and/or documentation regardless of their opinion of and adherence to this rule. SQLite has been and continues to be completely free to everyone, without precondition.```

Do I have to go for confession before every pull request now?

<comment><USER23> You would have never made a pull request for SQLite anyway, since anyone in a position to do that would know they don't use GitHub.</comment></comment>


Response to John Cook's "Myth of the Lisp Genius" - <AUTHOR> http://rondam.blogspot.com/2011/04/is-it-lisp-or-is-it-me.html

<comment><USER2> Not that I don't agree with some of the points raised, but the article's purpose is to be a refutation to this claim:

         There are genius programmers who write Lisp,
         and Lisp may suit them well. But these same folks
         would also be able to accomplish amazing things in
         other languages.

Languages and tools are not created equal, but the author assumes he's one of those geniuses, which may not be the case.

Extraordinary developers do extraordinary things, regardless of the tools used. Here's an example, using as reference <http://en.wikipedia.org/wiki/Git_(software)#Early_history>

_The development of Git began on April 3, 2005. The project was announced on April 6, and became self-hosting as of April 7. The first merge of multiple branches was done on April 18. Torvalds achieved his performance goals; on April 29, the nascent Git was benchmarked recording patches to the Linux kernel tree at the rate of 6.7 per second._

And here's the kicker: Linus would probably be more productive in LISP, but would he bring more value to the world? Probably not, as churning out code is not Linus' strength -- he outcompetes everyone by superior design, by pragmatism and by being a good team-leader.

That's the type of developer I admire -- people that kick-ass in bringing value and making sacrifices is part of that. Sometimes you have the luxury of picking up a new language (Ruby) and invent a new web framework with it (Rails), sometimes you don't. Either way, code talks bullshit walks (so to speak).

<comment><AUTHOR> > the author assumes he's one of those geniuses

Exactly the opposite actually. Not only do I not assume that, I specifically deny it.

<comment><USER3> Actually, even though you deny that you are a genius I think you are. I don't think your article refutes the original article by John Cook at all as you are one of the very small percentage of people that can "make things happen" in Lisp or any other language.

I would suggest you are too much of an engineer to use an "inferior" tool like C++ or Java because you know there is something "better" otherwise I am sure you would achieve equally spectacular results in other languages.

<comment><AUTHOR> > you are one of the very small percentage of people that can "make things > happen" in Lisp or any other language

Although I'm flattered, I have to ask: what possible basis could you have for making that assessment? My track record certainly doesn't support you.

> I would suggest you are too much of an engineer to use an "inferior" tool > like C++ or Java because you know there is something "better"

A true engineer solves the problem under the constraints that he is given. I have a this tendency to try to change the constraints -- or the problem. Those can be advantageous personality traits for some tasks, but they make me a damn poor C++ coder.

</comment></comment></comment></comment><comment><USER4> I started seriously focusing on learning Lisp perhaps a year ago. My exposure to Perl had brought me to the point where I understood the idea of functions as first class in their own right.

Lisp rolled forward my mind into new places of understanding how to program. It was like having lights flicked on all over the place. I've been able to conceptualize post-Lisp in ways I did not before.

Perhaps Haskell would have done similar things. I can't say. But Lisp definitely did, and I believe that given the project (and a sufficient lack of having to interface into weird libraries), I could do more in a given slot of time in Lisp than I could with other languages.

<comment><USER5> Yeah, Lisp is a really good mind-bender. If you picked up some good experience with CLOS, I recommend using the Moose packages in your perl work. Moose adds to Lisp's default CLOS with lazy attributes, roles, and a functioning type system.

SML, OCaml, and/or Haskell will show you a new way of looking at types (and secondarily, expose you to unification on a level that is a little deeper than destructuring-bind). If your background is in perl and then some Lisp experimentation, I recommend checking these others out in order to fill in this other nice piece in the equation. Finally, once you have convinced yourself that type systems are the hotness, it will be good to expose yourself to Erlang, specifically with regard to error handling and the role of supervisors for process restarts.

</comment></comment><comment><USER6> A brilliant anecdote, yet I am curious how you can still believe in the dreaded "lisp curse," after experiencing so much success with it.

Is it an attribute of Lisp that there exists a mythical lone-wolf that seeks to produce software so pure and elegant that no mere mortal can possibly understand it? Is it an attribute of Lisp that this lone-wolf, like a by-gone action hero, prefers to work alone?

Lisp, like any sufficiently useful language, simply gives you enough rope. It's good, sturdy, and well-tested rope. You could probably climb a mountain with it. Or hang yourself. Your pick. The rope has very little to do with it.

<comment><AUTHOR> I experienced _personal_ success with it. It's not that Lisp _causes_ people to not be able to work together. The causality runs in the other direction. Lisp tends to attract people who are antisocial by nature, because if they use Lisp they can be vastly more productive as individuals than if they don't. But then you get a community full of antisocial people, and they tend to drive away the team players. So the team players go off and use C/Perl/Ruby/Python/whatever because those communities are full of other team players. As a result, the whole becomes greater than the sum of the parts, and the team players win, even though as individuals they may be generally less productive/smart/whatever.

On those rare occasions when Lisp programmers manage to all row together in the same direction they can produce some truly spectacular results (Viaweb, ITA, RAX). But those seem to be the exceptions.

<comment><USER7> Have you ever found it difficult to understand someone else's lisp project, because they have customized the language so much? (or vice versa, has a fellow lisper found your code hard to understand)

I wonder if the flexibility and power of lisp might work against co-operation in this way too.

I've witnessed confusion caused by operator-overloading in C++ (I heard that that's common); lisp is more customizable.

<comment><AUTHOR> > Have you ever found it difficult to understand someone else's lisp project, > because they have customized the language so much?

Yes. But that is not a problem unique to Lisp. It's possible to write unreadable code in any language. And in general Lisp's introspection capabilities and macroexpand make it easier to reverse-engineer things that in other languages.

<comment><USER7> opps, I what you mean; I actually meant well-written lisp.

Have you found that hard to understand, when it was heavily customized? I agree that tracing through complex code is taxing in any language; and it probably becomes much more important what concepts the author has chosen (and things like coupling/cohesion), than the language.

i.e. That the problem wasn't that the code was badly written, but it was because they had "customized the language so much". Extensive customization i how you're supposed to use lisp; it's an important source of its power. (The C++ example I mentioned was well-written.)

I can imagine it going either way (e.g. that lisp's customizations often aid clarity, by reducing code size); so I'm interested to hear someone's experience of how it actually goes in practice.

<comment><USER8> I have seen that happen before, but only when the domain was inherently complex. An example I actually committed; for a variety of reasons I needed a continuation driven LL(1) parser for my PhD thesis, and I needed it to be in Java. I wrote this as a Scheme program that output Java code. I tried hard to make things understandable (since I had to debug all of it!) but the Java code was basically incomprehensible and the Scheme program that generated it required some relatively sophisticated understandings of parser theory to understand the notation I was using.

A good theoretical example is: imagine trying to understand what a CPS driven compiler is doing with no understanding of CPS. That would be pretty hard in any language, and it's actually better in Lisp because you can express things closer to the theory.

</comment></comment></comment></comment></comment></comment><comment><USER9> It's worth noting that he says (in the other article he links to): "In fact, in a number of cases I saw people whip things up in Perl in a couple of hours that would have taken me days or weeks to do in Lisp.".

So therefore Perl > Lisp > everything? (I'm kidding for the humour impaired)

What he gained from using Lisp was not worrying about memory management, and built-in data structures that made life easy. These days you can get that with a lot of different languages (and I would argue that Java is not one of those languages), languages that also perform as well as Lisp.

So what's my conclusion? That I think there are both - genius programmers who can code well and quickly in just about any language, and also languages that let you build things a lot faster than traditional languages.

<comment><USER10> My guess is that you didn't seriously learn functional programming in any language.

It is not just about memory management and data structures. It is about functions as first class objects, no side effects, lazy evaluation, closure, monads. The fact that you can basically write a compiler in an hour as a first year student (that was exercise 3 in my course).

I'm not a programmer, I'm a DBA. The code I write is mostly short and ugly scripts in Perl and Bash. I can do very little Java and almost no other language. The one and only time I used Lisp was in my first programming course in the university. Incidentally, it was also the one and only time I enjoyed programming.

<comment><USER9> That would be a bad guess. For a start, Lisp is not a functional language. It just has some functional features. It has side effects.

I learned FP using Haskell, which is a pure functional language.

But I still stand by what I said. I code faster in Perl than I do in Haskell due to the availability of libraries. The "pure FP" features may make some things theoretically cleaner, but they don't honestly make things that much easier. Having _access_ to FP features (map, grep, reduce, closures in particular) is significant, but access to built in data structures (hashes in particular) make life so much easier than C or C++ or Java.

<comment><USER11> I'm sure baudehlo knows, but some other readers may not: map, grep, and closures are all native in Perl 5, and reduce is easily available. (All are native in Perl 6.)

<comment><USER9> reduce is "included" - it's just in a loadable module in the core library.

</comment></comment></comment></comment></comment><comment><USER12> This response was much more substantial than the original article.

To say that the original article was "about" Lisp, or the Lisp Genius, would be akin to my saying that there are fleas "about" my dog.

BTW: I wonder if Rondam(?) knows this guy: <http://www.flownet.com/gat/jpl- lisp.html>

<comment><USER13> Same person. He changed his name a while back.

</comment></comment><comment><USER14> I like and agree with the article, but:

        an attempt was made to port part of that code (the
        planner) from Lisp to C++. After a year that effort
        had to be abandoned because the planner team just
        couldn't make it work.

I'm sure they'd struggle just as much if the planner was written in assembly, and not because assembly is a far more elegant language...

<comment><USER15> Given that assembly is simpler than C++ both syntactically and semantically, a reasonable argument could be made that it is a more elegant language.

</comment></comment><comment><USER16> "A team of competent programmers willing to put up bullshit will out-compete a lone wolf striving for elegance no matter how brilliant he is."

I'm doomed.

</comment><comment><USER17> It seems that the main thing this guy is really saying is that Lisp is easier to program in than C++. I don't think that that's controversial around here. What is controversial is whether Lisp has a significant advantage over Python, Ruby, etc. Heck, he didn't even actually point out any advantage of Lisp over _Java_.

</comment><comment><USER18> A better response:

stop linking to John Cook.

Every John Cook blog entry I have ever read turns out, upon inspection, to be an almost-content free restatement of an accepted consensus -- motherhood statements at best.

Whereas Jeff Atwood at least gives credit to the books he reads and summarises, Cook merely regurgitates unsourced factoids and leavens with a few unimpressive anecdotes.

<comment><USER19> And yet, I never cease to be amazed at how many people need to be reminded of many of these accepted truisms.

<comment><USER18> Which can be more effectively done by referring people to the original sources rather than rehashing some folk lore.</comment></comment></comment>


Startup: Targeted sharing with friends most likely to read and discuss   - <AUTHOR> http://www.additback.com/

<comment><AUTHOR> Additback.com turns social "likes" into increased traffic for a site. It analyzes the social graph of users and recommends friends to be tagged who are most likely to read, like and discuss the post. Powered by a state-of-the-art recommendation engine, it also generates content recommendations to increase the time spent by a user on a website.</comment>


How Windows tech support scammers walked right into a trap set by the feds - <AUTHOR> http://arstechnica.com/tech-policy/2012/12/how-windows-tech-support-scammers-walked-right-into-a-trap-set-by-the-feds/ <comment><USER2> As great as it is that a few of these people have been caught, the reality of the situation is that not enough resources and person-hours are being dedicated to cracking down on these scammers. The tl;dr of the article is that 14 corporations and 17 individuals have had injunctions filed and summonses issued against/to them, but the scams aren't going to stop anytime soon.

I feel like retailers could make an easy profit by bundling a small book with practical computer advice (e.g., avoiding scams, viruses, etc.) with purchases for an extra $5-10, but they're too busy stuffing bloatware down the consumer's throat to care.</comment>


MOZAUS - <AUTHOR> https://mozaus.com/

<comment><AUTHOR> With MOZAUS you can create a stunning photomosaic in a minute and make a great gift! This online service is well optimized and truly cross-platform - <USER2> in any browser on any device.</comment>


The Complete Guide to Know the Relationship Between Telomerase and Tumor - <AUTHOR> https://www.creative-bioarray.com/products/tumor-cell-types-13.htm <comment><AUTHOR> Specific Information Related to Tumor Production 30 trillion normal human cells make up a complex and interdependent environment of common management, mutual regulation. A cell proliferates only when it receives growth stimulating signals from other nearby cells and stops growing when it receives an inhibitory signal. This interaction allows each tissue to maintain a certain size and shape to suit the needs of the body.

In contrast, cancer cells, which ignore signals that normally control proliferation, only follow their own intrinsic proliferation criteria. They can even move in and invade neighboring tissues. Due to such malignant tumor cells invade more and more tissues, they will cause the death of body when they interfere with the organs and tissues the body needs for survival.

Many of the proto-oncogenes normally function to transmit outside stimuli to cells. When a protooncogene mutation affects an important growth stimulating signal, it will activate the silenced gene. Some proto-oncogene mutations will interfere with part of the signal pathway in cells, such as Ras protein, so that in vivo genes are also activated in the absence of signals from outside growth stimuli.

</comment><comment><AUTHOR> Inhibition of the external signal is also can not be introduced into the cells due to the signal cascade interference. In addition, the cell cycle of cancer cells is also disturbed. A large part of the tumor cells in the p53 gene is missing or loss of function, which will lead p21 protein loses its ability to inhibit the cyclin, CDK5 and their complexes, thereby leaving the cell cycle unrestricted.

Generally there are two methods tissues involved to control cell proliferation and avoid cancer: One is cell apoptosis when important components in the cell are damaged or the control system is dysregulated; the other is the limit of cell multiplication.

</comment><comment><AUTHOR> Tumor is a kind of disease that faces various difficulties for treating because our immune system can not recognize it, and the tumor cell is a permanently dividing cell. Telomerase is essential for the immortalization of tumor cells so that it can serve as a good target for antineoplastic agents. If there are drugs which are able to turn off telomerase in tumor cells, the length of telomeres will gradually decrease as tumor cells divide, mutations will occur and tumor cells will become unstable. Experimental drug treatments have been performed in mice, while some drugs entering the early clinical trial phase.

</comment><comment><AUTHOR> In normal human cells, telomere shortening limits the grow ability of cells, telomerase re-expression plays an important role in cell immortalization and carcinogenesis. Therefore, some researchers think that cells with normal expression of telomerase activity will be easier to turn into tumor cells. In determining telomerase activity, it was found that more than 90% of normal tissue cells were negative for telomerase, associating this enzyme with the immortalization of the cells and the tumor. This situation has important clinical value for telomerase activation, diagnosis and suppression.</comment>


AWS Cape Town region goes live - <AUTHOR> https://mybroadband.co.za/news/cloud-hosting/349001-aws-cape-town-region-goes-live.html <comment><AUTHOR> This has been a long time coming for AWS users in southern Africa, as news about this region launching has been going around for a number of years. Fantastic to see it launch, I know it took a lot of hard work for the AWS CT team.</comment>


Show HN: SeKey: An SSH Agent for OS X, Using Secure Enclave and TouchID, in Rust - <AUTHOR> https://github.com/ntrippar/sekey <comment><USER2> see also the really excellent kyptonite, which i found linked here a few months ago and i've been positively delighted with:

[https://krypt.co/](https://krypt.co/)

i'm not a security expert, and i have a lot more trust in my iphone for managing secrets than my personally configured linux pc's.

<comment><USER3> I have a slightly different point of view:

In Linux, I can easily monitor how much data, what kind of data are transferred to the remote IP and disable them on per apps base anytime I want.

In IOS, I can't do any of that. At most, I can only disable an app from using cell data. If anyone else know how to do monitor/block network connection on per APP base in IOS, I would love to hear about it.

For me, it is a different between "trust" and "trust and verify".

I use IOS and have some level of trust on Apple/IOS. But I don't trust majorities of the IOS APPs for security/privacy.

<comment><USER4>
      If anyone else know how to do monitor/block network connection on per APP base in IOS, I would love to hear about it.

I've been seeking a Little Snitch type connection monitor/firewall for iOS for some time. I believe Apple purposely makes this difficult/impossible on iPhones due to the constant metrics/analytics sent to Apple servers.

Look at what they have done with turning off bluetooth and wifi from the Control Center.. It's really eye-opening to see how often Apple products ping home.

<comment><USER5> _I believe Apple purposely makes this difficult /impossible on iPhones due to the constant metrics/analytics sent to Apple servers._

I don't think that follows. Allowing applications to intercept and mess with other application's network traffic would be an obvious security issue; that's far more likely to be the reason than some kind of vague "we want to track your data" thing.

It's certainly possible that Apple could construct an appropriate API for allowing users to configure apps in such a fashion that they could monitor network traffic, much the same way as similar APIs exist for accessing e.g. photos. But since it's a niche application at best, I'm hardly surprised they haven't done so.

<comment><USER6> Such an API already exists: the NetworkExtension APIs, specifically NEPacketTunnelProvider and NEAppProxyProvider. They're meant for VPNs, but it should be possible to use the same APIs to monitor traffic and send it on, rather than tunneling it through a VPN. (There is also NEFilterProvider, but that API is designed to run the filter in a tight sandbox that doesn't allow it any outbound communication, so that it can filter packets but not exfiltrate them.)

…though if you're concerned about privacy, perhaps you should be using a real VPN anyway, in which case you could handle traffic monitoring and filtering on the server side.

Edit: I guess the server-side approach wouldn't allow identifying on which app is making the connection. The NetworkExtension APIs, however, should allow that: you get a flow of NEPackets, each of which has a 'metadata' property containing a 'sourceAppUniqueIdentifier' and 'sourceAppSigningIdentifier'. I don't have personal experience using these APIs though.

</comment></comment></comment></comment></comment><comment><USER7> Very, very cool.

To use a public key with something like Userify ([https://userify.com](https://userify.com), plug ssh key management) or a service like Github, use _\--export-key_ to export the public key in OpenSSH format:

        sekey --export-key <key-id>

(see also in the readme that you can use sekey --list-keys to get key ID's.)

This is seriously such an awesome project that I might have to get a new MBP just for this.

</comment><comment><USER8> For TPMs on non-Apple computers: [https://github.com/ThomasHabets/simple-tpm- pk11](https://github.com/ThomasHabets/simple-tpm-pk11)

But with TPM there's no external unlock mechanism like Touch ID, the TPM unlock happens from the operating system.

</comment><comment><USER9> This is a really cool project. I just tried to compile it myself, and code- signed it with my mac dev key. I changed the assets/sekey.entitlements file by replacing 5E8NNEEMLP with my own hex id for my developer key.

However, when i run ./bundle/Sekey.App/.../sekey, i keep getting a "Killed 9" message.

When i run the unsigned version, the binary at least runs (shows the -h messages). Any hints on how to fix?

<comment><AUTHOR> thats because the code signing its invalid. you are signing the whole app? or only the binary. could be many reasons, one is the lack of the provisioning profile on your computer (for your key).

</comment></comment><comment><USER10> This looks useful. I'd love to use this with gopass ([https://github.com/justwatchcom/gopass](https://github.com/justwatchcom/gopass)). It would have to support preexisting keys for that to work for me.

I wonder if the limitation around elliptic curve keys originate with the Secure Enclave, or is that just the one type of key this tool supports?

</comment><comment><USER11> I would love to see this usable as a U2F device too.

</comment><comment><USER12> Very cool project. I've done similar things with yubikeys before, having it built into the hardware is great.

Can it also support a pin to go with the biometric auth?

<comment><AUTHOR> as far i read in the documentation no. i will do more research on the implementation. also you device has to be unlocked for the enclave to work.

[https://developer.apple.com/documentation/security/ksecattra...](https://developer.apple.com/documentation/security/ksecattraccessiblewhenunlockedthisdeviceonly)

</comment></comment><comment><USER13> > Can't import preexisting key

That makes me sad :( Does anyone know if that's a SE limitation, or the app's?

<comment><AUTHOR> it's SE limitation :(. also makes me sad, will be awesome if you can import a key generated by yourself. so if you reinstall you can import again to the enclave

<comment><USER14> It's common for hardware security tokens like this to limit themselves to self-generated private keys. The intent is the device needs to provide a guarantee that the private key is not otherwise accessible, whereas it would be if the user generated it, perhaps wrote it to disk, provided it to the SE, and perhaps SEs on other devices.

<comment><USER15> YubiKeys allow you to load your own private key, which turned out to be a great feature. [0]

[0]: [https://www.yubico.com/support/security- advisories/ysa-2017-...](https://www.yubico.com/support/security- advisories/ysa-2017-01/)

</comment></comment></comment></comment><comment><USER16> Awesome work, this is a really cool idea and well executed.

</comment><comment><USER17> I'm amazed there's a market for this kind of thing. Since the 1990s its been known how to implement an undetectable backdoor in hardware based crypto which leaks your keys to an attacker.

E.g. [http://paper.ijcsns.org/07_book/201006/20100623.pdf](http://paper.ijcsns.org/07_book/201006/20100623.pdf) details how to do it for Elliptic Curves. But its been studied since [https://link.springer.com/content/pdf/10.1007%2F3-540-69053-...](https://link.springer.com/content/pdf/10.1007%2F3-540-69053-0_6.pdf)

The tl;dr is that any device in which you can't check the implementation or get the private key out (i.e. Secure Enclave, TPM etc), can leak your key to a passive attacker in a way that you _provably_ can't detect.

<comment><USER12> On the flip side, you can also demonstrably prove that private keys stored on disk can be exposed with a minimal intrusion of your user account, also with no indication they were leaked.

Another layer of security is never bad.

<comment><USER18> Additional layers of security can be bad when they reduce usablity, reduce accessibility/availability, or increase complexity too much.

As usual it's trade-offs all the way down.</comment></comment></comment>


Forget fears of automation, your job is probably bullshit anyway - <AUTHOR> http://www.wired.co.uk/article/bullshit-jobs-david-graeber-review <comment><USER2> In terms of impact to society I wonder what the effect would be of UBI and releasing people from BS jobs: would people use their new free time in a socially neutral or better way, or would anti-social acts increase? Our BS jobs give us something to do; I don't think increasing everyone's idle time will end up well.</comment>


Clojure from the ground up - <AUTHOR> http://aphyr.com/posts/301-clojure-from-the-ground-up-welcome <comment><USER2> > I want to convince you that you can program, that you can do math, that you > can design car suspensions and fire suppression systems and spacecraft > control software and distributed databases,

I know you are trying to help but you need to realize that the whole section, and this part in particular, is incredibly condescending and guaranteed to piss off any female who might be reading you.

You want to help achieve gender equality in the technical field?

Pretend that the gender of your reader is of no consequence and just write your stuff, period.

<comment><USER3> I agree that the part you quoted could come off condescending, but I disagree with your prescription. We have plenty of resources for learning how to code that make no gender assumptions, and yet we still have a glaring disparity. I see little reason to believe that your suggested solution of writing dispassionately about coding while avoiding elephant in the room of the gender disparity, in a piece meant to address that, is the proper remedy.

<comment><USER4> Agreed, it struck me as unique that the author says anything about women. I have seen dozens (if not hundreds) of programming tutorials and that was the first one that said anything about genders. The problem is somewhere else.

</comment></comment></comment><comment><USER5> The "who is this guide for?" section seems a bit out of place here in an otherwise technical document. While I appreciate the sentiment, studies have shown that girls/women perform worse on tests if they are reminded that they're female right before they take the test - I would imagine that a similar effect might occur when learning Clojure (for any of the discriminated groups mentioned in the welcome message). If someone has managed to find this page, chances are they already know a bit about programming and don't need a welcome message - no?

<comment><USER6> Three reasons. First, I want to justify and contextualize the work in the hopes of promoting more like it. Second, stereotype threat is ameliorated by explicit acknowledgement of the effect. Third, I want to challenge implicit assumptions about the audience of technical writing.

<comment><USER7> You may have good intentions but this article was condescending, destructive and self-serving.

You keep reinforcing these stereotypes about IT that (a) women aren't capable, (b) men are antagonistic towards women (c) they will never be promoted or accepted amongst their peers and (d) there is rampant sexism. These stereotypes are not pervasive, not unique to just IT and simply don't exist at many types of companies in particular many enterprises.

But don't worry women despite all of this you have come to save the day with a beginner's Clojure article that will gain you the respect of your peers. Give me a break.

<comment><USER8> Give yourself a break.

If you don't like how others are trying to raise awareness or encourage women in IT, then get off your high-horse and do something yourself that you do agree with. Sitting there lambasting others' efforts does nothing to improve the situation.

<comment><USER9> I'm getting really tired of this "go do something else" argument/excuse. Doing something constructive yourself is not always a solution for someone else doing something destructive. It's like the tu quoque fallacy, only good for getting someone to shut up, proving nothing. Heaven forbid we should try to prevent something bad from happening.

</comment></comment></comment></comment></comment><comment><USER10> I know I'm posting this after this article has peaked, but I did that on purpose. Maybe you won't ever read this. Probably not.

Aphyr I really admired you dude until you decided to post extremely graphic descriptions of your sexual activities on Twitter. I unfollowed you because of it, and I assure you it has absolutely nothing to do with your personal sexuality. I would've unfollowed anyone who posted what you did (hint: it was the 'toilet-cleaning' tweet last week).

And now this blog post. My god. Assault against women is "routine" in STEM fields? It's not routine, it's never been routine, it will never be routine. You live in a social media echo chamber that you need to break out of.

You know what the tech community needs more than anything? Thought-leaders who can teach the rest of us important, practical things about the technology we take for granted every day. What we don't need more of: pandering, condescending horseradish. I honestly will not be surprised if I get attacked personally because of this post as a woman-hating or homophobic bigot. This is the level of discourse now, unfortunately. Ergo why I waited until this post had passed its peak to post.

Break out of your dumb echo chamber, it's decreasing your worth as a teacher.

</comment><comment><USER11> I have really really been getting into clojure lately. It's a functional language that doesn't feel hard to grasp. But it can be way harder to make sane comparisons between libraries and stuff with a community so small but so active as clojure's.

My kingdom for a decent comparison between NodeJS+ClojureScript vs vanilla Clojure (w/Compjure maybe?) for high performance web applications!

<comment><USER9> If you mean a performance comparison, I would be surprised if Node (V8) outperformed vanilla Clojure (JVM).

<comment><USER11> Yeah maybe in general but what about a comparison for heavy IO applications? core.async vs node's system?

I really hope Clojure catches on. It's so fun to write in, I'm never going back!

<comment><USER12> I'm not aware of a good reason to prefer ClojureScript+Node.js in general. Maybe if you wanted interop with a specific Node library, but otherwise, Clojure on the JVM will tend to have vastly better performance, and the tooling is better.

For example, until recently ClojureScript's :keywords were just strings under the hood and it required a string compare to test equality. Apparently this is no longer the case due to this commit 2 months ago: [https://github.com/clojure/clojurescript/commit/2cef52840fcd...](https://github.com/clojure/clojurescript/commit/2cef52840fcd9d88f077d374cc81e50c7e645b9f) but it shows you the kind of stuff you might run into. In a recent talk I saw by David Nolen, the lead maintainer of the ClojureScript compiler, he brought up multimethod dispatch as something that can still be as much as 100 times slower than the JVM.

As a tooling example, Clojure gives you helpful errors if you initialize records the wrong way:

        user=> (defrecord Thing [foo bar])
        user.Thing
        user=> (Thing. 1 2)  ; correct usage
        #user.Thing{:foo 1, :bar 2}
        user=> (Thing. 1)    ; wrong number of fields

        CompilerException java.lang.IllegalArgumentException: No matching ctor found for class user.Thing, compiling:(/tmp/form-init7089728177345913731.clj:1:1)
        user=> (Thing 1 2)   ; forgetting the dot

        RuntimeException Expecting var, but Thing is mapped to class user.Thing  clojure.lang.Util.runtimeException (Util.java:219)

That's good! Especially if you're new to the language. You see where you messed up right away.

But ClojureScript just silently gives you nils:

        ClojureScript:cljs.user> (defrecord Thing [foo bar])
        cljs.user/Thing
        ClojureScript:cljs.user> (Thing. 1 2)  ; correct usage
        #cljs.user.Thing{:foo 1, :bar 2}
        ClojureScript:cljs.user> (Thing. 1)    ; wrong number of fields
        #cljs.user.Thing{:foo 1, :bar nil}
        ClojureScript:cljs.user> (Thing 1 2)   ; forgetting the dot
        nil

This should be a bug report against the CLJS compiler (edit: now it is[1]), and it's probably not that hard to fix. I could fix it. You could fix it. (The CLJS compiler is very approachable and needs contributors, by the way.) But, especially as a newbie, this kind of stuff can bite you. JVM Clojure is more polished.

1\. [http://dev.clojure.org/jira/browse/CLJS-639](http://dev.clojure.org/jira/browse/CLJS-639)

<comment><USER13> > JVM Clojure is more polished.

I wouldn't say that. In this case for instance it more or less just shoves java's error message in your face, you have to translate that back into the clojure you typed beforehand.

<comment><USER12> OK, I can see the case for that nitpick. Perhaps neither implementation is particularly "polished" in this regard, and the JVM one just happens to fail faster due to a statically-typed host environment. Polished or not, though, the end result is Clojure being more helpful when you make typos/newbie mistakes.

</comment></comment></comment></comment></comment></comment><comment><USER14> The guide appears to assume one is on Mac OS X or Linux without explicitly stating as such (unless I missed it, in which case my bad). That's not good for a world where most people programming on a desktop are on Windows (Mac user myself).

<comment><USER6> The linked leiningen page includes detailed installation instructions for all platforms, including a windows installer.

<comment><USER15> Nice guide! Is there more coming? I also loved your explorations on network partitions, keep up the good work!

<comment><USER6> Thank you, and yes, there will be more.

</comment></comment></comment></comment><comment><USER16> I've been playing around with clojure and clojurescript on my Ubuntu laptop for a while now, but according to this guide I'm not ready to get started because I don't have "javac" installed.

<comment><USER6> It's not necessary for all development, but you'll want a java compiler for later parts of the guide.

</comment></comment><comment><USER17> Great tutorial, look forward to the next one.

Clojure, and indeed LISP is one of the things I would really like to learn but most of the tutorials have been way to academic in there format. This one so far has been much more focused and clearer on the intent of the language.

Thanks

</comment><comment> sr-ix I was just asking a friend of mine for some suggestions for starting up with Clojure.

I loved your Jepsen series and you communicate on a level that I can relate to. As such I was thrilled to find your guide at the top of HN.

Keep up the awesome work!

</comment><comment><USER18> I love the thorough Guide to Programming in Clojure for Beginners: [http://blackstag.com/blog.posting?id=5](http://blackstag.com/blog.posting?id=5)

</comment><comment><USER19> Maybe you want to try light table. It's a pure gui experience, and is probably easier than setting up lein. Currently free.

<comment><USER20> I think all noobs should still get lein. (Install it in 1 second with your package manager)

That way they can run `lein new <project-name>` to get the app skeleton created. Then open it with Lighttable.

In fact, anyone that wants to check out the Clojure version of Sinatra/Flask should run `lein new compojure <project-name>` and it'll create it from a template. Then run `lein ring server` from the project root to start the dev server.

Someone happened to tell me those incantations my first day with Clojure and I was instantly productive.

<comment><USER19> If a newbie knows what a package manager is and has it set up on their system, then they're probably not the level of noob this article is going for.

</comment></comment></comment><comment><USER21> This first lesson was quite similar to Clojure in fifteen minutes: [http://adambard.com/blog/clojure- in-15-minutes/](http://adambard.com/blog/clojure-in-15-minutes/). I find both pretty good, although this seems more promising. Waiting for more!

</comment><comment><USER22> IMHO, It would be better to seperate two distinct things into two seperate articles. Your view in women in computing and intro to clojure.

</comment><comment><USER23> Pointers to a good follow up?

<comment><USER24> I've been compiling Clojure-resources for learning etc. at [https://github.com/tazjin/clojure-basics](https://github.com/tazjin/clojure- basics) \- maybe you find something that works for you?</comment></comment>


Python Concurrency Decorators - <AUTHOR> https://github.com/alex-sherman/deco <comment><USER2> Another page you might be interested in bookmarking:

[https://wiki.python.org/moin/PythonDecoratorLibrary](https://wiki.python.org/moin/PythonDecoratorLibrary)

A similar decorator to thread function calls for concurrency:

[https://wiki.python.org/moin/PythonDecoratorLibrary#Lazy_Thu...](https://wiki.python.org/moin/PythonDecoratorLibrary#Lazy_Thunkify)

<comment><USER3> Doesn't this second decorator only work with functions doing IO or releasing the GIL in any other way (like time.sleep() that they use in the example)? If all the function is doing is actual computation (i.e. using the CPU), no other code can run in parallel with it because of the GIL.

<comment><USER2> Yes, that's right, it is best used for I/O-bound applications. You could use it for:

* running multiple Database queries

* SSH-ing into multiple devices to run a command

* loading multiple web pages

* calling multiple APIs

</comment></comment></comment><comment><USER4> So, for me, replacing imap with pool.imap is the easy part. The hard part is dealing with things like handling exceptions, catching keyboard interrupts, and so on. Does this module do anything to address these issues?

<comment><USER5> I have a hack for dealing with KeyboardInterrupt's on a ProcessPoolExecutor: [https://github.com/tgbugs/desc/blob/master/util/process_fixe...](https://github.com/tgbugs/desc/blob/master/util/process_fixed.py). I used this in concert with asyncio run_in_executor which helps with some of the exception handling.

<comment><USER6> That's a nice hack when you have only a few elements in the iterable, but Futures are pretty heavyweight, so this is unfortunately a lot slower than multiprocessing.Pool when you have many elements.

The other thing is that this won't work on Windows. Efficient multiprocessing always a pain in Python in my experience.

</comment></comment></comment><comment><USER7> A couple of things offhand:

\- It has Python 2 and 3 support

\- It's a wrapper for the Python built-in "multiprocessing" library

\- It spreads out work over all cores (so the abstraction hides the ability to control the pool)

Seems like a great way to get your feet wet with multiprocessing in Python, but it likely has limited use in production...although certain infrastructures like resource limited containers might be able to accommodate it.

<comment><USER4> Is there no way to specify the number of cores to use?

<comment><USER8> Looks like there is:

[https://github.com/alex- sherman/deco/blob/cee63391bf4c6d66ee...](https://github.com/alex- sherman/deco/blob/cee63391bf4c6d66ee40628fb6ab61e62d3bc236/deco/conc.py#L108-L117)

<comment><USER7> Interesting, so when they claim it automatically scales out to all cores what they mean is it defaults to 3 unless overridden.

<comment><USER6> Should really be multiprocessing.cpu_count() / 2 or something like that.

<comment><USER9> I found out recently that some tasks do better if there are slightly more processes than cores.

</comment></comment></comment></comment></comment></comment><comment><USER10> See paper at [https://drive.google.com/file/d/0B_olmC0u8E3gWTBmN3pydGxHdEE...](https://drive.google.com/file/d/0B_olmC0u8E3gWTBmN3pydGxHdEE/preview)

</comment><comment><USER11> With Python 3.5 there is native support for concurrency by using the keywords await and async.

For simple usage if you are familiar with Go there is this library: [https://github.com/pothos/awaitchannel](https://github.com/pothos/awaitchannel)

<comment><USER12> Asynch and concurrency are very different. Python 3.5 allows first class aysnchronous calls, but concurrency is still "hard".

</comment></comment><comment><USER13> Of note is that the version of deco on PyPI[1] (0.2) is incompatible with Python 3.

There have been few commits to fix compatibility, but it's not there yet.

1\. [https://pypi.python.org/pypi/deco](https://pypi.python.org/pypi/deco)

</comment><comment><USER14> Perhaps a strange choice of the word "synchronized" when coming from Java, this typically implies a critical section. Here it seems to initialize a multiprocessing pool for use in the function labelled concurrent (perhaps)?

<comment><USER15> I think it's like sync in Cilk, meaning that all concurrent jobs must have finished before the part that is annotated synchronised is left. So it's not without precedence.

</comment></comment><comment><USER16> "We have proposed DECO, a simplification of concurrent programming techniques targeted at programmers with little understanding of concurrent programming." (from paper)

gave me the chills

</comment><comment><USER17> Related: [https://github.com/hcarvalhoalves/python- pmap](https://github.com/hcarvalhoalves/python-pmap)

</comment><comment> awinter-py this is such a good idea! the @synchronized decorator to collect the parallelized task at the end of a parent call is very very smart & simple.

<comment><USER18> It also has a potential for slowing down your code if used willy nilly, of course.

Multiprocessing gets pretty useless for anything outside of independent CPU bound tasks with little IPC and simple data types that can be stuck into shared memory.

If you're using multiprocessing pools so often that you think you need a decorator to clean up your code, then wow, I'd like to see what you're up to. ;)

<comment><USER19> > If you're using multiprocessing pools so often that you think you need a > decorator to clean up your code, then wow, I'd like to see what you're up > to. ;)

.. and I think once you do that in Python you should probably use NumPy.

I've been thinking that there should be a way to just program kernels in Modern Fortran because it's the easiest to interact with NumPy data structures (NumPy is nothing but glue code around a collection of very efficient Fortran numeric code). f2py [1] is doing that basically, but I've never had the chance to setup a project like this.

[1] [http://docs.scipy.org/doc/numpy-1.10.1/user/c-info.python- as...](http://docs.scipy.org/doc/numpy-1.10.1/user/c-info.python-as-glue.html)

</comment></comment></comment><comment><USER20> source looks surprising, for instance the decorators parse the decorated function code and build an AST (still have to find out why)

<comment><USER21> My best guess is that this is to circumvent issues with naming encountered by using decorated functions in conjunction with multiprocessing pools. Typically you would run into serialization errors.

<comment><USER20> it turns out that the decorator "rewrite" the fn code. that's at least how the synchronized decorator does its own magic. Once I saw that in the source code (and other few hacks) I was sure I was never going to use this lib :)

</comment></comment></comment><comment><USER22> This reminds me of AppEngine's ndb tasklets.

</comment><comment><USER23> I've been looking for a way to replace functools.partial and pool.map with something that could cause me to make bad architectural decisions. This could be the ticket.

<comment><USER21> Haha, having mucked around with similar mechanisms for dealing with concurrency via decorators I have to agree with you that this is likely to cause hard to debug behavior (especially since direct modification of the AST is going on behind the scenes here). That being said, it's an interesting thought experiment and likely an excellent class project.

</comment></comment><comment><USER24> Let me sum up my feelings towards this: neat!

</comment><comment><USER25> Then I can easily parallelize existing code without touching anything?

</comment><comment><USER26> I love developing in Flask cause of the way decorators written.</comment>


Ask HN: Does Python have anything like Kotlin's "where" statement? - <AUTHOR> <comment><USER2> I suspsect the number of people here who know both Python and Kotlin is close to 0.

What's a "where" statement?

</comment><comment><USER3> No. Python is a dynamically typed language, so it doesn't need generics as a compile-time feature.</comment>


Microsoft contributes a lot of changes to Linux kernel 3.0 - <AUTHOR> http://www.h-online.com/open/news/item/Microsoft-contributes-a-lot-of-changes-to-Linux-kernel-3-0-1280528.html

<comment><USER2> While I would agree (and some would make the point) that Microsoft does this to benefit mostly Microsoft, it's still GPL'ed code that is now part of the greater Linux kernel codebase, so good on them and everyone else.

<comment><USER3> > Microsoft does this to benefit mostly Microsoft

Well, of course. I would wager all the corporate contributions, and a good chunk of the independent contributions are contributing to add features they need.

I agree, though, good on them for contributing, and even better for making a substantial contribution, instead of a token gesture.

The irony is, there is a benefit to Microsoft for working with open source: if dosbox and wine become good enough to support their legacy software, they can end-of-life a large portion of their compatability codebase that they drag along with each version, and keep the compatability effort to a stable, free platform written for that purpose.

<comment><USER4> They don't need dosbox/wine -- "XP mode" in windows 7 is XP running in a virtualized environment.

<comment><USER5> Ah, but how does that replace DOSBox? iirc, Windows XP does not support real mode DOS software.

<comment><USER6> It does. <http://en.wikipedia.org/wiki/Virtual_DOS_machine>

NTVDM is unavailable in 64-bit Windows, but XP Mode uses 32-bit XP, so it can be used to run DOS software. (Though there will be trouble if you try to use it to run DOS games.)

<comment><USER5> NTVDM is useful, but only for the most basic software. For example, many programs do not work on NTVDM because of the limited audio and video support. You mentioned games, and I believe some of them suffer from timing issues (though this may be the games' fault for relying on a specific clock frequency for timing).

I'd say it's just good enough for the most useful 16-bit Microsoft utilities.

<comment><USER6> I've seen the entire suite of DOS Borland C++ developer tools run under NTVDM, and other non-trivial, useful stuff, like Lotus Magellan.

I've also seen some quite trivial programs fail completely in DOSBox due to imperfect compatibility.

</comment></comment></comment></comment></comment></comment></comment><comment><USER7> Looking at the stats, it's interesting the Google are so low (1.4% of changesets) when they do so much work on both Android and Chrome OS. Does their work not go upstream?

It's also interesting that Nokia are at 1.8% of changesets when Elop siad they weren't producing any more MeeGo phones.

Is most work that goes into Linux now just adding drivers for new hardware? Or are there ineresting new kernel features that people are working on?

<comment><USER8> > Does [Google's] work not go upstream?

A lot of it doesn't, actually. Many of the Android patches are pretty intrusive, and wouldn't necessarily be suitable for integration into the mainline kernel -- for instance, the Android permissions model depends on a bunch of these kernel patches.

<comment><USER9> I'm pretty sure that they'd ultimately accept kernel patches for the actual end-to-end functionality that Android needs, but there would be a lot of debate and probably considerable engineering changes to kernel interfaces needed first.

In practice, Android development seems to be more focused on shipping rather than on code quality, accruing technical debt in the process. To be fair to them, it's a project that is really an entire Linux distribution, requires lots of components written from scratch and not used anywhere else, and they're under massive pressure to keep up with the competition.

<comment><USER7> It seems a shame than Android is so different from standard Linux distributions and doesn't really use any of the normal Linux stack. It would be really cool if Android was more "Linux" than just the kernel (like Web OS & MeeGo are).

<comment><USER10> If it was, they wouldn't have the tight integration that makes Android vastly more viable than MeeGo.

<comment><USER11> What does that mean, exactly?

</comment></comment></comment></comment></comment></comment><comment><USER12> This is interesting in the context of Microsoft patent-trolling companies which deploy Linux (TomTom, Android OEMs).

Is it possible these patches introduce more patent mines into the Linux source?

Or is there a legal hook to prevent Microsoft from trolling after they (even when only represented by a single employee) participated in the development? (I wish there was, but I fear the answer will be "no")

</comment><comment><USER13> Original LWN article: <http://lwn.net/SubscriberLink/451243/060f24c5b1202513/>

</comment><comment><USER14> They only thing they are contributing is their hv driver to make Linux run on Mircosoft HyperV. HyperV has to support Linux. And the major hv developer is a former Novell employee.

<comment><USER15> While this is true (at least the part I can verify, no idea about personal things here), I'm genuinely curious why you want to point this out?

The article says the same thing (contributing to the HyperV driver). Why is the job history of this guy of interest?

<comment><USER14> Because it's not Microsoft who is contributing. They just paying Linux Kernel developers to build a driver for their HyperV. So, Microsoft does not contribute to Linux. They make it just run on HyperV because some customers need this "feature".

<comment><USER16> > Because it's not Microsoft who is contributing. They just paying Linux > Kernel developers

So it's Microsoft employees as directed by their managers ... but not Microsoft? What is the distinction.

<comment><USER10> The distinction is "He doesn't like Microsoft, so he must attack and minimize their contributions to feel better."</comment></comment></comment></comment></comment>


New subreddit for open APIs and datasets - <AUTHOR> http://www.reddit.com/r/opendata

<comment><USER2> Also take a look at programmableweb.com

They have a comprehensive list of APIs and the mashups built on top of those APIs</comment>