HN user

graue

2,897 karma

Just another {Python,Perl,C,JavaScript,Clojure,Lua} hacker. I was in Hacker School's winter 2013 batch. It was awesome.

https://scott.mn

email: scott@<the above domain>

https://twitter.com/graue

https://github.com/graue

Posts18
Comments744
View on HN

Think of strings in JavaScript. Those are already immutable:

    var fooString = "foo";
    var secondFooString = fooString;
    secondFooString;  // => "foo"
    
    fooString = "bar";
    secondFooString;  // => "foo"
We set the variable fooString to point to a different string, but the original, underlying string hasn't changed. In JavaScript, we can think of a string as a value.

This is not the case with arrays in JavaScript:

    var firstArray = [1, 2, 3];
    var secondArray = firstArray;
    
    firstArray[0] = 100;
    firstArray;  // => [100, 2, 3]
    secondArray;  // => also [100, 2, 3]
Because we can change the underlying contents of the array, an array in JavaScript isn't a value. It's a place: a reference to a location in memory. The underlying value could be changed at any time.

But, using Mori, collections are values, just like strings:

    var firstVec = m.vector(1, 2, 3);
    var secondVec = firstVec;
    
    firstVec = m.assoc(firstVec, 0, 100);
    firstVec;  // => [100, 2, 3]
    secondVec;  // => still [1, 2, 3]
Instead of modifying firstVec in place, mori.assoc creates a new vector that is identical to firstVec except for the change we want. We then assign the result to firstVec. secondVec is unchanged. We are unable to go in and change the underlying values because a vector is a value, not a place.

The most obvious way to build this would be to deep-copy the entire collection when it's changed, but that would of course be way too slow and wasteful — imagine copying a one-million-long array just to change one element. Clojure, ClojureScript and Mori minimize unnecessary copying using a very thoughtfully designed data structure you can read about here: http://hypirion.com/musings/understanding-persistent-vector-... The short story is that, surprisingly, you get "effectively O(1)" copying when you use assoc.

Interesting perspective, thanks. I suspect it depends on whether you're more used to langs like Ruby, Python, JavaScript (which are more like Clojure) or Java (which is more like Scala). Coming from Python and JavaScript, and with minimal Java experience, I find Clojure more approachable... but then, Java-style OO is utterly vexing to me.

Did you ever look at Clojure? If not, why not? If so, what didn't you like?

While Clojure surely has a bigger learning curve than Go, it's much simpler and more approachable than Scala. I've learned it recently and am an absolute convert. It seems perfect for your use case and you could even skip writing the prototype in Rails because you'll be just as productive in Clojure.

Note that I'm not trying to convince you to change; you obviously found something that works for you. But I am curious if there were obstacles to using Clojure (missing libraries? poor tutorials?) and if so, how that could be fixed.

Congrats on your company's success!

However, I'm surprised that you single out a 40-hour work week as though it's something exceptional. Isn't that the standard? I would never consider joining a company that expected me to work weekends. I hope that's not as common as you imply.

As a fellow Clojurist, I agree with the substance of what you're saying here but wish you could express it in a more friendly manner. Both your comments essentially say "you're wrong" without educating or adding value. I don't feel that reflects well on the Clojure community, and I'd like us to do better.

It's true that historically "he" has often been used a generic pronoun, but singular "they" also has a long history. I'd start with this Wikipedia article:

https://en.wikipedia.org/wiki/Singular_they

Some object to the usage because:

Proponents of gender-neutral language argue that the use of gender-specific language often implies male superiority or reflects an unequal state of society. According to The Handbook of English Linguistics, generic masculine pronouns and gender-specific job titles are instances "where English linguistic convention has historically treated men as prototypical of the human species." Words that refer to women often devolve in meaning, frequently taking on sexual overtones.

These differences in usage are criticized on two grounds: one, that they reflect a biased state of society, and two, that they help to uphold that state. Studies of children, for instance, indicate that the words children hear affect their perceptions of the gender-appropriateness of certain careers. Other research has demonstrated that men and women apply for jobs in more equal proportions when gender-neutral language is used in the advertisement, as opposed to the generic he or man.

https://en.wikipedia.org/wiki/Gender-neutral_language_in_Eng...

Many years ago, I would have agreed with you that using "he" as neuter was correct and therefore preferable to singular "they". I no longer feel that way. I'd attribute that change in opinion to two causes:

One, I'm less concerned with by-the-book "correctness" and pedantry, and more concerned with the real-world effect my words have on people.

Two, I now realize that English is a living, evolving language, and there is no one authority on what is or is not correct usage. What is widely held to be proper English at a given time is a product of who happened to have influence in society at that time, no more, no less.

Also, although this is not what changed my opinion, I find it interesting to note that many of the same people who call the matter trivial will also expend considerable time and effort defending generic "he". If you find it so trivial, why not humor the people who think gender-neutral language is important?

Cryptocat was and is open source too:

https://github.com/cryptocat/cryptocat

That doesn't solve the problem. No one is going to manually view source and compare it every time they use the damn thing.

To address your points 1 and 4: Since all data is encrypted BEFORE leaving your browser (this was NOT the case with lavabit) even if our servers were compromised your data would still be secure.

At rest. Yes, at rest it's fine, like I said, but if someone logs in while the server is compromised, it would be trivial to decrypt anything they post or access during that session. Same as Lavabit.

We'll be releasing [..] a browser-extension, that will help confirm that the code you've received on the site is the same as that in the repository.

So it'll download two copies of the code, one from your servers and one from GitHub, and check that they match? Doesn't seem to me that that buys you much. And unless it's mandatory, you'll be leaving the users that don't install the extension unprotected.

See here for a long list of other reasons in-browser crypto is problematic: http://www.matasano.com/articles/javascript-cryptography/

we are creating a client-side, in-browser encryption system where a user can upload their already encrypted content to our storage system and be 100% confident that their data can never be decrypted by anyone but them.

This concept may sound clever at first but gives you as the user no additional confidence compared to encrypting data on the server side upon arrival. Either way, you're trusting the host.

The threat model for server-side encryption is essentially:

1) the host has an unethical employee who wants to read your content.

2) the host's servers are insecure and get compromised.

3) someone successfully MITMs your connection to the host (possibly due to the SSL problems being discussed here).

4) the government compels the host to provide your data (i.e. what happened with Lavabit).

The threat model for browser-based client-side encryption is the same! In any of these cases, the attacker (or the host, in case of #1 or #4) simply sends JavaScript encryption code to your browser with a backdoor in it.

Cryptocat originally worked the same way: all chats were encrypted on the client side, but with JS code sent from the server, in which a backdoor could be inserted at any time. After much criticism, this is why Cryptocat is now a browser add-on, with discrete releases made available from a central source (Chrome Store/Mozilla addons site), which can be audited.

Awesome site!

Having done a few Clojure projects lately, I got most of these right immediately, but there were a few I messed up. It would be cool if you could go through these flashcard-style: one try for each koan in a category, then re-show the ones you got wrong, and repeat until you get them all right.

Undo 13 years ago

"every undoable action first needs to be represented by an object in your code. This is called the Command Pattern"

This is too OO for my taste. Having just seen a talk about MiniKanren, I wonder if you can implement undo effectively with a relational (logic) programming system. Is anyone aware of research (or practice) to that effect? My googling isn't turning up anything relevant.

Shoot, no patch for the 1.2.x series? That's disappointing. It's not that old, is it? I feel like I upgraded to 1.2.x, which was then the newest stable branch, just over a year ago.

Rust is not fast 13 years ago

Three times, so:

    1. Old version compiles new version
    2. New version, compiled by old version, compiles new version
    3. New compiled by new-compiled-by-old compiles new version
I hadn't heard of this before and initially didn't see why #3 is special. But I guess the idea is, the output object code is a function of both the input source code and the compiler version. And those two are the same for #2 and #3. So you expect the output of both #2 and #3 to be identical, and if it's not, that's a bug in the compiler. Is that how it works?

If you're going to comment mentioning it, you should probably tell people what it is :)

For those who haven't seen it, Nightcode is a new, open-source Clojure and Java IDE written by the person I'm replying to. Has project templates, paredit mode, REPL and CLJS build integration. I only played around with it for 5 minutes and went back to Vim, so I can't really endorse it but it looks cool.

https://nightcode.info/

Didn't see this survey in time to contribute, but I'm one of the tinkerers who's used CLJS more than Clojure. Most of what I've been interested in doing is in-browser. For my last project[1] I used a regular Clojure REPL to clarify my understanding of the standard lib and paste in little functions for testing. Don't remember why I didn't use a browser-connected ClojureScript REPL. Maybe it just didn't seem worth typing "rlwrap lein trampoline cljsbuild repl-listen" when I can type "lein repl" :P

My biggest wish is for the ClojureScript compiler to be less accepting of stupid code. I've made all kinds of moronic mistakes[2] that would ideally yield a warning or even a straight-up error, right at the source, but they don't and I just end up finding data structures full of nils at runtime. I've also hit a few traps with lein-cljsbuild[3][4]. This is all definitely improving though.

I've now started my first real Clojure project, a web app built on Luminus[5]. Luminus kind of strikes me as training wheels for Clojure. It's easy to get started with, and minimizes the sense of foreign-ness coming from a Python web development background. But I doubt I'll still use it once I have more experience, as opposed to simply putting its component libraries (Compojure, Ring, lib-noir, etc.) into a project directly. Which is fine; it fills a valuable role in the ecosystem anyway.

1. https://github.com/graue/dumbbell

2. Example: http://dev.clojure.org/jira/browse/CLJS-639

3. https://github.com/emezeske/lein-cljsbuild/issues/239

4. https://github.com/emezeske/lein-cljsbuild/issues/248

5. http://www.luminusweb.net/

That bit from the Underscore docs is only a suggestion, and one that Google, for example, certainly doesn't follow. Try typing a search query so fast you don't get suggestions until you're finished. It's hard to do!

Right after your quote, the docs add: "For example: rendering a preview of a Markdown comment, recalculating a layout after the window has stopped being resized..." These operations can both be very expensive on the client side — layout is slow — and can also distract the user if they make stuff jump around on the page. The downsides of doing these updates too often are more clear than for a simple autocomplete.

Thanks for posting this. I'd written my own ad-hoc version of _.debounce for a web app, but the difference between throttle and debounce was totally lost on me. (If anyone else is slow today and doesn't immediately get it from reading the Underscore docs, there's a very clear comparison here[1].)

Empirically, I can't type fast enough (sustained) for throttle to be better than debounce here — there are frequent 200ms gaps in my key presses. This is part of why I was confused. I thought I was typing very quickly, definitely faster than 43wpm == five keystrokes per second, but apparently I slow down to think now and then. My code seemed to behave like _.throttle already, but changing the timeout from 200ms to 2sec made it clear that it wasn't.

But I'm switching to _.throttle, partly in case someone is a faster typist than me, and partly because it makes a leading-edge call, which may give a feeling of greater responsiveness.

1. http://drupalmotion.com/article/debounce-and-throttle-visual...

Snapchat, which thrived partially due to 'offensive' content

Assuming you mean sexting, I think the percentage of sexually explicit images sent on Snapchat has been wildly exaggerated — by tech journalists looking for clicks, and by older folks not in Snapchat's target market who don't really get the point. Snapchat's appeal for everyday, non-sexual use seems to go over the heads of most tech people I know, but has been described eloquently by, e.g., Nathan Jurgenson[1] and Dustin Curtis[2].

Porn on Tumblr and sexts on Snapchat make for interesting headlines, but I'd hesitate to credit either as a major reason for the platform's success without actual numbers on its prevalence. To my knowledge those numbers don't exist.

1. http://thenewinquiry.com/essays/pics-and-it-didnt-happen/

2. http://dcurt.is/photos-for-communication

Unaffected by Microsoft's announcement, yes. However, they will be affected by any successful preimage [edit: or collision] attacks on SHA-1, and the possibility of such an attack appears to motivate Microsoft's announcement.