Update Regarding ACME TLS-SNI and Shared Hosting Infrastructure - <AUTHOR> https://community.letsencrypt.org/t/2018-01-11-update-regarding-acme-tls-sni-and-shared-hosting-infrastructure/50188 <comment><USER2> It looks like Let's Encrypt has come up with the best plan possible for the goal of balancing mitigation of the security risks with compatibility for users.

If their plan works out as they've laid out, and as certain recent commits in the boulder source code would suggest...

It would seem they intend to:

1\. Allow renewal of already-issued certificates to same account holder to revalidate via TLS-SNI-01 for some limited time period.

2\. Whitelist certain shared infrastructure providers who have lots of LE certs in force and who have demonstrated that they are not vulnerable. I'm betting especially for those that manage the whole certificate retrieval and deployment process. It's not clear if this is temporary but longer than #1 or "temporary" but very long term or "temporary" until we come up with another inband process.

3\. Otherwise TLS-SNI-01 is gone.

Meanwhile, they'll work with the ACME WG to see if they can't figure out a better TLS-SNI method which would not be vulnerable. That looks less and less workable absent some special TLS extensions or ALPN and server support for those.

For those who have options, it's worth pointing out that the purely DNS based validation methods are literally closest to the facts that the CA's validation process wishes to prove. Domain Control validated means that you're showing effective control of the domain. Nothing says I control the domain like the ability to add and remove data from the authoritative DNS servers for the domain label (and children thereof) in question.

<comment><USER3> > Nothing says I control the domain like the ability to add and remove data > from the authoritative DNS servers for the domain label (and children > thereof) in question.

Unfortunately this makes life difficult for us.

We run a whitelabelled platform with tens of thousands of users - it's hard enough to get many people to understand setting a CNAME record (vs just setting an A record). Requiring them to update a TXT record _once_ would be a big enough challenge, but doing it every 30-90 days is never going to happen. The smaller customers would probably be happy with us hosting their DNS, but we're not going to do that - the larger ones wouldn't.

TLS-SNI being gone and DNS being unworkable means we're left with HTTP only.

<comment><USER2> But if you're a web post with 10k+ users, what's the problem with the HTTP-01 challenge?

You just allow .well-known/* to be passed on to reflect the challenge responses you've generated for the client, while 301 redirecting everything else to their [https://](https://) site.

I'm confused how that would be harder for a web host at that scale?

EDIT: I get people trying to run a server off their cable modem / rtr public IP, and 80 might be taken by something other than the target the port forward for 443 is going to -- and that's a problem for those use cases -- but that kind of concern wouldn't exist in a significant hosting infrastructure.

<comment><USER3> > what's the problem with the HTTP-01 challenge?

Nothing, yet.

But who's to say that another similar bug won't be found in common shared- hosting platforms that forces LE to turn that challenge off too?

<comment><USER2> True.

Because almost all of the CAs utilize a web control mechanism, with many of them probably having processes not as rigorous as HTTP-01, it is likely that there would be significant backlash and a lengthier migration away from the method for that case.

That said, anyone who can would be well advised to figure out how their DNS based mechanism would work if it were ever needed.

As I and others have pointed out, there are clever and fully supported hacks for validating dns-01 without dynamic control of the full domain zone. (CNAME to another zone for the _acme-challenge labels, NS delegation to refer each _acme-challenge label as an independent zone at a different NS, etc.)

</comment></comment></comment></comment></comment><comment><USER4> The tls-sni challenges rest on the assumption that a hosting provider will somehow ensure that a self-signed cert uploaded by the user contains "truthful" information, even though the second half of the cert is blatantly fake and is being abused to carry data. This is a bold assumption to make, considering the entire point of CAs is to say that the information being presented in a cert has been vetted, so why presume that anyone will vet any claims in a self-signed cert?

That aside, Let's Encrypt had an exemplary response to this issue throughout, and has made the right call here. A best-effort whitelist will enable a smoother transition for those on some known-good hosts, while mitigating this vulnerability and keeping their cert ecosystem uncompromised.

The work will now begin to add support to the other validation methods in ACME software that's lacking them, and to engage with the other custodians of the ACME protocol to rectify this particular flaw in design.

While the http-01 challenge is the recommended migration path, and likely the easiest to automate with greenfield software, the dns-01 challenge is the one with the fewest amount of intermediate assumptions -- such as the ones made when designing tls-sni-*, which in this case turned out to be faulty -- and represents the one most likely to be futureproof. After all, what better way to prove you own a domain itself than being able to add arbitrary records to it that all nameservers then echo back?

<comment><USER2> I completely agree on the dns-01 challenge. Those who are migrating off of TLS-SNI-01 and have a capability to standardize on dns-01 will be better off in the long run.

As you point out, domain control validation is best performed by having the application demonstrate control of the domain.

<comment><USER5> The problem with dns-01 is that it much of the time, it requires granting far too much privilege to the system that requests the certificate.

This is because the great majority of DNS hosts do not provide sufficiently granular permissions to only allow changes to _acme-challenge RRs.

e.g. Cloudflare, as far as I can tell, only gives you one API key which grants all access to all zones.

e.g. Most domain registrars who offer DNS hosting who provide an API grant access to all sorts of management functions, not just DNS zone changes.

e.g. Route53 IAM doesn't let you restrict to a single RR, you expose modifications to the entire zone.

I am really not comfortable giving my web application these kinds of powers.

TLS-SNI was useful because it was relatively protocol agnostic, so some of that flexibility is now gone.

<comment><USER6> > The problem with dns-01 is that it much of the time, it requires granting > far too much privilege to the system that requests the certificate. This is > because the great majority of DNS hosts do not provide sufficiently granular > permissions to only allow changes to _acme-challenge RRs.

There's a cool solution to this that I learned from someone else on the Let's Encrypt forums (where I often help do support). The Let's Encrypt DNS-01 validator will follow CNAMEs. Therefore, you can make _acme-challenge be a CNAME to an arbitrary text record which can be in another zone (including a zone dedicated for this purpose). For example, you could say

_acme-challenge.example.com. IN CNAME foo.acmevalidation.example.net.

Now an application can just have API keys to update RRs under acmevalidation.example.net, which does not need to be used for any other purpose (or even necessarily hosted on the same infrastructure as example.com's own DNS). The CNAME can be created manually at the outset and does not need to be updated for renewals.

This has been possible for a long time, but if it becomes more widely known and more widely supported by client applications and DNS providers, it should make use of DNS-01 authentication much more practical, and safer, for a pretty wide range of people.

<comment><USER7> Another similar option would presumably be to delegate _acme- challenge.example.com to different nameservers with an NS record, then give your application the required privileges to control solely that nameserver.

<comment><USER2> Yes. Or even to the same name server, breaking out each whole label starting with _acme-challenge as its own independent zone, with its own access policies.

<comment><USER8> Yes, but there's no need to have separate zones; you can grant update access to subdomains and have the CNAMES point into one zone with a subdomain dedicated to each separate actor which needs access.

Like so: Assume that Actor 1 has example.com and example.net. You then add this to the example.com and example.net zones, respectively:

      _acme_challenge.example.com.  CNAME  example.com._.actor1._.your-special-domain.com.

      _acme_challenge.example.net.  CNAME  example.net._.actor1._.your-special-domain.com.

Then you give update access to Actor 1, but not to the whole "your-special- domain.com" zone, but to the "_.actor1._.your-special-domain.com" subdomain. The ACME system would then be configured to send updates to the correct subdomains of that subdomain. Or "your-special-domain.com" could even be a subdomain itself of another domain; it doesn't matter.

</comment></comment></comment></comment></comment></comment></comment><comment><USER9> From my point of view the big advantage of TLS-SNI is that it uses the same protocol and port as 90%+ of certificate users want to use with the issued certificate: HTTPS.

That is especially useful for webserver plugins. Also this is much better when there are security policies that (for maybe misguided but well-intentioned reasons) completely block or redirect all HTTP traffic.

What would be insecure about a https-01 challenge, that esentially works identical to the http-01 challenge but allows any certificate?

<comment><USER10> > What would be insecure about a https-01 challenge, that esentially works > identical to the http-01 challenge but allows any certificate?

There's a specific reason http-01 is HTTP-only, and it's actually quite similar to the tls-sni-01 situation. In many of the major web servers, including apache and nginx, the web server will use the first HTTPS vhost in its configuration for any unmatched domains, unless you explicitly specify a default vhost. In practice that means an attacker on the same hosting environment used by the victim could get themselves in a position where they control this default vhost and obtain a certificate for their domain. The vhost order is often based on the alphabetic order of the domain, so that's fairly easy to pull off. http-01's predecessor did allow HTTPS, but this attack came up during the IETF ACME standardization process and, IIRC, was fixed before Let's Encrypt entered public beta[1].

http-01 does permit the CA server to follow redirects to HTTPS, including to ones with self-signed, expired or otherwise invalid certificates, so common setups with HSTS and redirects to HTTPS are fine, you'll only be in trouble if you can't use HTTP on port 80 at all.

[1]: [https://mailarchive.ietf.org/arch/msg/acme/B9vhPSMm9tcNoPrTE...](https://mailarchive.ietf.org/arch/msg/acme/B9vhPSMm9tcNoPrTE_LNhnt0d8U)

<comment><USER9> But that behavior is true and exploitable for HTTP as well, isn't it? It is a risk if there is no specific vhost config for the validated domain, which means a customer pointed the DNS to the shared host without also configuring that host to serve content for his domain from his account.

I realize in current real-world setups you would normally start with a HTTP- only config and only later or maybe never configure HTTPS for that domain, or configure both protocols simultaneously. And almost never the opposite where you configure HTTPS only and someone else would be able to grab your HTTP traffic. So that's still a good argument to do HTTP only, thank you for explaining it.

I did not know http-01 would follow redirect to HTTPS, that is also really good to know and should be a good way for some setups.

</comment></comment></comment><comment><USER11> Happy to see this. I was very critical of their plan to re enable Tls-sni and I'm happy to see they reconsidered. They made the right call here.

</comment><comment><USER12> For the record, I am pretty sure Caddy will be unaffected by this. Any programs using xenolf/lego as their ACME client should be fine as well, as long as one other validation method is still available. (lego also uniquely supports a wide variety of DNS providers for automated negotiation of the DNS challenge. Caddy supports them too, as long as they are plugged in and configured.)

I've been asked if we'll turn off TLS-SNI in Caddy and the answer is no; as their announcement says, some accounts will still be able to use TLS-SNI for a limited timeframe until it is turned off completely. Caddy won't try the TLS- SNI challenge as long as the ACME server doesn't advertise it in an exchange.

<comment><USER2> One would think that most of the Caddy users who previously used TLS-SNI-01 could also avail themselves of HTTP-01 validation.

<comment><USER12> Yeah, I imagine so. Many sites still have port 80 open to redirect to 443.

</comment></comment></comment><comment><USER13> RIP

I have a few services which were using Go's acme/autocert package. I now need to update them to the HTTP challenge.

<comment><USER12> xenolf/lego arguably has the widest support in the sense of ACME verification methods, but autocert might get other methods too: [https://github.com/golang/go/issues/21890](https://github.com/golang/go/issues/21890)

</comment></comment><comment><USER14> I don't understand why TLS-SNI can't work fine if you just have the response certificate be entirely distinct from the server name.

EG: LE sends a challenge of a.b.c.acme.invalid

You must reply with a certificate of d.e.f.acme.invalid

Doesn't that entirely mitigate the shared hosting issue since any shared hosting setup will require SNI to match the certificate name that you reply with?

<comment><USER2> No, that's the problem. A lot of shared hosts will allow any customer to board a new website — as long as it's not already taken on that hosting provider — then allow you to upload any TLS cert for that.

So attacker requests to validate for a name that you have pointed via DNS to that hosting infrastructure.

The names that you need to respond on and have certs for are then calculated by attacker. Attacker, who is also a customer of same hosting service creates the necessary "sites" and uploads the matching challenge response certs, and successfully receives a cert for your domain.

<comment><USER14> None of what you're saying is an issue in my outline.

If I'm able to upload a certificate for a.b.c.acme.invalid, the validation TLS-SNI request for a.b.c.acme.invalid will reply with a certificate for a.b.c.acme.invalid and thus fail.

If I'm able to upload a certificate for d.e.f.acme.invalid, the validation TLS-SNI request for a.b.c.acme.invalid will not match my uploaded certificate and the challenge will thus fail.

I may well be misunderstanding the situation, but, I just don't see how.

<comment><USER2> It is still an issue, actually.

You misunderstand how the TLS balancer chooses which certificate to present.

When the TLS connection comes in and presents a SNI name of "a.b.c.acme.invalid", the balancer checks its configuration to see if the host has a "website" called "a.b.c.acme.invalid". It discovers that it does. It looks at what certificate in the database was uploaded for that website configuration.

It doesn't actually check the certificate details at all....

It presents the certificate that was uploaded by the "owner" of the "website" a.b.c.acme.invalid.

And if that name needs to present a certificate that says "d.e.f.acme.invalid" then that is the certificate that the attacker will have uploaded for his "a.b.c.acme.invalid" site.

There are numerous web hosts who would permit this and it would work just like that.

The mechanism you're describing is similar to the changes in TLS-SNI-02. It has already been determined that TLS-SNI-02 is deficient as it is vulnerable to the attack I've parroted here.

The trouble is that the people who wrote both TLS-SNI-01 and TLS-SNI-02 apparently had little knowledge of the vast breadth of behaviors exhibited by a plethora of shared web hosts. The assumptions they made, upon which all the current TLS-SNI-0x protocols rely to provide security, simply are not upheld and honored by the real world marketplace of web hosts.

<comment><USER14> Ok, that makes sense, thanks for explaining it a bit more.

That seems like an absurdly broken implementation, I get why LetsEncrypt feels the need to disable it but I really hope they come up with some alternate solution.

I really like the tls-sni authentication method as it keeps authentication entirely inband to the final SSL goal. With HTTP you need to listen on/control 80+443, with DNS you need to control DNS. With tls-sni you need only control port 443. I'm a huge fan of x/crypto/acme/autocert.

Custom ALPN-signaled protocol should be doable and should solve all of this, I hope they do it.

<comment><USER2> It is a rather limited protocol. Really, the implementation isn't so bad... In a perfect world.

It's naive.

It imagines there was a whole different set of operating circumstances at shared web hosts than the reality exhibits.

I actually had not read the protocol specification for that challenge as I utilize http-01 and dns-01 on all my various systems. Then, when the early report without details was released, I read the protocol and realized almost immediately that there were several circumstances in the field which could yield actual vulnerability.

They also made the mistake of failing to align to a promise which the other mechanisms do make: the other mechanisms tie the validation directly to the target domain label being authorized or a known child thereof. The TLS-SNI-01 and TLS-SNI-02 don't do that. And they knew that, because they wanted to be able to perform a TLS-SNI validation without having to change server software. I believe that was a bad decision.

The proposed TLS-SNI-03 ALPN "acme" extension that Mr. Rudenberg has put forth will not be resilient to these attacks, ultimately. I think they should do a real ALPN protocol and do the validation through that. But let's assume time to market for that would exceed a year. In the mean time, people reliant on TLS-SNI-01 are likely going to need to do something else.

In short, a mechanism which would achieve much the goal of getting validation off of a single TLS port running the right software can happen, but I believe it should borrow pretty much nothing from the current TLS-SNI-0x proposals.

It should be a whole new real ALPN protocol.

<comment><USER14> > I think they should do a real ALPN protocol and do the validation through > that.

Agreed.

> But let's assume time to market for that would exceed a year.

I'm sure it would take a year or more for good packages for most languages to exist, but, it doesn't seem so complex that it should take a year for it to exist and for it to be usable if you're sufficiently motivated (EG: you're willing to write your own software).

> In the mean time, people reliant on TLS-SNI-01 are likely going to need to > do something else.

I just moved to using a commercial wildcard certificate. I didn't particularly want to, but, for this and a few other reasons, LetsEncrypt became non-viable for me.</comment></comment></comment></comment></comment></comment></comment>


We read all the research on which charities to give to, so you don't have to - <AUTHOR> https://80000hours.org/2016/12/the-effective-altruism-guide-to-donating-this-giving-season/ <comment><USER2> I picked one to research (partially because I would have expected MSF / Doctors Without Borders to rate in the "Global health and development" category).

Charitynavigator has this to say about Against Malaria Foundation: "This organization is not eligible to be rated by Charity Navigator because it does not meet our criterion of having nontrivial fundraising expenses."

Oddly, they don't even include Charity Navigator among their six chosen sources.

<comment><AUTHOR> I'm the author - Charity Navigator isn't very useful because it doesn't tell you whether the program delivered by the charity actually helps people, which is by far the most important and most frequently lacking factor. The only thing CN is useful for is identifying outright frauds, and even then it's not amazing.

As you can see GiveWell has investigated AMF including its finances in vastly more detail over 4 years than Charity Navigator has ever investigated anyone: [http://www.givewell.org/charities/against-malaria- foundation](http://www.givewell.org/charities/against-malaria-foundation)

<comment><USER2> Where does Givewell break out fundraising costs, though? The specific breakouts of spending seem more detailed on CN.

If all of that 92% is actually going directly to programs, that's excellent.

<comment><AUTHOR> I actually think it's a good thing for charities to spend more on fundraising than they do - it's a harmful metric to judge them by. Here's a discussion of that: [https://www.ted.com/talks/dan_pallotta_the_way_we_think_abou...](https://www.ted.com/talks/dan_pallotta_the_way_we_think_about_charity_is_dead_wrong)

However, IIRC all the fundraising and admin costs are covered by separate donors so that any additional donations go to nets. AMF doesn't have much of a fundraising operation as it gets its funding through GiveWell and Good Ventures primarily.

<comment><USER2>
      it's a good thing for charities to spend more on fundraising than they do

Well, sure, if a little money spent fundraising yields far more in donations and/or broadens your audience to your cause.

What raises concern for me is when the _percentage_ of receipts spent on fundraising is disproportionately high and/or spent on overpaid insider salaries.</comment></comment></comment></comment></comment>


Imprisoned by the Haskell Toolchain - <AUTHOR> http://jackkelly.name/blog/archives/2013/01/06/imprisoned_by_the_haskell_toolchain/index.html

<comment><USER2> Given how much I've had to fight with Automake and Libtool to get really simple things done, they're hardly the things you want to hold up as shining beacons.

1\. Do you want to compile certain source files with different build flags? Hah, no! Automake only supports it through obscene hacks, and those break if you're using Libtool.

2\. Do you want to make a plugin? Best way is to ditch Libtool completely, make an _executable_ target in Automake, and add the linker flags yourself. It makes you feel like you're banging two rocks together and it's not portable but at least it gets the job done.

3\. Do you have any linker flags? Hah, no! Libtool will mess with them and they won't work.

The other bit is that Libtool is basically all magic, and Automake is basically all macros. The amount of magic that Libtool does to _fool_ you into thinking you're not writing dynamically linked code is enough to make you puke and makes a mess when it breaks, and Automake's macro system is terrible.

Just imagine, if you will, that you want to compile one file in your library with the flags -msse3, to produce a dynamic library that has to run on systems both with and without SSE3. You can use cpuid to call functions in that file or not at runtime.

All of my searching has lead me to the conclusion that this is impossible if you want to use Automake and Libtool, and easy if you ditch both of them.

<comment><USER3> Basically, these days I recommend cmake as the sane build system that runs everywhere. I don't know about PCs running MacOS, but it works just fine under Linux or Windows and you can do whatever magic you want; it makes simple things easy and complex ones possible.

<comment><USER2> I wouldn't recommend CMake without qualifications.

It is vastly inferior from the perspective of the end user. Any autotools package can be handled with "./configure && make && sudo make install", and you can change it up by "./configure --without-gtk --enable-network --prefix=/opt/crazy CFLAGS='-O0'" and then make a package with "make install DESTDIR=/tmp/package". Try doing that in CMake, you'll see what I mean.

The syntax is also really terrible, in particular, If/Else. The documentation is not so good, in particular, it's available online as one big block of text and they want to sell you a book.

Finally, CMake doesn't solve the one problem I was complaining the most about, which was the ability to set per-file compilation flags. This is not an optional feature in my eyes -- it's necessary for avoiding cross-contamination of -D_GNU_SOURCE turds picked up by pkg-config, and it's necessary for writing libraries that use processor features that might not be available at runtime, like SSE3.

I think CMake, like Autotools, has a niche in which it does best. "Simple things easy and complex things possible" is a nice motto, but the truth is really boring -- CMake and Autotools make _different_ things easy and _different_ things possible. CMake's niche is medium-large projects with medium amounts of complexity. Projects that are complex, like Firefox or FFMpeg, tend use Autoconf with custom build systems.

</comment></comment></comment><comment><USER4> The Haskell toolchain has its share of weaknesses (e.g. the impurity of package builds has been painful recently), but I also feel the need to point out that GHC learned lesson 1 a long time ago:

[http://www.haskell.org/ghc/docs/latest/html/users_guide/sepa...](http://www.haskell.org/ghc/docs/latest/html/users_guide/separate- compilation.html#makefile-dependencies)

Edit: I should also add that, as an expected corollary, if you use ghc -M to generate your Makefile dependencies parallel make works fine. I used ghc that way for years. I think there was a corner-case if you interrupted a parallel build, but it was easy to deal with.

</comment><comment><USER5> Yeah, this happened to me when I was integrating Ur/Web and Haskell; Ur/Web generated C and wanted to handle linking, but to link against Haskell libraries I needed GHC to do everything. There's a happy ending to the story, though: we patched Ur/Web to use ghc instead of gcc to do compilation, and everything worked out great. :-)

</comment><comment><USER6> The reason people do this is the C toolchain is terrible, especially on linux. Want to depend on a specific version of a library? Whoops, no, you can't do that. Want to extend make? Well, you either do it in make or in shell, neither of which are nice languages. Want to compile and link your code once? Good luck fighting libtool. Want a package with dependencies? You'll have to choose whether to work on debian or on not-debian. And actually the debian maintainers are going to move all your files around anyway, because the FHS committee certainly knew better than you where your program's files should go.

It's bad enough I start to wish everyone would just use the JVM, where you have maven. Truly reproducible builds, depend on whatever range of library versions you work with (and it's no problem if two programs want to use different versions), a structured and testable plugin system for extending the build system, and you can use it to build any language (there are some benighted fools who write their own tools like SBT, but they will at least stay compatible so can usually be safely ignored).

</comment><comment><USER7> > The ultimate problem is that people insist on rolling their own sucky > versions of build systems and package managers. (Though cabal and ghc --make > suck less than most, I'll admit).

Cabal is probably the #1 thing keeping me from writing more Haskell code. I've had so many issues with conflicting versions of various libraries being required, and incredibly cryptic error messages upon failure.

Which is sad, because Haskell otherwise seems rather attractive.

It's also ironic, because I would have imagined that a package manager for a purely functional programming language would be a bit more robust[1].

<http://nixos.org/>

<comment><USER8> Please give concrete examples of the problems you've had. Likewise, when you have concrete problems, have you asked for help on #haskell irc or the Haskell-Cafe mailing list? The community members on both those channels are super helpful and can probably help you quickly resolve / debug your problems.

People: hand wavy complaints that do not give concrete examples are hard to fix. Please communicate concrete instance of your problems so that either a) someone can help you solve them now or b) there is a concrete example of a problem so that folks can fix it.

That said, any serious dev work really should use the cabal-dev tool, it solves having those build problems that new ghc users hit.

<comment><USER9> I'm not a haskell user, but I did recently try to install a haskell project on my Debian Squeeze host:

      $ sudo apt-get install ghc6 cabal-install
      $ sudo cabal update
      $ sudo cabal install hakyll

That failed with an error of the form "installing XX version YY requires FOO version BAR". That gave me zero help in completing the installation, and so I gave up.

FWIW: <https://github.com/skx/static-site-generators>

<comment><USER10> Don't sudo cabal install whatever. Actually, avoid cabal install without sudo too, unless you're working with software using dynamic recompilation like xmonad. Use cabal-dev instead, this will save you a world of pain.

<comment><USER9> I'm confused by your comments relating to sudo ..?

That said it seems that cabal-dev is not packaged for Debian. Come the wheezy release of Debian the hakyll project I wished to try out will be available as a .deb, so I'll try it again then.

<comment><USER10> What I mean is, "cabal install" is usually a bad idea, with or without sudo.

However, you _can_ do "cabal install cabal-dev" and rely on cabal-dev for the rest. It means you don't have a global package cache, but in this case it's really for the best. Don't forget to add .cabal/bin to your $PATH if you want access to cabal-dev.

<comment><USER9> Thanks; I'll give that a try shortly.</comment></comment></comment></comment></comment></comment></comment>


Computational Types in C# and F# - <AUTHOR> http://www.codeproject.com/Articles/432071/Computational-Types-in-Csharp-and-Fsharp

<comment><USER2> I'm very glad to see articles like this: accessibly written on a topic (types) that in the past may have been considered largely academic, but are now entering mainstream engineering mindshare.

I've been thinking recently about why functional languages and features have been gaining traction in the last half decade. Concurrency & parallelism have often been given as rationales, but I suspect the real reason is the need for programs (and libraries) to behave as intended and the desire to express complicated processes more simply. And the driver for that may be that a 'commodity programmer' mindset for businesses is faltering as the rate of change and complexity of technology increases.

In my hiring experience, readily available programmers are well-versed in the technology of several years ago. This makes sense because they've spent their time maintaining and extending systems designed and built years ago. But as requirements increase and become more exotic (due to competitive business pressure), such systems get used beyond their original design, and become more difficult to work with. I believe a 'testing culture' developed to mitigate this risk (along with the rise of dynamic language use to address the need for development speed). The hope was that the cost of testing (which can be pretty heavy for a business) would outweigh the cost of maintenance. But the overhead incurred may go to trivialities (ie, test that are easy to write) or struggling to implement more complex (and probably more valuable) tests which themselves are prone to trouble. Wouldn't it be nice if the parts of the program did what was intended and that testing be used more selectively to ensure the integrity of the system? I think correctness is one of the things functional programming languages encourage.

Types are an important part of many (most?) functional languages and are arguably an important part of the puzzle of building correct program components. I think we'll see a lot more articles musing on what they mean for engineering.

</comment><comment><USER3> I voted it up because a) I'm interested in type theory and I like the idea of something that tries to explain it using C# rather than Haskell

b) I wish HN had more of these sorts of articles as opposed to the usual startup/productivity/lifestyle crap

</comment><comment><USER4> Type systems mean different things in different languages. This is trying to apply one language's type philosophy to another language.

In Haskell, a type represents the results of performing a computation. The "results" include the "output" but are not limited to it: they also include things like state changes, possible exceptions, and I/O. That's why Haskell is so big on Monads, because that's the best way to embed these results into a return value.

In a systems language like C or Rust, a type represents the size and meaning of an area of memory: is it an int, a float, a pointer to a float that stays constant, or a pointer to a float that someone else can change?

In languages like C# & Java, a type represents something like the allowable operations on a value, usually represented as the list of methods on a class.

What this article is basically doing is taking a type system of the third category (C#, allowable operations), and embedding into it a type system of the first category (result of computation). While there are advantages to Haskell's approach, I'm not convinced the metaphor shear is worth the effort here. Your types end up expressing things that no other part of the language cares about or can make use of.

<comment><USER5> I'm writing a parser and I noticed that my code turned out quite a bit simpler when I decided to rename a class to "Tokenized" rather than "Tokenizer".

In the case of C#, Java, et al, I think limiting the type system to "expressing allowable operations" is due to habit and custom rather than something intrinsic to language.

In my mind, the purpose of a computation is to create new/more structure so that, on the surface, your program ends up being a series of simple queries rather than a bunch of messy computations using complex algorithms. Classical OOP in which the constructor does the computation and the methods do the querying on the new encapsulated structure seems to be a good fit for that. This is subtly different than treating methods as allowable operations because we're not concerned with transforming the structure, just asking easy questions about it. So in this way, OOP à la C# is very similar to FP à la Haskell.

</comment></comment><comment><USER6> The F# code isn't as slick as it should be. This is much better:

      type FullName = FullName of string

This is a sum type (discriminated union) with a single case. If you want to have a simple accessor just add:

      with member x.Value = match x with FullName x -> x

I'm not sure why you'd create all those records; it seems very messy.

Edit: Also, phantom types may be of interest. Here's an example in F#: [http://stackoverflow.com/questions/3583679/implementing- phan...](http://stackoverflow.com/questions/3583679/implementing-phantom- types-in-f)

</comment><comment><USER7> Okay, I'll bite. Why is this voted up so much?

<comment><USER8> Because it's related to monads and this is HN. ☺

</comment></comment><comment><USER9> Am I a bad person? I found this incredibly tedious and, hell, I enjoy Haskell.

But from reading it, it seems like we're trying to graft a Haskell-like type system onto a couple of languages with little support for it in the first place. I think the impulse is noble but there's a truckload of boilerplate which introduces another layer of complexity. It seems brittle to me.

Maybe invest the time you'd otherwise spend maintaining this kind of scaffolding into more/better tests?

</comment><comment><USER10> Using reflection to "find" the computation from some input types to output types seems a bit naive in the face of real world problems. It seems likely to me that most types can be combined in a myriad of ways that can't be found automatically.

Also this article seemed like a long winded way of saying 'make up types for your own data'. Don't just pass around void*! Well thanks for the tip.</comment>


Swift-Keylogger – Keylogger for MacOS written in Swift using HID - <AUTHOR> https://github.com/SkrewEverything/Swift-Keylogger <comment><USER2> It doesn't log passwords using EnableSecureEventInput. There are probably other use cases, but Apple seems to have implemented things rather well here.

<comment><USER3> It would be nice if macOS had the same permissions models as iOS, and then some. A permission before apps can access the camera, or access what keys are held down when the app isn't in the foreground - that would block this case.

<comment><USER4> This would effectively kill innovation. There is a reason you can't do half the things you do on a laptop on a phone unless you root said phone.

<comment><USER5> I'm not sure I buy that requiring user opt-in to camera access is why the Mac app ecosystem is is much larger than that of iOS. Can you elaborate on what apps/innovations would become impossible because of a mandatory opt-in? I cannot think of any...

<comment><USER4> Everything that is either very low level or is used for deep introspection of other parts of the system.

I'm not against sandboxing, but if there should be a way to say i know what i'm installing, go with it. Otherwise you will say good bie to new ways of debugging, alternative drivers, unusual way of routing network packets, innovative UI interactions that are not part of the standards widgets, or anything you haven't think of yet.

The computing experience you have today is the result of all the stuff we fiddle with for the last 30 years because it was allowed to. It would be foolish thz big players invented most of it.

</comment></comment></comment></comment></comment><comment><USER6> A keylogger in C# for Windows doesn't require any permissions either and I actually used that to implement a global keyboard-shortcut listener.

<comment><AUTHOR> The security in macOS is tougher than in windows

</comment></comment><comment><USER7> ".. Heck, even the $300 chromebook we recently got has 16GB of RAM.. " I don't think sth like that exists.. which one is it?

<comment><USER8> I mean, you can get the HP Chromebook 13 with 16GB of RAM.. but not for $300.

<comment><USER9> Appears to be 500 dollars new on best buy website, so what would make you think that 300 dollars is not possible?

<comment><USER10> 16gb of ram is around 140 dollars.

</comment></comment></comment></comment><comment><USER11> Readme:

      License
      MIT
      Free Software, Hell Yeah!

Code (Keylogger.swift, lines 5 & 6):

      //  Created by Skrew Everything on 14/01/17.
      //  Copyright © 2017 Skrew Everything. All rights reserved.

Umm.

<comment><USER12> Please articulate your concerns with this. Is it because it's copyrighted? I think most open source software is under copyright; but the license (MIT in this case) grants end-users certain rights that can be revoked if that license is broken.

<comment><USER11> Hey. Sorry, it appears that I am totally wrong. I just assumed that those statements were totally conflicting, but ten seconds on Google tells me that's not so.

At least I learned something. My apologies.

<comment><USER13> Yeah usually open source software grants some permissions but retains copyright ownership. This somewhat disallows abuse of Open Source projects, and is probably part of what makes something like the GPL enforceable in court. IANAL</comment></comment></comment></comment>


Prisma 2.0 Beta: Type-safe Database Access - <AUTHOR> https://www.prisma.io/blog/prisma-2-beta-b7bcl0gd8d8e <comment><USER2> I was really excited when Prisma1 came out. It would be understatement to mention that Prisma1 was way overpromised and nothing ever materialised.

With Prisma2, honestly disappointed as it is too little to show for. This is an ORM like library that supports only couple of databases with database migrations still in experimental state with broken links for workarounds[1]

Also Prisma2 has half of the features at 'No / Not yet' supported state - [https://www.prisma.io/docs/reference/database- connectors/dat...](https://www.prisma.io/docs/reference/database- connectors/database-features)

Well makes me wonder what's wrong with TypeORM which supports 8 different databases with full feature support and migrations that work!

[1] [https://www.prisma.io/docs/reference/tools-and- interfaces/pr...](https://www.prisma.io/docs/reference/tools-and- interfaces/prisma-migrate)

      Data Validation

      Cascading delete

      Cascading update

      Renaming existing table

      Renaming existing column

<comment><USER3> After working with TypeORM in a quite few projects I can tell that there're a lot of things that are wrong with it. And TypeORM absolutely doesn't provide "full feature support" for all 8 databases. Even some basic things are missing, like joins on delete sql queries in query builder. Simple 'set' mysql datatype support was missing and I had to add it myself. When it comes to mapping and data modeling, things are OK most of the time but it breaks when it comes to somewhat non-basic stuff like STI. Don't get me started on bugs. Any reasonable alternatives and orm developments are welcome and Prisma2 doesn't take away anything, it's a free software.

<comment><USER4> TypeORM seems wonderful for basic stuff, but also in dire need of maintainers/contributors, at least based on its GitHub issues and docs [0] to get that last 20% (that takes just as much time as the first 80%).

[https://github.com/typeorm/typeorm/blob/master/docs/query- ru...](https://github.com/typeorm/typeorm/blob/master/docs/query-runner.md)

<comment><USER3> It's actually really good but I don't get the feel of wonder after all those years together anymore :) Huge db and feature scope definitely keep it away from any particular completeness despite size and age of the project. Hope to see something more focused @next.

</comment></comment></comment></comment><comment><USER5> Was really excited about this until I got to "smart node module". Isn't changing the contents of a package in node_modules going to break any kind of caching, de-duplicating etc? In my current project we install node_module` ahead of time and bake it into a docker image, it is quite common.

<comment><USER6> This is such. A. Stupid. Decision. Indeed.

For example, we use yarn pnp in our codebase so I have absolutely no hope that it will ever work with Prisma 2.

"Don't try to be smart" is a very useful mantra for programmers, but Prisma seems to ignore this.

But hey I don't want to use it anyway because what I want is a graphql endpoint not an ORM. We used Prisma 1 and now moved on to graphile.

<comment><USER7> Hey there, thanks a lot for the feedback! As I mentioned in other threads, you can configure the output location for the generated Prisma Client library [1], node_modules is just the _default_. The reason why we made it the default is because it comes closest to what Node.js developers are used to and therefore fits their workflow and mental model nicely.

Also please read this Twitter thread between the lead Yarn maintainer and our CEO [2]. The gist is that we're very open to other approaches but this was the best we've come up with so far after 9 months of experimentation and lots of feedback from the community. This doesn't get easier by the variety of package managers out there and the custom workflows they sometimes employ (e.g. wrt pruning and caching). To put it in the words of our CEO: _we 'd be more than happy to embrace whatever package manager mechanism would enable this use case "more cleanly"._

[1] [https://www.prisma.io/docs/reference/tools-and- interfaces/pr...](https://www.prisma.io/docs/reference/tools-and- interfaces/prisma-client/generating-prisma-client#specifying-the-target- location-for-prisma-client) [2] [https://twitter.com/FredKSchott/status/1245053210852618246](https://twitter.com/FredKSchott/status/1245053210852618246)

</comment></comment></comment><comment><USER8> It's alright isn't it to get something done fast, until this huge amount of code that you will never understand bites you in the ass.

I'm secretly rewriting an API written in Prisma 1 into something lower level that actually allows me to write database queries, optimise what is going on, look into the _simple_ underlying abstractions if things go wrong and essentially produce something I can reason about without just hoping nothing goes wrong under the hood.

Apollo codegen is what you want if you'd like your Typescript frontend to be consuming the API in a typesafe way.

<comment><USER6> You might want to have a look at Postgraphile. It is nice

</comment></comment><comment><USER9> I don't know why this is not getting more up votes it looks pretty cool.

At first it may seem like yet another attempt to make database access easy while really making it more complex and harder to maintain.

I haven't tried this yet, but after reading a couple pages it looks more interesting than that. For example the fact that it relies on typescript knowledge which is already widespread, and the fact that it doesn't require any server side technology to be installed is a huge advantage.

I'm not sure how it feels in practice, if anyone has experience with it please chime in.

<comment><USER10> One headline is:

 _Focus on your data – not on complex SQL queries_

Looks like just another SQL DSL trying to make you not learn SQL. TS's structural typing and plain SQL can get you far into a simpler/robust system IMO.

Also, the "introspection" part of Prisma seems very crippled, Postgres has so many useful features for writing application code that it seems wasteful to just treat it as dumb data store.

<comment> david-cako I find the process of writing database access functions annoying, and for the most part, arbitrary and repetitive. ORM functionality that bakes types/accessors, migrations, graphQL, and even infrastructure into your codebase is where it's at. The fact that you are writing your models once and automatically exposing them as types in any project's language is a huge value. I don't need the same language everywhere, but I want types that plug together without hassle.

Next generation "serverless" databases will fully abstract object mapping away. It's tedious and arbitrary. Even indexing is relatively easy to automate. I am incredibly excited for what Apple is brewing up right now for developers.

<comment><USER11> Is Apple working on some sort of serverless/Firebase type thing?

<comment><USER12> I think they're referring to this: [https://developer.apple.com/icloud/cloudkit/](https://developer.apple.com/icloud/cloudkit/)

It kind of flew under the radar, because it's not super clear how to use it from the landing page.

</comment></comment></comment></comment></comment><comment><USER13> The fact that the returned objects are plain old javascript objects (POJOs) that's nice.

The smart module bit, it's a bit scary.

basically all I want is a lightweight layer that exposes a promise api to deal with different databases in a uniform manner.

1) sync to schema.json (this json file contains info of all tables, their columns, indices and foreign keys). I can sync to db or from db. This lets me have my state of schema committed to git, and easily move from dev -> staging -> prod. Django migrations are a giant pain in the ass. Don't do smart fancy node modules either.

2) autogenerated typescript types, this are nice. But again don't do fancy node modules, have the typescript types committable to git repo. It makes it easy to diff and bisect when things fo awry.

3) Super light weight Object -> sql. Access foreign relationships as promises (always). Make it very easy to debug the generated sql for perf reasons. Django does some bits well but it's insanely slow at times. Doing things with raw sql should be just as fast as using a library.

<comment><USER7> Prisma Client is generated into node_modules by _default_ (because that's the most familiar thing for JS/TS devs), but you can specify any target location you like for it: [https://www.prisma.io/docs/reference/tools-and- interfaces/pr...](https://www.prisma.io/docs/reference/tools-and- interfaces/prisma-client/generating-prisma-client#specifying-the-target- location-for-prisma-client)

<comment><USER13> getting a `Not Found`

</comment></comment></comment><comment><USER14> This looks great and should surely cover most of the CRUD needs of simpler apps and hopefully even more. On the other hand, in my experience such complicated abstractions eventually leak, especially due to the complicated nature of the relational model and modern SQL.

For developers not keen on adding a thick indirection layer between the app and the DB, I have been trying to make raw SQL easier and more reliable to use directly in TS with PgTyped[1].

In general, I think most people are more than glad to use raw SQL solution instead of a mapper as long as it has:

1) Realtime parameter/result type inference in their language of choice.

2) Has autocomplete and validation in their IDE

3) Is composable, allowing to join queries/sub-queries..

So far I have been able to implement SQL-in-TS type inference in PgTyped[1] with autocomplete and validation on the way.

[1]: [https://github.com/adelsz/pgtyped](https://github.com/adelsz/pgtyped)

<comment><USER7> pgtyped looks awesome, fantastic work! We're huge fans of type-safety at Prisma so anything that makes working with DBs type-safe is right down our alley! :D

I think one thing that distinguishes Prisma (on the longer run) from a library like pgtyped is that Prisma will enable more database workflows than just database access. With Prisma Migrate, you can alter your DB schema and keep a migration history, Prisma Studio will enable lots of DB workflows on a GUI level, and Prisma Cloud will have great integrations for teams and larger scale organizations eventually.

All that being said, because Prisma is a DB _toolkit_ , you can also pick and choose any tools you like from it. Nothing would e.g. speak against using Prisma Migrate to run your schema migrations but keep accessing your DB with pgtyped, in fact I think this would be an awesome combination :)

</comment></comment><comment><USER6> Why on earth did Prisma take the choice to move away from a brilliant automatic GraphQL backend as a service to some kind of weird ORM?

Prisma became relevant during their Prisma 1 time, it was one of the first solutions to automatically generate GraphQL endpoints from DB schemas. It only had to keep going this way to lead the whole market. But they chose not too, and competing solutions such as Graphile beats prisma 1 so much now.

Meanwhile they have been stuck for 2 years in their new weird direction of Prisma 2, with no results to show for, and no clear vision. The GraphQL server is gone, even though it was central to their product. Who cares about yet another ORM? I can generate types from any GraphQL endpoint automatically anyway!

</comment><comment><USER15> I have been using it for a new project and it really is awesome. I can't imagine going back to an ORM or another query builder now.

<comment><USER16> Been using it as well on a side project together with nexus and nexus-prisma and it's really a joy to work with.

<comment><USER17> Same we've been using Graphcool/Prisma 1 for 2 years. Has been single handedly the biggest reason for our speed of development. We absolutely love the generated types and automatic introspection, everything is just documented automatically, it's truly revolutionary.

</comment></comment></comment><comment><USER18> This seems to be solving mostly the same problem as the following libraries:

[1] [https://github.com/phiresky/ts-typed-sql](https://github.com/phiresky/ts- typed-sql) [2] [https://github.com/Ff00ff/mammoth](https://github.com/Ff00ff/mammoth) [3] [https://github.com/AnyhowStep/tsql](https://github.com/AnyhowStep/tsql) [4] [https://github.com/travigd/vulcyn](https://github.com/travigd/vulcyn)

A query in one of those looks like the following:

        const rows = await select(list.id, list.createdAt)
          .from(list)
          .where(list.createdAt.gt(now().minus(`2 days`)).or(list.value.eq(0)))
          .limit(10);

The resulting type of `rows` is inferred by TypeScript to the corresponding correct type (`{id: string, createdAt: Date}`)

Prisma solves the problem by generating code, while all of these do it completely in type-level within typescript. Prisma also seems to introduce its own query language, while the above linked libraries stay closer to SQL.

[1] was written by a friend of mine and I'm using it in production to great success. I wouldn't recommend it though because it has repeatedly broken with new TypeScript updates since it uses very complex type structures and the dev has basically given up on it due to the complexity.

[2] is probably the most production-ready, though it has some design choices I'm not sure about.

[3] is the most well-designed, and can handle complex scenarios (including differentiating between join types etc). But it's incomplete so far.

[4] I have not used.

Pure type-level has the advantage of not adding a compile-step and keeping everything in a tool you already know. But all of the above have the disadvantage that the resulting type structures are very complex - most TS devs would have a hard time understanding the internals of the libraries and the resulting type errors can be unreadable. They can also cause the TS compiler to slow down significantly (in the past [1] had exponential compile time when adding a new column, though this has been fixed).

Also, since the TS compiler uses heuristics in multiple places and the type system is not sound, Microsoft has introduced regressions that have broken [1] in every other release.

<comment> timmy-turner Thanks for sharing these projects. So far I only knew tsql.

I'm in the avoid code generation camp as well as typically my build processes are complex enough and don't need another step.

But I am not quite satisfied by the existing query generators. Also after having read [https://github.com/jawj/mostly- ormless/blob/master/README.md](https://github.com/jawj/mostly- ormless/blob/master/README.md) I wanted to put Postgres' `json_agg` function into use as it looks like it is simplifying a lot of the nested objects stuff one serves over REST APIs.

So I designed my own [https://github.com/hoeck/typesafe-query- builder](https://github.com/hoeck/typesafe-query-builder) \- with special support for `json_agg` and `json_build_object`. Its working already in production and for me, the dev UX is unprecedented in working with database code. Typechecks and autocompletions really boost it. But to be honest, I'm a bit worried about Typescript compiler bugs and compilation times when the project grows.

</comment></comment><comment><AUTHOR> Tom Preston-Werner chose to include Prisma 2 in his new RedwoodJS project and it's been a pleasure to work with.

<comment><USER19> I'm very curious. Can you pleas share some specifics.

<comment><USER7> [https://twitter.com/mojombo/status/1244877311196856320](https://twitter.com/mojombo/status/1244877311196856320)

</comment></comment></comment><comment><USER20> Those, who prefer a more old-school approach, may find PgTyped [1] interesting: you write SQL and you have typings in TypeScript. Still very alpha, but promising.

I'm working on integrating PgTyped into Huncwot [2]

[1]: [https://github.com/adelsz/pgtyped](https://github.com/adelsz/pgtyped) [2]: [https://github.com/huncwotjs/huncwot](https://github.com/huncwotjs/huncwot)

</comment><comment><USER21> Edit: please read nikolasburk's answer below which makes a lot of sense. The docs weren't an attempted attack on all ORMs but rather a description of problems with certain Javascript ORMs.

My original post:

This looked interesting at first but this reads like someone either don't know a thing about JPA and Entity Framework or are deliberately misrepresenting them:

> ORMs are libraries that map tables in your database to classes in your > programming language. Prisma on the other hand is an auto-generated query > builder that exposes queries which are tailored to your models. All Prisma > Client queries return plain old JavaScript objects.

Yep, tables maps to classes, but guess what gets returned?

Plain Old Java (or CLR) Objects. And guess what: Thanks to those languages well thought out design and extensive metaprogramming abilities this can all be done without making up a new language also.

This is probably the harshest I've been here on HN, but smearing good solutions really doesn't sit well with me.

<comment><USER7> Hey, thanks a lot for the feedback (and I've seen harsher words on HN, so no worries)! I wrote most of the docs, so more than happy to take any feedback to see where it can improved!

What I'm mostly trying to refer to are ActiveRecord style ORMs in the Node.js ecosystem (such as Sequelize and TypeORM). With those libraries, you often have model objects that can get really complicated to work with, these are not plain objects but implement lots of additional behaviour for storage and retrieval of data, often times business logic as well. Compared to that, working with plain objects (which are statically and structurally typed) is a fundamentally different approach that's hopefully easier to reason (at least that's what I've found from my personal experience).

<comment><USER22> I don't really understand the claim you're making here--you have to go out of your way in TypeORM to get ActiveRecord objects instead of plain JavaScript objects. The happy path is pretty firmly in data-mapper territory; as an example, for all the shade I will happily fling NestJS's way they just hand you a Repository and tell you to get on with your day.

There's also stuff like Objection.js (which works well in TypeScript), too.

I don't dislike Prisma, but the framing is really strange to me.

<comment><USER23> Could be off-topic for this thread... but what shade would you like to throw NestJS's way? Or do you have a write-up somewhere else, by chance?

<comment><USER22> \- I think it comprehensively misunderstands and mis-implements a lot of things that are important. Their "microservices" boondoggle is a whatever RPC mechanism that has no real reason to exist, their CQRS library expects the world to be a single node, their OpenAPI library is vestigial and completely separates the generation of documentation from actually validating inputs. Most of the things outside of core are rotated about 45 degrees away from where you'd expect with a holistic understanding of a web application. Stuff built by somebody who heard of a problem, not felt a problem.

\- I think that the core team is bad at and refuses to improve at communicating with its community via roadmaps. Huge changes just appear, including literally breaking changes within a given major release, with little to no warning.

\- I think they don't respect what community they do have, building completely new, blessed-by-the-core-team libraries that step on existing open-source solutions in the NestJS ecosystem mostly just so the package can say "@nestjs/" at the front of it. (Top of mind example is "@nestjs/schedule", which is a worse take on "nest-schedule.") There isn't much personal incentive to build community tooling if the core team will swoop in and go "mine now!" without so much as a prior-work credit and it's disrespectful besides.

\- They continue to build their own tooling that steps on the accepted norms and systems in the Node community. The NestJS CLI now incorporates "monorepos" that aren't Lerna or Yarn ones; they're also pushing developers to use it as their primary way of building applications, rather than invoking tsc, with the dangly carrot of "we'll write plugins for it [rather than using one of the existing ways to better handle extended compilation]". It feels like a lock-in play for future monetization (there's open rumors that Kamil is very focused on monetization, which--you do you, but as Rails and Django and even Spring showed us this stuff seems to really work better if you care about it existing to exist, and you make money off of using it) and the lack of community roadmap makes assuaging those concerns very much not a priority of the core team.

I was a big booster of NestJS a year ago and I've written a bunch of modules for it. I was even a personal donor to the project's Open Collective, it's the only project I've ever done that for. But I do not use NestJS for new projects because I have no confidence in the design or the leadership there and I don't think it's a wise use of my time anymore.

<comment><USER24> What are you using now for your new projects instead of nestjs?

<comment><USER22> I'm writing a framework atop Fastify at the moment. My intention is to address a number of deep-seated technical problems I see with NestJS and present a holistic view of an _application_ , rather than a _web app_ , that can be used to more clearly structure and maintain my projects. I don't intend to monetize it, so I don't feel compelled to work outside of the normal NodeJS ecosystem and if there's any interest I intend to build a binding steering committee rather than run the risk of having a non-communicative "B"DFL.

</comment></comment></comment></comment></comment></comment></comment><comment><USER25> I LOVE massivejs[1], a query builder type library for Postgres in nodejs. Is prisma2 like massivejs but for typescript?

If someone's tried both, would love a quick comparison :)

[1] [https://massivejs.org/](https://massivejs.org/)

<comment><USER7> Massive is great and we certainly took some inspiration from it (in fact we're friends with Dian, the author of Massive and are fans of her works).

The level of type-safety when using Prisma Client with TypeScript is indeed a major factor that sets Prisma apart from other DB libraries in general (not Massive in particular).

Would also love to hear what other people think of the two in comparison! :)

</comment></comment><comment><USER26> How does this compare to TypeORM? First time hearing about this project, and it looks interesting

<comment><USER7> Nikolas from the Prisma team here.

The most important thing to note here is that Prisma Client is not an ORM! [1]

Prisma doesn't map classes to tables as ORMs do and therefore doesn't suffer from the object-relational impedance mismatch. Prisma Client queries return plain old JS objects, which makes it really easy to reason about queries and returned data.

Prisma also has a query engine [2] that's implemented in Rust. This is being developed separately from the TS/JS layer above (so that in the future Prisma can support other languages as well).

Prisma also generally provides stronger type safety than TypeORM. For example, you get full type safety even for partial queries [3], you can find an example for what this looks like in this video [4].

Let me know if you have more questions about this :)

[1] [https://www.prisma.io/docs/understand-prisma/prisma-in- your-...](https://www.prisma.io/docs/understand-prisma/prisma-in-your- stack/is-prisma-an-orm)

[2] [https://www.prisma.io/docs/reference/tools-and- interfaces/pr...](https://www.prisma.io/docs/reference/tools-and- interfaces/prisma-client/query-engine)

[3] [https://www.prisma.io/docs/reference/tools-and- interfaces/pr...](https://www.prisma.io/docs/reference/tools-and- interfaces/prisma-client/advanced-usage-of-generated-types)

[4] [https://youtu.be/LggrE5kJ75I?t=40](https://youtu.be/LggrE5kJ75I?t=40)

<comment><USER27> In the first document, all the links in the comparison table link back to the document itself instead of the documentation for the things mentioned.

<comment><USER7> Thanks, will get that fixed!

</comment></comment></comment></comment><comment><USER28> We started using Prisma 1 for our project and ran really fast into missing features that are really missing for a complete product.

But with a few workarounds it was possible to make it work and is quite nice to use.

Example of missing features:

Primary key as a combination of two relational models: [https://github.com/prisma/prisma1/issues/3553](https://github.com/prisma/prisma1/issues/3553)

Database Constraints [https://github.com/prisma/prisma1/issues/728](https://github.com/prisma/prisma1/issues/728)

Cascading Deletes [https://github.com/prisma/prisma1/issues/1262](https://github.com/prisma/prisma1/issues/1262)

Upsert [https://github.com/prisma/prisma1/issues/2194](https://github.com/prisma/prisma1/issues/2194)

On delete restrict [https://github.com/prisma/prisma1/issues/2701](https://github.com/prisma/prisma1/issues/2701)

Mutation CreateOrConnect [https://github.com/prisma/prisma1/issues/3724](https://github.com/prisma/prisma1/issues/3724)

Improving performance with Indexes [https://github.com/prisma/prisma1/issues/1300](https://github.com/prisma/prisma1/issues/1300)

Multiple field unique constraint [https://github.com/prisma/prisma1/issues/171](https://github.com/prisma/prisma1/issues/171)

Interface types [https://github.com/prisma/prisma1/issues/83](https://github.com/prisma/prisma1/issues/83)

Embedded Types [https://github.com/prisma/prisma1/issues/2836](https://github.com/prisma/prisma1/issues/2836)

Declarative support for multi-field unique constraints [https://github.com/prisma/prisma1/issues/1237](https://github.com/prisma/prisma1/issues/1237)

Support union types [https://github.com/prisma/prisma1/issues/165](https://github.com/prisma/prisma1/issues/165)

Transactions for multiple mutations [https://github.com/prisma/prisma1/issues/74](https://github.com/prisma/prisma1/issues/74)

<comment><USER7> Hey! Thanks a lot for sharing this, a lot of the features you mention here are already possible with Prisma 2.0 (or will be in the future). Would love to hear your thoughts on the new version :)

</comment></comment><comment><USER29> I've been using Prisma in development and highly recommend it. There's nothing like it out there!

</comment><comment><USER30> How does it differ from Hasura?

<comment><USER7> Prisma and Hasura are very different!

Prisma is a _database toolkit_ that's used by application developers to develop server-side applications in Node.js and TypeScript (e.g. REST APIs, microservices, gRPC calls, GraphQL APIs, ..., anything that talks to a database). The main tool Prisma Client is a _query builder_ that's used to _programmatically_ send queries to a database from Node.js/TS.

Hasura is a "GraphQL-as-a-Service" provider that generates a GraphQL API for your database. This GraphQL API is typically accessed by frontend developers. That setup can be great when your application doesn't require a lot of business logic and the CRUD capabilities that are exposed in the GraphQL API fit your needs (though I believe you can add business logic in Hasura by integrating serverless functions).

With Prisma, you're still in full control of your own backend application and can choose whatever tech stack you like for developing it (as long as it's Node.js-based, though Prisma Client will be in available in more languages the future)!

By the way, we also love GraphQL. We're currently brewing a new "GraphQL application framework" that can be used on top of Prisma. That way it will be possible to auto-generate resolvers for Prisma models to reduce the boilerplate you need to write, while still keeping the full control of your GraphQL schema.

You can learn more about this here: [https://www.nexusjs.org/#/](https://www.nexusjs.org/#/)

<comment><USER31> I want to point out a defining characteristic between Hasura and Prisma:

While Hasura does work to auto-generate a GraphQL API from an existing database, it also has a web console that lets you build your database models and relationships, plus permission logic and authorization point-and-click.

Custom business-logic outside of the CRUD it generates is done by writing HTTP endpoints that you can wrap as "Actions", which it generates GraphQL types and resolvers for as part of it's schema. IE, you will want to define an API endpoint for login/signup, and declare these as "Actions", which you can then query from Hasura's schema.

An SDK/toolkit can be auto-generated from the GraphQL schema Hasura produces using graphql-code-generator, giving you strongly-typed query/mutation/subscription components in your desired frontend framework (IE React/Vue/Angular + Apollo/urql etc.)

Scheduled tasks/cronjob functionality is under development as well.

Prisma gives you a "finer grained" set of tools to "build" an application with, where Hasura kind of just hands you the whole thing (though in an opinionated fashion).

</comment></comment></comment><comment> timmy-turner Not getting warm with any query/ORM library out there.

My own take of interfacing with an SQL database with Typescript: a query generator that uses mapped types a lot to infer result set types from queries and a schema file.

[https://github.com/hoeck/typesafe-query- builder](https://github.com/hoeck/typesafe-query-builder)

Not sure if thats a good idea and if the Typescript inference even scales that well when using lots of tables.

Any feedback and criticism would be welcome.

</comment><comment><USER32> Why generate types from a query when you can write a schema for your objects and then write queries where types can be inferred based on object types and query constructs?

Some ideas from a recently open sourced project:

[https://github.com/facebookexperimental/fquery/blob/master/t...](https://github.com/facebookexperimental/fquery/blob/master/tests/test_operators.py)

</comment><comment><USER33> Makes sense, non-type-safe language, we can push type safety guarantees to the persistence layer by coupling the domain models to the type-safe data models.

</comment><comment><USER34> Looks very interesting. At the moment we're using a Node.js + Postgres + Sequelize ORM [1] + Express setup in production and are very happy. All lot of features and very robust setup.

Any production ready experience with Prisma?

[1]: [https://sequelize.org/v5/](https://sequelize.org/v5/)

</comment><comment><USER35> Hi there, I'm a prisma 1 user and am wondering if there is thorough docs on how to transition over to prisma 2.

Also what breaking changes or not-yet-implemented features of prisma1 should I be aware of.

\----

Edit: I see there's a "I currently use Prisma 1, what should I do?" section. Any other info would be greatly appreciated.

<comment><USER7> Hey! We will provide upgrade guides and dedicated tooling [1] in the next couple of weeks to ensure a smooth transition for current Prisma 1 users!

You can find more context on isprisma2ready.com.

[1] [https://github.com/prisma/prisma/issues/1937](https://github.com/prisma/prisma/issues/1937)

</comment></comment><comment><USER36> Is mongo support in yet? I tried the Prisma2 beta a couple of months ago and it was still on the way.

<comment><USER37> We do not have Mongo support in Prisma 2 at this point, but we have a GitHub issue to track it as a feature request: [https://github.com/prisma/prisma/issues/1277](https://github.com/prisma/prisma/issues/1277)

</comment></comment><comment><USER38> I wish I was not stuck on Ms SQL server. The JS ecosystem tends to ignore it or treat it as a second class citizen. Would love to check this out otherwise.

</comment><comment><AUTHOR> Will SQL Server databases be supported at some point?

<comment><USER7> We're indeed planning to broaden the support for various databases in the future (e.g. already looking into MongoDB and FaunaDB).

If you have a specific DB in mind that you'd like to see supported, please open a feature request here: [https://github.com/prisma/prisma/issues/new?assignees=&label...](https://github.com/prisma/prisma/issues/new?assignees=&labels=&template=feature_request.md&title=)

<comment><USER39> Good to hear. Curious why Fauna is being looked into by your team, since it appears to be a much newer database (and also not open sourced AFAIK)? Mongo makes sense given its obvious popularity.

</comment></comment></comment><comment><USER25> Looks cool! Is there a business model around prisma?

<comment><USER7> We are planning to eventually add commercial cloud services to make Prisma/DB workflows easier (especially for teams and larger organizations). The current OSS database toolkit will remain free forever!

More info here: [https://www.prisma.io/docs/more/faq#how-much-does- prisma-20-...](https://www.prisma.io/docs/more/faq#how-much-does- prisma-20-cost)

</comment></comment><comment><USER40> Does this work with pnpm since node_modules/@prisma/client changes based on the project it's in?

<comment><USER41> It works fine with pnpm. The client package has a postinstall hook that generates the client after you install it.

</comment></comment><comment><USER42> Is real-time subscriptions on the roadmap? It's the most killer feature of Hasura and Postgraphile IMO.

<comment><USER7> Nikolas from Prisma here, a realtime API for Prisma is certainly on our roadmap – as Prisma doesn't provide a GraphQL interface, this most likely will not come in the form of GraphQL subscriptions though but another (programmatic) realtime API.

However, using Nexus [1] on top of Prisma, you'll be then be able to turn Prisma's realtime API into GraphQL subscriptions. All of this is quite a bit further down the road, but certainly on our radar and part of future plans!

We have an open feature request for that here: [https://github.com/prisma/prisma/issues/298](https://github.com/prisma/prisma/issues/298)

[1] [https://www.nexusjs.org/#/](https://www.nexusjs.org/#/)

</comment></comment><comment><USER43> So is that some sort of "ActiveRecord" for Javascript? It looks pretty darn cool.</comment>


Show HN: Priooo.com Agile product development tool - <AUTHOR> https://www.priooo.com <comment><AUTHOR> Hi, I'm a junior dev at Integration Partners which is located at Rotterdam, The Netherlands. The main business of our startup is the Ibis Adapter Framework which is built in Java.

[https://github.com/ibissource/iaf](https://github.com/ibissource/iaf)

We have a team dedicated to developing for the IAF and a smaller team which puts the IAF to use as a backend framework.

That is what I at Priooo. With the IAF as backend and Angular for the front end, we are building an amazing tool for agile scrum product development.

[https://www.priooo.com](https://www.priooo.com)

Yesterday we opened the free sign up because we think our product has reached a stage where it's stable and functional. Both teams within the our company use Priooo as our leading tool for the agile scrum process.

We offer an easy way to manage and filter trough your backlog. A roadmap to visualize what is going to happen in the future. A great kanban board to support you with what's going on in the current sprint and a way to look back at your historic sprints.

We are constantly looking to improve and listening for feedback. I'd say take a look at Priooo and feel free to leave your suggestions and thougts. They will be discussed within the Priooo team.

Many thanks for reading, Laurens

<comment><USER2> I'm going to sound a bit negative, but the site is not very nice. It's not 'sexy' enough to sell the service. Not that it shows much of it to anyway. I'll write an unordered list of thoughts about it.

\- Focus. meet. goals. Is it an introduction like "Peter, meet Claire" or is it a misspelling of "focus meets goal". Nitpicking but the more I thought about it the less clear it became and now I want answers :)

\- The huge image is kinda low res.

\- Why is there a bird? This bird could be the logo, could be slick.

\- I don't understand the logo, is it a bullseye or a signal? Why is the Ooo becoming smaller into the dot?

\- The headers and text, size and color is all over the place. Like:

1\. "Agile in the essence" is white and large like the header, "Vision" but it's not a header, it's inspirational .. stuff

2\. I count like 100 colors, backgrounds and font sizes.

3\. Too much green text

4\. Spelling errors, like "..in intuitive way" should be "..ways" right?

\- Misaligned icons and texts (like "[icon] look ahead") etc.

\- Horribly bad cropped screenshots of the product itself (and the tags in the product looks misaligned in their boxes)..

\- There's a section of text, again green, with green .. stuff between them, the diamond things.

\- Spacing is off, Like the "[icon] focus on now" and the screenshot below it.

\- The product itself screenshot of the kanban, the shadows are really strong.

\- Contact only through twitter or FB?

\- Way too much buzzwords, just show me the tool. Anyone interested is likely aware of what it is.

I'd have a proper designer take a look at everything, I feel most of these are at least fixable by even just making sure it is more consistent than currently.

<comment><AUTHOR> Yes, the landingpage atm is not sellings worthy, it's high on our backlog to have it redone.

Too bad you didn't checkout the tool itself</comment></comment></comment>


"Neo-Reactionaries" drop all pretense: End democracy and bring back lords - <AUTHOR> http://davidbrin.blogspot.com/2013/11/neo-reactionaries-drop-all-pretense-end.html

<comment><USER2> I'm rather amazed that there apparently are people who think replacing democracy with aristocracy is a good idea.

I admit, in the past I've said that the best form of government is an benevolent, enlightened despot. Someone who knows best, informs himself, and has the good of the people at heart. But surely everybody with half a brain knows that it's a complete crap shoot what kind of despot you get? Maybe you do get one good despot (probably because he got there through his own ability and some significant support), but the next one is going to be no better than all those crappy kings and lords we've had in the distant past.</comment>


The Guardian has SSL cert problems - <AUTHOR> https://www.theguardian.com/ <comment><AUTHOR> It looks like they installed a certificate only valid for theguardian.com, forgetting the wildcard. And since all calls redirect to _www_.theguardian.com ...

Someone is not going to the pub tonight.</comment>


McMansion Hell: The Devil Is in the Details - <AUTHOR> http://99percentinvisible.org/episode/mcmansion-hell-devil-details/ <comment><USER2> Previous discussion: [https://news.ycombinator.com/item?id=12286724](https://news.ycombinator.com/item?id=12286724)

Origin blog post/series the 99% invisible post is on: [http://www.mcmansionhell.com/post/148605513816/mcmansions-10...](http://www.mcmansionhell.com/post/148605513816/mcmansions-101-what- makes-a-mcmansion-bad)

</comment><comment><USER3> On one hand I'm really sympathetic to the criticisms from this blog.

On the other hand people want big houses and they have a limited budget. They can't afford a real mansion, so this is what they get instead. Is it really so wrong for people to want a lot of space?

I wish there was more in this blog about how to do it right other than "have enough money for a proper mansion" or "you should have a smaller living space."

<comment><USER4> The criticism in the article wasn't about people on a limited budget owning big houses. It was about the lack of architectural cohesiveness in the big houses they do build.

<comment><USER5> Seems like the same thing - isn't that pretty tied up to "don't have the budget for a 'proper' architect"? Design is a get-what-you-pay-for field. Do it piecemeal vs a single grand unified vision from the start and you end up with something easier to pay for but less ideal.

<comment><USER6> Most mcmansions have zero budget for design. Fifteen thousand dollars on a $600,000 job is good sense.

</comment></comment></comment></comment><comment><USER7> As someone who lived in upper middle class Texas suburbia, I'm pretty desensitized to "McMansions".

Aside from older houses (usually near the city center, small, and can be expensive) or custom-designed houses (very expensive), there's not much choice if you actually care about this stuff. Even the new apartment/townhome complexes could be considered "McApartments".

<comment><USER8> _Even the new apartment /townhome complexes could be considered "McApartments"._

That's a problem here in SF, too. Andrea Palladio would have wept.

</comment></comment><comment><USER9> I believe the commenters so far have failed to address the main point: the devil is in the details. And everyone knows why the details suck in this category of McMansion: they are spec houses designed by beancounters. They represent the aggregate current view of what would have maximum curb appeal. That is the only design criteria for such houses.

</comment><comment><USER10> This is the equivalent of graphic designers presenting alternate proposals for boarding passes and Craigslist. They're not wrong, and for those with a specific sort of sensibility, the "imperfections" can be grating, but for 99% of the population, they don't even _notice_ and it works just fine.

<comment><USER11> You've said this in two places on this submission, but I challenge you on the claim that "99% of the population" doesn't care what their house looks like.

I think a _lot_ of people do care.

<comment><USER10> I agree: a lot of people care what their houses look like here. But 99% of the population doesn't care about _this level_ of architectural nuance. And certainly not the population of people who are in the market for these sorts of homes in the first place (upper middle-class, suburban, etc.).

It's hard to prove a negative, but "despite all of this, the popularity of McMansions is picking up again". If McMansions are as "bad" as the author makes them out to be, and homebuyers "care" as much as you say they do, how do you account for the market?

<comment><USER11> If people actually didn't care, it would be of no consequence to hear their home called a "McMansion", and yet I suspect we both would agree that folks probably don't appreciate their home being critiqued such as how the blog writes about homes.

The reality is, most people would care if they knew, but don't know and therefore can't possibly care. It's not apathy, it's ignorance that drives the sale of McMansions, even though McMansions _are_ "bad", in the sense that they break architectural principles and are considered poor reflections of art because of it.

Obviously art isn't required to prevent rain from falling on your head, but the folks who are buying these houses are spending this extra money for something other than the literal safety, aren't they? _If_ someone buys a McMansion for any aesthetic reason, _then_ they are making a sub-optimal choice.

I think the assumption the blog makes is that a McMansion is a _failed_ attempt at creating art, not a rejection of the concept of home beauty.

</comment></comment></comment></comment><comment><USER12> This reads like old-$ "highbrow" East-coast hate for the nouveau riche. What is the alternative for someone who wants to build a house for a large family while spending 6 (or low 7) figures, as opposed someone with Larry Ellison money and Ivy League cultivated tastes?

"Cheap materials" \- that's valid, but what is the cost difference for "real Louis XIV marble fireplace" as opposed to "imitation"? Why build something to last 500 years when your children may not even want it?

<comment><USER7> One thing that has always puzzled me is the cheap materials thing. My parent's house, though not a McMansion, is in a neighborhood full of them and made of the same materials.

It's held up perfectly for ~10 years and plenty of hurricanes (some that happened while it was in the middle of being built!). What's the problem with the current materials?

<comment><USER13> Your mention of hurricanes, and parents who might be safely assumed to be retired, makes me think Florida. With that big bag of assumptions (throw out what follows if those are wrong), I'll remind folks that anything built in the last ten years is going to be very much regulated on how it's built. It'll be made of reinforced concrete block and the roof will be firmly tied to the rest of the house. The builder has no say in this. I'm not saying that given the choice the builder would choose the cheaper route, but a Florida house that laughs at a hurricane is due to government regulation more than the builder's choice of materials.

That, and Florida hasn't really had a decent hurricane in the last ten years.

<comment><USER7> Not so close but an interesting answer. My parents live in South East Texas (south East of Houston!) and not retired. I'll admit that the last big hurricane we had was that I remember was in 2008~ish.

</comment></comment></comment></comment><comment><USER14> I would happily live in any of these houses.

</comment><comment><USER15> Is it possible to buy good craftsmanship these days? I'm asking this in all earnest, not to make a rhetorical point; does anyone know of businesses in the US today that can build a house that will endure like a 1920s Craftsman?

If so, who are they, and where do they operate -- what businesses should I contact?

<comment><USER6> Absolutely. The key is in the general contractor (GC). One accustomed to doing better work will know the right subcontractors (subs). For instance, those that specialize in restoration, remodeling, and repair in historical districts.

<comment><USER15> Thank you!

</comment></comment></comment><comment><USER16> Even if we grant all these points as correct, not everyone shares the same aesthetic sense as professional architects. As long as you like your own home, it really doesn't matter what other people think of it.

And I find the last bit of the article truly scary -- bragging over fan mail sent to the site about how this type of critique is letting people verbalize and validate their own instinctive hate for their neighbor's design choices. Is that really a net positive to our society? To use critique as a mechanism to feed negativity between neighbors?

<comment><USER17> There are a LOT of people who think they should be able to substitute their own judgment for other people's when it comes to the home they live in.

</comment></comment><comment><USER18> This is a little off topic but does anyone know of any resources for architecting/designing your own house. Specifically, I think it'd be worthwhile to learn from the layouts of other houses. I'd also love to hear about how people are wiring up their houses (fiber, audio, etc).

<comment><USER19> How to Design Your Own House: Step 1) Pay an Architect to design your house.

<comment><USER18> I'll definitely do that! I guess I'm just looking for places to get inspiration from.

</comment></comment></comment><comment><USER20> European here. Are there really people who live in those er... things, or are they only used to shoot porn flicks?

On a more serious note, if they want to display different styles, instead of packing them together, why don't they build 2 or 3 smaller buildings?

</comment><comment><USER8> It's a little harsh. Not everyone can afford a top-quality architect.

And mixing styles (the main criticism of this article) is not always a bad thing: Chartres Cathedral is considered a masterpiece, despite it's weird mixed spires.

<comment><USER6> She discusses that in Eclecticism. She uses pictures throughout to demonstrate the difference between mixing well and badly.

</comment></comment><comment><USER17> Don't like it? Then don't buy one.

</comment><comment><USER21> For those lacking the visual aids to understand what a grandiose home vs. a McMansion looks like, the blog this is based on has a good visual explainer here: [http://www.mcmansionhell.com/post/151896249151/the- mcmansion...](http://www.mcmansionhell.com/post/151896249151/the-mcmansion- scale-explained)</comment>


Why is "on hold" music/audio so bad? - <AUTHOR> Why is on hold audio sound like a cassette tape? Are they trying to get rid of me?
Why is the music they play so dated?
Etrade on hold is the same music for the last, I don't know, 15 years.
Missed opportunity or is this on purpose? <comment><USER2> > Why is on hold audio sound like a cassette tape?

Because a telephone voice channel is limited to a bandwidth of about 3100hz with a pass band of about 300hz to 3400hz ([https://en.wikipedia.org/wiki/Voice_frequency](https://en.wikipedia.org/wiki/Voice_frequency)). This is a compromise for reasonable voice transmission, but produces terrible music transmission.

> Are they trying to get rid of me?

The answer for some may be "yes", but that's not the technical reason for the poor music sound quality.

> Why is the music they play so dated?

Most likely guess: copyrights.

> Etrade on hold is the same music for the last, I don't know, 15 years.

Several reasons likely play into this:

1) once set, it is simply forgotten about because it is just working

2) the purpose of the music is not to entertain, but to assure the person on hold that the call has not terminated prematurely.

3) in part because of #1 and #2 the PM's and or those controlling the budget allocations don't see any reason to spend money 'fixing' something that in their mind is not broken.

</comment><comment><USER3> I've been, even in recent times, on hold only to be stuck with staticky music. Not just low quality, but literally from what sounds like a half-tuned-in radio station.

In such cases, I am left to assume they want you to do your deeds online so they don't have to pay people to answer the phone and inevitably tell you to do your deeds online.</comment>


Bop.fm (YC S13) Links Together Music Silos Like Spotify, Rdio To Share Tracks - <AUTHOR> http://techcrunch.com/2013/12/05/yc-backed-bop-fm-links-together-music-silos-like-spotify-radio-and-itunes-to-share-tracks-universally/

<comment><USER2> From the terms for embedding the player [1]:

> You agree to place a link ("SEO Link") to bop.fm's home page (www.bop.fm) on > at least one (1) web page within each Website that is no more than 3 clicks > away from the home page of the applicable Website and is indexed by Google > with "Page Rank". Each SEO Link will be displayed using the anchor text > "bop.fm" (the "Anchor Text") and will be accompanied by a generic > description of bop.fm (e.g., "bop.fm enables any user to play any song, use > any streaming music service, and share with any friend.") and the bop.fm > mark. You will not prevent search engines from crawling any web page > containing an SEO Link and crediting bop.fm for such SEO Link, including, > without limitation, by using "no follow" designations, placing the SEO Links > in an i-frame, or placing the SEO Links in JavaScript.

This seems like a bit of an odd requirement, especially since it's not mentioned anywhere other than the ToS.

[1] [http://www.bop.fm/tos-meta](http://www.bop.fm/tos-meta)

<comment><AUTHOR> If you're interested in embedding the player in a more programmatic way, shoot us a note - email@example.com

</comment></comment><comment><USER3> I'm really excited about this kind of service. People have been moving increasingly online in everything they do, and music is no exception. I believe that in the future the vast majority of media consumption will use streaming. (As if it isn't, already!) My main side project involves this kind of service, so I know at the very least it can be complicated to write a server/website which can chomp diverse APIs. [1] What puzzles me is how this could be monetized--I'm sure YouTube and SoundCloud aren't in a hurry to stream their media for free without seeing license fees.

[1] [https://github.com/fruchtose/muxamp](https://github.com/fruchtose/muxamp)

</comment><comment><USER4> How do they make money?

<comment><USER5> My first guess would be affiliate commission from the various services where you can buy the music.

</comment></comment><comment><USER6> Tomahawk has been doing this for quite awhile, both as a standalone payer and on the web: [http://toma.hk/](http://toma.hk/)

</comment><comment><USER7> I had a similar idea since I wanna create playlists from tracks in multiple resources and made this library; [http://github.com/azer/play- url](http://github.com/azer/play-url)

Which takes a url (Mp3, Rdio, Soundcloud and Youtube) and gives you a unified API to play it. www.7min.io/customize is based on this.

</comment><comment><USER8> Looks like a more enhanced, professional version of one of my side projects, TuneCrawl. Hopefully it does well!

</comment><comment><USER9> Oh man, if they expose some sort of API, it could be used to clean up tags in music libraries and such. Being able to give a service the tags you have (or a hash of the song or something) and have what track the result most probably is could be awesome.

<comment><USER10> have you heard of the echonest api? im pretty sure they even use it at bop.fm

<comment><USER9> I have not! Thanks for pointing that out. I have a few projects that I wouldn't mind using this in.

</comment></comment></comment><comment><USER11> How does this compare to Tomahawk?

<comment><USER12> For those not familiar with Tomahawk, it has an api to locate songs across multiple services. Afaik, it only offers a native music library; it's lacking a way to manage a personal library online. It also has trouble identifying mislabeled live vs studio recordings, which bop.fm seems to solve by using song fingerprints.

[http://toma.hk](http://toma.hk)

</comment></comment><comment><USER13> No more "this is not available in your location."! I have been waiting for that.

Just got picked up by TNW - [http://tinyurl.com/bopfm1](http://tinyurl.com/bopfm1)

</comment><comment><USER14> I feel like it'll probably make Spotify Premium obsoltete considering it makes mobile listening of Spotify's tracks free...

<comment><USER15> Not even close (for me). Offline playlists is the main reason I use Spotify on my mobile.

<comment><USER14> Yeah, I guess that is a big plus. The feature I was referring to was the ability to directly access a track on Spotify from mobile, which is only available with Premium.

</comment></comment></comment><comment><USER16> Been waiting for something like this!

<comment><USER17> Just curious, what for? Seems like you can do the same thing just listening on youtube.

<comment><USER18> It looks like they skip through the Youtube ads. I'll be using bop.fm a lot.

</comment></comment></comment><comment><USER19> Nice. Can't login with my Spotify though. Just says 'launch spotify or login here'.

</comment><comment><USER20> You can only login/signup through facebook? Unfortunate.

<comment><USER8> There is a TODO comment for adding in login with email in the source code. So hopefully that will change soon!

<comment><USER20> Nice catch. I'll be looking forward to it.

</comment></comment></comment><comment><USER21> I love this idea

</comment><comment> saiko-chriskun meh. I'll be sticking with google all-access.

</comment><comment><USER22> [http://xkcd.com/927/](http://xkcd.com/927/)

<comment><USER7> this is such a silly and dummy example.

<comment><USER22> this is such a silly and dummy argument</comment></comment></comment>


We are working towards launching a human being into space - <AUTHOR> http://www.copenhagensuborbitals.com/

<comment><USER2> Note that this item also has been discussed in detail at: <http://news.ycombinator.com/item?id=583550>

Reading about attempts like this that "push the envelope" in any area just make me happy to be a human watching other humans accomplish great things.

<comment><AUTHOR> Thanks.

</comment></comment><comment><AUTHOR> Sorry for the title. There was no real usable title on the page, so I took a sentence from their site ("[http://www.copenhagensuborbitals.com/mission.php"](http://www.copenhagensuborbitals.com/mission.php)) instead.</comment>


Cracking the credit card code - <AUTHOR> http://blog.paylane.com/cracking-the-credit-card-code

<comment><USER2> ...there's nothing to crack here, so I find the title misleading. I would find articles such as "Cracking the ISBN code" or "Cracking the CRC32 code" equally misleading.

To me, cracking implies breaking through a barrier intended to be opaque. Hence, Ross Anderson's paper on an attack on the hardware security modules in ATM machines to brute force a PIN for a given account in less than the full PIN space is, truly, an example of cracking:

<http://www.cl.cam.ac.uk/techreports/UCAM-CL-TR-560.pdf>

</comment><comment><USER3> Original link/source: <http://www.mint.com/blog/trends/credit-card- code-01202011>

</comment><comment><USER4> Back in the day, when processing payments for online transactions cost the earth and pre-auth was but a twinkle in the eye of the bank API developers, knowledge of the Luhn algorithm allowed one to test services via their free trials without having to give up one's credit card number. These days it's only useful as a pre-pre-auth sanity check.

</comment><comment><USER5> The article mentions and informally describes the Luhn algorithm which is fairly interesting.

<http://en.wikipedia.org/wiki/Luhn_algorithm>

</comment><comment><USER6> Why should anyone do this it is against the law.

<comment><USER7> What on earth are you talking about?</comment></comment>