1. 31

    I switched my project from MIT to Apache 2 when I read a blog post from the LLVM project, indicating that they interpret the MIT licence differently than I do. MIT is ambiguous, and this blog post verifies it. The Apache 2 licence is clear and unambiguous, plus it covers patents, which is important to me in case a patent holder ever contributes to my project. The one drawback is that Apache 2 is not compatible with GPL 2 (according to the FSF).

    I would consider using the Blue Oak licence if the following things occur:

    • The Open Source Initiative certifies it as Open Source.
    • The Free Software Foundation certifies it as a Free Software Licence, and certifies that it is compatible with GPL 2 and GPL 3.
    1. 9

      The English language, as commonly used in informal conversation, is ambiguous, but we mostly don’t notice, because we automatically look for the most obvious or reasonable interpretation. In legal disputes, it’s different, which is why contracts and licences need to be more explicit and verbose. I think the Apache 2 licence does a good job of being both readable and unambiguous.

      The Blue Oak licence is a lot shorter than Apache 2, and I think it is ambiguous. It appears you are allowed to delete the author’s name from the copyright notice, while leaving the licence in place. Blue Oak seems to allow this:

      Each contributor licenses you to do everything with this software that would otherwise infringe that contributor’s copyright in it.

      Deleting my name from the copyright notice would certainly infringe my copyright, so is this allowed? Apache 2 explicitly disallows this.

      1. 9

        “copyright notices” haven’t been a part of any country’s copyright law for years and preserving names/attribution requirements have never been a part of most. Some licenses require attribution (ISC/MIT/BSD) but in practise that is routinely violated and never enforced. Blue Oak explicitly has no attribution requirement (only the requirement to notify downstream of the license) and has no language about “copyright notice” because it’s an antiquated concept with no legal teeth.

        1. 11

          Some licenses require attribution (ISC/MIT/BSD) but in practise that is routinely violated and never enforced.

          Really? it’s a pretty big deal to me if somebody copies my source code verbatim, deletes the “Copyright Doug Moen”, and substitutes their own name, with no other changes, even if the licence is preserved. I would definitely take action if I found out some other project was doing that with my code.

          There was a high profile case in 2007 when a Linux kernel developer copied a driver from OpenBSD, deleting the copyright notice and licence, replacing it with their own. In that case, the OpenBSD team did enforce their licence and forced the Linux team to restore the original copyright and licence text. See: http://undeadly.org/cgi?action=article&sid=20070913014315

          In this case, the issue wasn’t just a matter of the licencing terms being changed. It was also an issue of the original author no longer being credited with writing the code. Theo de Raadt wrote:

          Now it may seem petty to be pointing out the above, but these Linux wireless developers have ignored the ethical considerations of honouring the author for his work, and then violated the law 3 times under advice from a ex-FSF laywer. Come on. By that point someone should at least be offering the author an apology

          1. 2

            Fair point, I shouldn’t say “never”.

            But go try to find a website that isn’t violating a MIT/ISC/BSD license on a javascript dependecy by omitting the license and notice.

            I’ll wait.

            1. 5

              To be fair there is a convention for preserving licenses and common tooling supports it so this happens less than you’d think. You are right in general though – people don’t always think about this, and the library not being set up correctly w.r.t. the tooling does not not remove the requirement to include attribution.

              1. 3

                Off the top of my head, FSF.org.

          2. 4

            I believe (IANAL) that keeping your name intact is a “moral right” separate to copyright. Wikipedia lists the moral rights as:

            the right of attribution, the right to have a work published anonymously or pseudonymously, and the right to the integrity of the work

            The Blue Oak license doesn’t mention them but that’s not unusual as I think only Creative Commons really addresses the issue.

        1. 15

          The easiest way to solve the problem is to increase the size of your gp2 volume.

          While this is true, there’s another way that will give you even more iops for less (or zero!) additional cost. Many EC2 instances come with a local SSD. For example the i3.large instance type - which is fairly small, just 2 cores and 16GB ram - includes a 475GB NVMe SSD. You can perform tens of thousands of iops on this disk easily.

          Obviously, since this SSD is local it’s contents are lost if your instance is stopped for any reason, like hardware failure.

          1. 3

            Also worth noting there’s more options like this since the introduction of the new generation instances with “d” designators, like c5d and m5d, which have local nvme storage, and might be a good balance between general purpose compute while still having local storage. The i-type hosts are “I/O optimised” which solves the storage problem but might leave you without much for the actual build tasks.

            1. 2

              Thanks for the idea, noted in the article.

          1. 6

            I believe they are actually using the api for the intended purpose, I used them on a site to optimize code sample displays inline (I just couldn’t get it to be perfect wit just css) but there’s nothing I see on the ddg website that couldn’t be done without scripts at all - so many websites use javascript when you don’t really have to. (Though, to their credit, they do offer a functional non-script experience, just on a separate page.)

            1. 3

              I wondered about this while reading the article.

              I’m not familiar with the “Canvas DOMRect API”, but the insinuation in TFA seems to be that just using the API is enough for a site to be considered a fingerprinting tracking site? Is that true? Why do browsers even include it?

              1. 8

                Why do browsers even include it?

                Basically any information you can get about a browser can form part of a fingerprint, which is one of the things that makes fingerprinting so hard to counter. In this case the API lets you get the geometry of the browser (window size primarily I think), which while unlikely to be unique on its own, could be quite discriminating, and could form part of a fingerprint. It’s an API with a completely reasonable innocent normal use, though.

                There’s some information about fingerprinting using canvas on this on this website.

            1. 16

              Once again this highlights just how slow some of the most popular mainstream languages are.

              1. 28

                It’s too apples to cucumbers comparison for that. The Rust solution and prior efforts are wildly different. Author started with scripting language known to be slow as hell to do a performance-oriented application. Then, switched to a product of a hype train, Spark, that’s known to use clusters of servers to do things slower than a laptop. Then, the author did a custom algorithm in a language suitable for high-performance apps. It outperformed the prior solutions. No surprise.

                A better comparison would be similar algorithm in C, C++, .NET, Java, and so on. Even the JIT’d ones would have time to optimize given the size of data set and amount of repetition. Each also has libraries to solve specific problems well like the author discovered about Rust. Who knows which would win at what performance gap in such an apples to apples comparison. All this article tells us is that Rust (a) could do this specific job well, (b) rayon made it easy to parallelize it, and (c) all that was faster than horribly-inefficient tools. Still useful but title gives wrong impression.

                1. 5

                  Spark, that’s known to use clusters of servers to do things slower than a laptop.

                  This is a little bit of an unfair comparison in this case. The “laptop” article talks about cases that map/reduce-type frameworks are especially bad at. Spark provides some libraries for doing graph algorithms like this but they are super-slow and only really make any sense if you have colossal data sets (and even then I’m not sure).

                  In this article though the person is doing a straight map of a file to stats and Spark will just run the code you provide to do that, introducing little overhead. It’s likely that the improvement the person sees here really are due to their Rust parsing code bring faster than calling their Python parser via. a JVM. A better comparison would probably be to have written the Spark job in Java or Scala but Spark is unlikely to add much overhead to that.

                  That said for a straight map job Spark doesn’t buy you a whole lot unless you are running multiple inputs in parallel in a cluster so a straight lambda, similar to the final solution, would likely work as well as the Glue implementation since they seem to receive files one-by-one.

                  1. 4

                    I agree. However, I assume Ruby has a regex library implemented in C. I wonder why wasn’t that used?

                    1. 2

                      Onigmo is great. I like using Ruby for grokking lots of text, you can get some pretty decent performance out of it. Maybe the author was allocating too much memory (which is too easy to do in ruby)

                      1. 1

                        Probably. Could likely wrap on, too, with who knows what cost.

                      2. 4

                        While Spark wasn’t quite an apples-to-apples comparison, I think the Ruby vs Rust comparison is pretty valid, and that’s what the 230x improvement refers to.

                        1. 5

                          If title said Ruby, Id be fine with it. People woud instanty know the speed up was from super-slow tech to speed-focused tech. Without it, one might wonder if they moved from a fast stack to Rust still getting 230x speedup.

                          If title and tag said Ruby, Id have not even clicked the link since interpreted to parallelizing native always has big speedup.

                          1. 4

                            Ah, that’s fair. I misunderstood and thought you were criticizing the blogpost title itself, rather than the Lobsters presentation of it. FWIW in the context of André’s blog the post and title make a lot of sense: he’s the lead maintainer of Bundler, the de facto Ruby package manager, as well as the founder of Ruby Together, an organization for supporting open-source Ruby projects, and so when he posted about a 230x speedup with Rust in context it makes sense that he’s comparing it to Ruby. When I saw the title and the URL I knew what I was getting into, but people outside of the Ruby community probably wouldn’t, so a Ruby tag on Lobsters would’ve helped.

                            1. 1

                              See, that makes since if author’s well-known. Yeah, I wanted the change for us non-Ruby developers so we know at a glance if there’s tips we can use.

                      3. 6

                        Ruby is slow but not that slow, there’s certainly a performance hit from the VM and the GC but I bet you could rewrite that parsing script to be just 2x to 5x slower than the Rust version if you try your best to avoid allocations and keep the cpu caches warm.

                        Rust’s main advantage here, IMO, is that it’s perceived as a fast language, which makes people question their code rather than the language when something’s slow. You can write fast Ruby and Python too, but it doesn’t feel as “idiomatic” as writing fast Rust.

                        1. 1

                          That’s what I’m wondering. It sounds like he didn’t experiment much with the Ruby version and it has different features than the Rust version. It would be interesting to see how much the Ruby version compares with the same feature set and aggressively tweaked for speed.

                          1. 1

                            It is actually about that slow, if you do non IO-bound stuff without aid of foreign (read: C) libraries. Things like matrix multiplication or FFT, and it’s not a perception issue.

                            1. 1

                              I was talking about the specific case of reading and parsing files from disk, obviously the more CPU-bound the job is the more the overhead of the VM is gonna hurt speeds. But in my limited experience (solving some project euler problems in Ruby) it’s still not that slow even for number crunching compared to an equivalent C program, and tuning memory usage is still gonna get you very far.

                        1. 3

                          The damn cookie notice spam won’t go away, and it’s over the contents.

                          1. 1

                            Haven’t tried this one, but I usually delete the Instagram etc. overlays in developer mode.

                            1. 1

                              Try clicking then dismissing the settings thing (cog icon), I had the same issue.

                              1. 1

                                I found it helpful to open it in Incognito, then export it as a PDF.

                              1. 4

                                Its really easy to write a simple HTTP server. I’ve done it a couple of times for weird languages like Self. You can do it in an afternoon and you end up with something which is fast enough and usable enough for simple websites with low traffic and all you need is to be able to talk to your OS to open a socket, read, write and close it.

                                There is no way that I’m going to write a HTTPS server. Which is a shame because it means that small language projects like Self will need to rely on a bunch of third party C code and third party infrastructure (letsencrypt, caddy, openssl etc) to serve a simple website.

                                1. 8

                                  Any HTTP Server can be easily converted into a HTTPS server by piping it through a SSL proxy. It’s the same protocol going over the pipe, after encryption there is no difference.

                                  1. 1

                                    Sure, that’s what letsencrypt, caddy, openssl, etc provide you: a way to turn your simple HTTP server into a public facing HTTPS server. But the cost is that a small protocol which could be completely written in house for fun now needs a whole bunch of complicated C/Go/etc code and systems written and hosted by someone else…

                                    1. 10

                                      At the risk of being overly reductive you’re already depending on a bunch of code someone else wrote unless your HTTP implementation also included the TCP and IP layers. Adding in TLS can be thought of as just inserting one more layer to the several that already exist beneath you.

                                      (A complicated one you might need to configure and that isn’t provided by the OS, I grant you)

                                      1. 3

                                        I was reading your post and wondering if the size difference between a standard kernel-space TCP implementation and openssl was negligible or not.

                                        find linux/net/ipv*/tcp_* -name '*.c' -o -name '*.h' | xargs cat | wc -l
                                              25119
                                        find openssl/ssl openssl/crypto -name '*.c' -o -name '*.h' | xargs cat | wc -l
                                              285101
                                        

                                        Turns out t’s an 11.3 ratio, it is not negligible at all.

                                        I was actually not expecting a difference that big!

                                        [edit]: I just re-read my comment, do not interpret that as an attack, it is not :) You just itched my curiosity here!

                                        1. 2

                                          On top of that, if we compromise performance for code size by dumping optional parts of the spec, we can get a minimal functional TCP stack in an amazingly small amount of code (cf uIP, lwIP, and the fabulous VPRI parser based approach in Appendix E of http://www.vpri.org/pdf/tr2007008_steps.pdf)

                                          1. 1

                                            That’s really interesting! Didn’t interpret it as an attack at all, don’t worry!

                                          2. 2

                                            Come on now, there’s a big difference between depending on, say, BSD sockets and depending on an SSL proxy like nginx or something.

                                            1. 1

                                              I’m more familiar with using languages/frameworks with built-in support. If you’re implementing it by a proxy that’s obviously a whole other component to look after.

                                              1. 1

                                                And what exactly would that difference be?

                                                1. 3

                                                  A separate daemon adds more complexity (and therefore fragility) to the system. BSD sockets are well understood and aren’t something the sysadmin has to manually set up and care for.

                                      1. 2

                                        To divide by 3, I used a multiplication trick. On tiny devices, division is often implemented as a (slow) library call, but if you’re dividing by a constant, you can usually find a good equivalent fixed-point constant. “One third” in binary is “0.5555…” repeating, so using a 16-bit fixed-point fraction, you can multiply by 0x5556 and shift right 16 bits.

                                        Why 0x5556 and not 0x5555?

                                        1. 7

                                          Because shifting right by 16 is the math equivalent of “floor” instead of “round”, so we need the result to be not just “as close to 1/3 as possible”, but the error needs to be on the high side instead of the low side.

                                          0x5555 * 3 = 0xffff – shifts right to zero

                                          0x5556 * 3 = 0x10002 – shifts right to one

                                          I’ll add this to the post, thanks!

                                          1. 1

                                            Thank you!

                                          2. 1

                                            Because the number 0.555555… is a little closer to 0.5556 than 0.5555. When they say “in binary” I think they mean “in hex” too.

                                            1. 3

                                              0x0.55555… is closer to 0x0.5555 than 0x0.5556. Remember, 0x0.5 is five sixteenths, significantly less than a half (which would be 0x0.8).

                                              1. 2

                                                Well corrected! I clearly fluffed that in my head.

                                          1. 3
                                            import java.util.stream.*;
                                            
                                            public class Triangle {
                                                public static String triangle(int rows) {
                                                    return IntStream
                                                            .rangeClosed(1, rows)
                                                            .boxed()
                                                            .map((row) -> Stream.iterate(row % 2, (n) -> n == 0 ? 1 : 0)
                                                                                .map(Object::toString)
                                                                                .limit(row)
                                                                                .collect(Collectors.joining(" ")))
                                                            .collect(Collectors.joining("\n"));
                                                }
                                            
                                                public static void main(String[] args) {
                                                    System.out.println(triangle(4));
                                                }
                                            }
                                            

                                            Yes, it looks much uglier than Haskell version, but constructs are almost the same.

                                            (I’m not arguing that you can avoid imperativeness in Java, you almost can’t, and even Streams are imperative but somewhat composable)

                                            1. 5

                                              to be fair, java 8 (and streams) had only been out in the wild for 5 months when this was written.

                                              1. 3

                                                But are those features of Java actually taught at university? Because they sure don’t spend time on them where I’m at.

                                                1. 2

                                                  I haven’t run across it, though I could imagine some contexts where they might be. I might even consider doing it in the future, given the right circumstances. But I think they’re not that likely circumstances. Usually university courses are trying to teach at least two things with a programming language (or language construct): the language itself, and some broader principle, which students will hopefully retain long-term and be able to apply even when languages inevitably change over. So typically Java has been used either as “generic intro-level language” or “OO language”, which Java 8+ streams don’t fit that well into.

                                                  In universities where Java’s used as the standard intro-level language, there’s some advantage to continuing to scaffold atop it for further things, because you can assume everyone already knows the basics. But it’s falling out of favor for intro-level classes in favor of Python. So I think you will either see people introducing this “streams” style of programming in Python if the circumstances fit, or else they’ll stick with a more traditional introduction to sequence filtering/mapping/etc. in the context of an introducion to functional programming, in Haskell or ML or maybe some Lisp dialect.

                                                  1. 1

                                                    So I think you will either see people introducing this “streams” style of programming in Python if the circumstances fit, or else they’ll stick with a more traditional introduction to sequence filtering/mapping/etc. in the context of an introducion to functional programming, in Haskell or ML or maybe some Lisp dialect.

                                                    I’m aware of some libraries that provide special syntax for that in Python, but I don’t think anything other than list comprehensions (and maybe higher-order functions) for this kind of stuff is considered “Pythonic”.

                                              2. 3

                                                I did much the same but tried to introduce names in the same places as in the original; as relatively idiomatic Java that’s:

                                                public class Triangles {
                                                    public static void main( String[] args ) {
                                                        System.out.println( triangle( 4 ) );
                                                    }
                                                
                                                    public static String triangle( int n ) {
                                                        return IntStream.rangeClosed( 1, n ).mapToObj( Triangles::line ).collect( Collectors.joining( "\n" ) );
                                                    }
                                                
                                                    public static String line( int n ) {
                                                        return alternating( n ).limit( n ).mapToObj( Integer::toString ).collect( Collectors.joining( " " ) );
                                                    }
                                                
                                                    public static IntStream alternating( int start ) {
                                                        return IntStream.iterate( start, i -> i + 1 ).map( i -> i % 2 );
                                                    }
                                                }
                                                

                                                You can also go totally crazy, but I wouldn’t recommend it:

                                                public class Triangles {
                                                    public static void main( String[] args ) {
                                                        IntFunction<IntStream> alternating = i -> IntStream.iterate( i, n -> n + 1 ).map( n -> n % 2 );
                                                        IntFunction<String> lines = l -> alternating.apply( l ).limit( l ).mapToObj( Integer::toString ).collect( Collectors.joining( " " ) );
                                                        IntFunction<String> triangle = n -> IntStream.rangeClosed( 1, n ).mapToObj( Triangles::line ).collect( Collectors.joining( "\n" ) );
                                                
                                                        System.out.println( triangle.apply( 4 ) );
                                                    }
                                                }
                                                
                                                1. 2

                                                  Great, now I want to my own version but I have to work…

                                                  1. 5

                                                    I wrote mine too! ;)

                                                    Funny how similar Rust and Haskell are in those small examples.

                                                1. 2

                                                  it’s hard to tell what this has to do with plan 9… what is “go and plan 9 assembly”?

                                                  1. 4

                                                    Plan 9 had its own assembler and the one in the Go toolchain is based on it, which might explain its use here. Like you I’m not sure why the prominent billing in the title of this post, the actual page doesn’t make a huge deal out of it.

                                                    1. 5

                                                      IIRC, plan 9 assembly is platform independent; the plan 9 assembler takes it as input and outputs platform-specific machine code. This means it’s more portable, basically.

                                                  1. 39

                                                    A single anecdote honestly doesn’t even hint very hard that this is a real thing. Confirmation bias is incredibly strong. In the absence of significantly more rigorously-collected evidence, I’m very strongly inclined to say the ad was relevant by pure coincidence.

                                                    1. 9

                                                      Yea, there are many possibilities that are far more likely than the one they propose.

                                                      Simple coincidence is definitely one. Or someone else in the group did a search while connected to the same hotspot, or while advertisers had figured out they’re in the same household.

                                                      People often overestimate how random and unique their behavior is. You can often tell a lot about someone based on a few demographics…and can make surprising correlations.

                                                      It may be as simple as their age/location/profession to tell you they’re likely to consider buying a projector in the next 6 months. Perhaps they read an article about setting up a movie night, or gaming outdoors, etc.

                                                      1. 2

                                                        Quite likely, but ytf would Instagram require microphone access?

                                                        1. 16

                                                          Video?

                                                          1. 2

                                                            Oh, I didn’t know. Thought it was a picture service. Only seen it occasionally, never used it.

                                                            Thanks for clearing it up!

                                                          2. 6

                                                            It can record videos with sound. Microphone access is required to use the camera in the app as a result.

                                                        1. 1

                                                          I like internet quizzes, I’ll admit it.

                                                          SILE/INTP for me.

                                                          1. 11

                                                            Interesting thing about this task is that I think static typing in a language like Java gets in the way more than it helps.

                                                            I haven’t used Java in a long time, but I would spend most of my time figuring out how to make a list that contained both integers and List objects. Maybe Oracle finally got around to making the primitive types real objects and it wouldn’t be so difficult now?

                                                            In Common Lisp it’s almost trivial, although this version isn’t as fast as the one in Alexandria:

                                                            (defun flatten (lst)
                                                                (if (listp lst)
                                                                    (apply #'nconc (mapcar #'flatten lst))
                                                                    (list lst)))
                                                            
                                                            1. 10

                                                              I’m guessing the “correct” way of doing this in Java would be to make a List<Object> and then fill it with Integers and other lists. Basically completely sidestepping the type system. This is unintuitive, and so you’re right that this question is probably a better fit for a dynamically typed language.

                                                              Alternately, in a language like ML, Haskell, or even Swift, you can use a sum type, where you can specify that the list contains objects that can either be other lists or integers, and have the type checker enforce that they can’t be anything else (unlike the Java example where you could theoretically stick any object in that list).

                                                              1. 6

                                                                Interesting thing about this task is that I think static typing in a language like Java gets in the way more than it helps.

                                                                That’s what makes it a strange interview question in this context imo, where it seems they’re hiring for a Java shop, interviewing candidates who responded to a job ad looking for Java programmers. Flattening a list is an introductory textbook example in dynamic languages where you can actually write literals like “[1,[2,3], [4, [5,6]]]”. But it’s not really a introductory Java textbook example.

                                                                It’s of course solvable in Java, and a broadly competent programmer should be able to come up with a solution in an hour. But I’m not sure it serves as a great fizzbuzz-type baseline filter when hiring for a Java shop. You probably end up filtering more on whether the candidate has previously encountered a flatten function in a different language and remembers the algorithm (maybe they went to a university that had a Scheme course), and/or whether they’re comfortable with doing ugly run-time type things in Java. Which are not useless skills, but there are probably lots of reasonably but narrowly competent Java programmers who would get hung up because it’s a bit of a “foreign” example to someone who works entirely in Java.

                                                                1. 3

                                                                  Pretty easy in Python too:

                                                                  def flatten(lis):
                                                                      ret = []
                                                                      for item in lis:
                                                                          if isinstance(item, int):
                                                                              ret.append(item)
                                                                          elif isinstance(item, list):
                                                                              ret.extend(flatten(item))
                                                                      return ret
                                                                  
                                                                  1. 1

                                                                    Using generator and yield from would be my first choice, but yeah… What’s so hard about that? I mean… It’s literally a five minute task.

                                                                    1. 3

                                                                      It’s only easy if you recognize the right case analysis. I use to TA for a programming languages course (mostly juniors and seniors), and one of the first assignments contains a question that asks you to write this function in a lisp-like language. Tons of students trip on it. A lot of them do get it right, and some of them write sub-optimally correct solutions (i.e., redundant case analysis). If you’re not use to thinking about recursive structure, then it can be tricky!

                                                                      N.B. The assignment is given after a lecture that covers rose trees, so we weren’t just throwing them to the wolves. :-)

                                                                      1. 3
                                                                        def flatten(source):
                                                                            for item in source:
                                                                                yield from flatten(item) if isinstance(item, list) else [item]
                                                                        

                                                                        yield from ftw indeed!

                                                                        1. 1

                                                                          I should use these Python-3 only features now that I’ve finally ported my setup :)

                                                                    2. 1

                                                                      I haven’t used Java in a long time, but I would spend most of my time figuring out how to make a list that contained both integers and List objects.

                                                                      I think I would start by taking a step back to see if your data are being properly represented by objects. Java is, after all, OO. If you need a heterogeneous collection, it should be typed to store a parent class of the subclasses you want to store. Asking how to collect objects and lists is too abstract; rather ask how do I collect records about single family homes and also apartment buildings that are composed of multiple units.

                                                                    1. 1

                                                                      yeah, why?

                                                                      1. 5

                                                                        its the blog post:

                                                                        This happened not before trying to convince @Unknwon about giving write permissions to more people, among the community. He rightly considered Gogs his own creature and didn’t want to let it grow outside of him, thus a fork was necessary in order to set that code effectively free.

                                                                        1. 2

                                                                          Looks like there was some minor drama in the Gogs world and that the primary developer of that project was away for a while. Since nobody could push changes they forked the project. An issue on the Gogs Github seems to indicate the protects have differing philosophies now.

                                                                          1. 1

                                                                            Looks to me like your typical governance fork, like with ØMQ/nanoMSG, egcs/gcc, eglibc/glibc. I would bet on the fork with a more open community.

                                                                            Here’s what happened with ØMQ (but in reverse, name-wise):

                                                                            http://hintjens.com/blog:93

                                                                            http://sealedabstract.com/rants/nanomsg-postmortem-and-other-stories/

                                                                            People over code, the best is the enemy of the good, worse is better. Instead of being conservative, accept more input from the community, grow and breathe enthusiasm into the community. Any warts introduced by one contributor will be polished by another.

                                                                        1. 9

                                                                          I think the DailyDot is incorrect, or at least confused. There was never, to my knowledge, a way to enable any sort of device (full or not) encryption for the eReaders. (Kindle Whitepaper, DX, etc) The Android-based tablets? Yeah, and as the screenshot shows, Amazon no longer supports it. The only encryption I know of on the eReaders is the DRM for the ebooks themselves, which I doubt Amazon is too keen on removing any time soon.

                                                                          1. 1

                                                                            What you’re saying sounds right to me, as well.

                                                                            1. 1

                                                                              They’ve since updated the article and posted a correction at the bottom.

                                                                            1. 10

                                                                              I can’t find a license for this code, which is disappointing given how prominently the code of conduct is displayed. As it is, there isn’t much here.

                                                                              1. 5

                                                                                Yeah, I noobed out, sorry. I wasn’t expecting anyone to really really pay attention here until next week, when I had more content up and was gonna promote it for real. Oh well.

                                                                                1. 3

                                                                                  This looks like a project by Lobster’s steveklabnik

                                                                                  1. 3

                                                                                    Yeah, it is. I skimmed it a few days ago and it only had a handful of sections…now it has a dozen. Definitely a work in progress, and mostly a hobby/teaching OS if I understand correctly, so I imagine a lot of stuff is still being fleshed out.

                                                                                    Neat stuff steveklabnik!

                                                                                    1. 5

                                                                                      now it has a dozen.

                                                                                      I rode a bus home from my mom’s for 8 hours on Saturday, and got a bunch of drafts up… then got back to the internet, saw it was on HN, and said “well, I might as well publish the drafts, since people are checking it out and there isn’t a ton yet”.

                                                                                      So what’s there is rough but it will get better.

                                                                                  2. 2

                                                                                    There’s an issue for this which is being worked on. Only complicated since it’s derived from another project.

                                                                                  1. 1

                                                                                    Question about HTTP status codes in general: should they be represented as int or as string? It’s prolly inconsequential, though I’ve seen both choices floating around.

                                                                                    1. 1

                                                                                      That’s curious. What are the benefits of string representation? I have only seen ints.

                                                                                      1. 1

                                                                                        IIS will pass fractional sub-codes so I suppose it might be too support handling those?

                                                                                        1. 1

                                                                                          Oh wow, hadn’t encountered that. Yes, strings would be helpful there. Thanks for passing that along.

                                                                                      2. 1

                                                                                        I’d answer “no”. They should be represented as strongly typed instances, though probably with the option of giving a custom one - possibly enums with the correct ints would be adequate. Look at spray.io (or its spiritual successor http4s) for a library that I think handles status codes really well.

                                                                                        1. 1

                                                                                          It’s appropriate that an HTTP library would define some response code types for the programmer. Yet it’s interesting to note that both of the libraries listed choose to represent the “raw” response code as int. Again, inconsequential, but curious…

                                                                                        2. 1

                                                                                          I would use int only. Because range of the number also matters and int are easier to compare. Check these lines. For example, any code between 200 and 299, including those, is considered success.

                                                                                          1. 2

                                                                                            Equivalently, for a string type, you could check the first character to determine which class the response falls in.

                                                                                        1. 4

                                                                                          For him the scrolling becomes natural, comfortable and predictable.

                                                                                          I would have picked better examples. The intence page doesn’t feel natural or predictable at all. It has the wrong “intertia” on iPhone. Exactly what this library claims to get right, it gets wrong. And it breaks tap on status bar to scroll to top, to boot.

                                                                                          I don’t understand these scrolling libraries. The worst native browser scrolling crushes (crushes!) even the best fake scrolling JavaScript. And typical js scrolling is far from the best.

                                                                                          1. 1

                                                                                            Had a similar experience on Android, but maybe it’s only supposed to make a difference in desktops?

                                                                                            1. 1

                                                                                              In general, I agree with you regarding the intence page.

                                                                                              However, the natural scrolling has good applications in places where automatic scrolling has to happen – especially when 2 dimensions are involved. A project I worked on this summer needed to highlight the relationship between a list and an SVG, and we used automatic (smooth) scrolling to make sure the thing that was to be highlighted was actually visible

                                                                                              1. 1

                                                                                                Yeah, kinda makes you wonder: if JS is in fact going to take over the world, wouldn’t it have done so by now? JS is butting up against technical limits, and I don’t see browser vendors having any real incentive to push things further. Three of the four major browser vendors (Google/MS/Apple, but not Mozilla) have a major source of income established on top of native apps. That is probably a safer revenue stream than the web can ever be.

                                                                                                (Though from the app economy’s POV, wouldn’t it be nice to reclaim some of the economic surplus being extracted by the app stores? I don’t think it’s possible though, I think app store success is somewhat derived from there being a consistent and optimized way to pay – i.e. a payment system monopoly is a precondition to the current native app distribution success.)

                                                                                                Maybe it would work to build JS a new UI toolkit that is not dependent on HTML (but polyfilled to it). Surely it would be easy to write useful apps in JS if you were targeting a different toolkit, i.e. one not hamstrung by HTML. Android showed that it is possible to write OK user facing apps in Java. It seems within reason to do so in JS as well.

                                                                                                Then again, I think it’s fair to say that any web developer turned app developer that cares about UX enough to switch to a more native language has already done so. And therefore the JS developers that remain have been selected down to those that don’t care about UX as much or aren’t as capable. I guess it’s a question of how many such JS developers there really are.

                                                                                              1. 7

                                                                                                This looks pretty useful! Did you consider using the JSON Pointer notation for the key output? It’s not without its issues but it is “standard”.

                                                                                                1. 7

                                                                                                  Huh, I’ve never seen this RFC before.

                                                                                                  You could easily change the separator to “/” in the current implementation. However, there is not (currently) an option to remove the wrapper around the keys. I think that the wrapper makes it all more easily grep-able. The RFC also does not address array indices, which makes things a little challenging.

                                                                                                  However, adding the ability to remove the wrappers would be a simple enough change to support this kind of format if one chose.

                                                                                                1. 2

                                                                                                  This is the kind of distributed database I’d want to use. Dealing with data loss from extremely fringe eventual consistency bugs is not my definition of fun.

                                                                                                  Also, the keys having a total order is really nice! :D

                                                                                                  1. 3

                                                                                                    I don’t see FoundationDB hitting the same use cases as an eventually consistent DB. I’m not actually sure what the use case is for FoundationDB. The database does not support multiple data centers and the company actively tries to talk people out of expanding across datacenters[1]. Things that would require the kind of write performance they are offering are going to be pretty big, I would imagine. You wouldn’t host Twitter in 1 datacenter, for example (to take a comparison the author makes).

                                                                                                    I think it’s cool that they are achieving this kind of performance. I just don’t understand want problems it’s solving. I would rather have eventual consistency where I can setup clusters around the world and sync them, giving me horizontal scalability of operations, than be stuck in 1 database cluster in one datacenter and have to get as much performance out of that as possible.

                                                                                                    [1] http://highscalability.com/blog/2014/11/12/three-reasons-you-probably-dont-need-multi-data-center-capab.html

                                                                                                    1. 1

                                                                                                      I’m not actually sure what the use case is for FoundationDB.

                                                                                                      It goes fast, and has multi entity transactions. Already with transactions it’s better than Amazon DynamoDB, and there are lots of use cases for that. DynamoDB also doesn’t have multi datacenter replication.

                                                                                                      Not every application needs to be multi datacenter. Tons of applications have exactly zero need for that. Not a lot of mega-scale web 42.0 apps, but those certainly aren’t the only applications that use a lot of data. Your use case is always on ecommerce (if I recall correctly), and you didn’t see a use case for Redis Cluster either, which is hardly surprising given your domain.

                                                                                                      I would rather have eventual consistency where I can setup clusters around the world and sync them, giving me horizontal scalability of operations, than be stuck in 1 database cluster in one datacenter and have to get as much performance out of that as possible.

                                                                                                      If these benchmarks are accurate, you don’t need multi datacenter capability for horizontal scalability. Use case wise, data exploration and analysis would be extra flashy with a database with this kind of latency and throughput. Real time analysis would be way more real time.

                                                                                                      All that besides, the transaction coordination system is still quite interesting.

                                                                                                      1. 5

                                                                                                        Not every application needs to be multi datacenter. Tons of applications have exactly zero need for that.

                                                                                                        I agree. But how many of those apps need to do 14 million writes per second? It’s unclear to me who needs this kind of performance in one datacenter that doesn’t also need to scale horizontally, at the very least for availability.

                                                                                                        If these benchmarks are accurate

                                                                                                        I do question the results of the benchmark too. The test was only run for 5 minutes. That is far too little time for a database test. On top of that, this was in very ideal circumstances, the data fitting easily in RAM. I’d like to see a run for around a week, with data larger than can fit in RAM. Not that I think the results are a lie, more than I’m not sure it is covering a realistic workload.

                                                                                                        1. 2

                                                                                                          More distant clients would probably be good too. They’re comparing to twitter, for example, but twitter clients aren’t all running in the same cluster. Running the DB in one AWS region and the load generator in a separate would be a good test (like say US East vs US West).

                                                                                                          1. 1

                                                                                                            I don’t think that many need 14 million writes per second, I think it’s more than you can have less hardware and still get really good performance, with the option to scale up fairly easily in the future. You certainly don’t need to employ hundreds of servers in a base case deployment of the database, the benchmarks are more about saying that you could if you wanted to for whatever reason.

                                                                                                            Also, RAM is the new disk. ;)

                                                                                                          2. 3

                                                                                                            I agree with you in general, but it’s worth considering that only being in one datacenter is a resiliency hazard. If your datacenter gets smashed by a hurricane for example, you’re going to see nontrivial downtime, even if you can handle 14M writes per second.

                                                                                                            With that said, I don’t think that foundation DB is anti-multi-DC. I think they already have some partial support of it. From their docs:

                                                                                                            Multiple-datacenter support in this release is immature. If you are considering using multiple datacenters in production, we recommend that you contact us so we can work together for best results.

                                                                                                            1. 2

                                                                                                              With that said, I don’t think that foundation DB is anti-multi-DC. I think they already have some partial support of it. From their docs:

                                                                                                              I’ll believe it when I see it. The goal of the database seems at conflict with supporting multiple datacenters. And the article from FoundationDB on High Scalability seems to be trying hard to talk people out of multiple datacenters. I’ll be interested to see what they do though, clearly very capable people.

                                                                                                            2. 2

                                                                                                              DynamoDB also doesn’t have multi datacenter replication.

                                                                                                              DynamoDB only has multi-datacenter (well “facility”) replication. You can’t disable it. It’s not cross-region though. From documentation:

                                                                                                              The service replicates data across three facilities in an AWS Region to provide fault tolerance in the event of a server failure or Availability Zone outage.

                                                                                                              1. 4

                                                                                                                I’m aware, I used to work on DynamoDB before I left Amazon, I was just simplifying. The big thing people want is actually multi region replication. Having 3 data centers right next to each other makes them susceptible to the same problems. Region wide failures aren’t unheard of on AWS.

                                                                                                                1. 1

                                                                                                                  Thanks for clarification!

                                                                                                        1. 3

                                                                                                          With things like the ConcurrentAdder I wonder why its a new API instead of just a new, faster implementation of AtomicInteger. The author supposes that developers should always use the adder, so why the new API?

                                                                                                          1. 4

                                                                                                            In addition to the size argument made in a sibling comment, AtomicInteger/Long has a very different API to LongAdder. It is used for counter management because it’s the best construct available for it, but that doesn’t mean it’s a great one.

                                                                                                            In particular you always sample when you increment an atomic type (using incrementAndGet or getAndIncrement). This means it must update inline. The adder type, which has a void increment, doesn’t have this constraint, so can defer the synchronisation cost. The actual means of implementation changes the structure’s internal representation enough that it warrants another type.

                                                                                                            1. 3

                                                                                                              One potential problem (if it matters to you) is size: LongAdder is a lot bigger. It uses a list of packed AtomicLongs. So if you have 24 cores and high contention, your LongAdder could grow to 24 packed counters. And each counter is packed with 64 bytes to prevent false-sharing along cache lines, which makes them rather bloaty for what is basically a simple counter.

                                                                                                              Of course, if you have 24 cores and high enough contention to cause the LongAdder to use 24 counters…you need the concurrency anyway and probably don’t care about the bloat.

                                                                                                              If your counter is rare-contended, AtomicLong will be faster since there is a certain amount of overhead to the whole LongAdder setup.