HNHacker News
TopNewBestAskShowJobs

Rangi42

444 karma · joined August 17, 2012

submissionscomments
Rangi42··on JSON Lines
I don't see what this improves over standard JSON. Just add a comma at the end of each line and wrap the whole Lines file in brackets, and you have a valid JSON file. You can petition spreadsheet makers to support this subset of JSON files, while still letting any general JSON program read and write them.

As for CSV and TSV, they're a dead-simple format to read and write, and you can enforce a standard way to escape special characters if you aren't dealing with arbitrary user-submitted files. With numeric data escaping isn't even necessary, and if you have to deal with strings that might themselves contain special characters, the ASCII control characters 0x1E and 0x1F work well as alternatives to comma/tab and newline.

I know Python has a csv module, but I've just gotten used to writing these snippets:

    def tsv_write(path, headers, data, sep='\t', end='\n'):
        with open(path, 'w') as file:
            file.write(sep.join(map(str, headers)) + end)
            for datum in data:
                file.write(sep.join(map(str, datum)) + end)
    
    def tsv_read(path, headers, sep='\t', end='\n'):
        with open(path, 'r') as file:
            for line in file:
                yield line.rstrip(end).split(sep)
(That tsv_read function only works if end == '\n'. Here's a somewhat-inefficient general-purpose alternative, although I've never needed it.)

    def read_records(file, end='\n'):
        if end == '\n':
            for line in file:
                yield line
        else:
            record = []
            while True:
                c = file.read(1)
                if c:
                    record.append(c)
                if c == end or not c:
                    yield ''.join(record)
                    record = []
                if not c:
                    break

    def tsv_read(path, headers, sep='\t', end='\n'):
        with open(path, 'r') as file:
            for record in read_records(file, end):
                yield record.rstrip(end).split(sep)
Rangi42··on The HTTP/2 implementation
HTTP/1.1: 1.53s, 1.97s, 1.32s, 1.65s, 1.48s = average 1.59s

HTTP/2: 1.09s, 0.87s, 1.19s, 0.92s, 1.30s = average 1.07s

The slowest of five HTTP/2 results is still faster than the fastest HTTP/1.1 result, and on average it's nearly 50% faster.

(I'm on a 37 Mbps network in New York, using Firefox 40.0.3 on Windows 8.1 with a cleared cache.)

Rangi42··on “Two days ago the police came to me and wanted me to stop working on this”
I downloaded the source code on principle. It's good to know there are plenty of online copies.
Rangi42··on “Two days ago the police came to me and wanted me to stop working on this”
This wasn't a thorough deletion. The shadowsocks-iOS project has been switched to the 'rm' branch, but the 'master' branch still contains all the source code: https://github.com/shadowsocks/shadowsocks-iOS/tree/master There's also a downloadable 2.6.3 release with a built .dmg and source code: https://github.com/shadowsocks/shadowsocks-iOS/releases

Even if it does get completely removed, a duplicate exists on GitLab: https://gitlab.com/mba811/shadowsocks-iOS (No guarantee that it has all the commits prior to deletion, or that it hasn't been modified from the original in some way.)

I can only hope the police in clowwindy's country don't know how to switch GitHub branches.

Rangi42··on Tentacles that think
"An octopus is probably something like an unruly parliament of snakes ruled by a dog."

—Andreas Schou

Rangi42··on Official Android 6.0 SDK and Final M Preview
> The Android emulator system images and developer preview system images have been updated for supported Nexus devices (Nexus 5, Nexus 6, Nexus 9 & Nexus Player) to help with your testing.

The Nexus 7 is pointedly absent. Will they even get an OTA update for the final Android M release?

Rangi42··on Marvin Minsky's Homepage
This already is a nice template. Plain text that responds well to zooming by the user; default colors that are easy to read and make links obvious; a few important images that are large enough to see, but don't take up half the screen like some sites' banners. If you prefer white-on-black text and have a user stylesheet for it (which I do), the site responds well to that too, without any nested <div>s or background-image:s complicating things (unlike some). I don't think that HTML5 web fonts or a whitespace-heavy designer template would aid in conveying any of the brief and well-organized information on the page.

See also: http://justinjackson.ca/words.html and http://motherfuckingwebsite.com.

(The only thing I would add to either of those is this bit of CSS: body{max-width:900px;margin:0 auto;} to make it easier to read on wide screens.)

Rangi42··on Capitalists, Arise: We Need to Deal With Income Inequality
The highest one I see is a 94% tax on income over $200,000 in 1945. First of all, that was towards the end of a World War during which we developed an entirely new kind of bomb. Nothing our government is currently doing requires that level of commitment from its citizens. Second, that income bracket in 1945 would be at $2.676 million today [1]. Even the top 0.1% of US incomes today start at just $1.6 million [2]; a tax bracket like the 1945 one would have barely any people in it.

[1]: https://www.wolframalpha.com/input/?i=US%24200000+%281945+US...

[2]: https://en.wikipedia.org/wiki/Affluence_in_the_United_States...

Rangi42··on Rational fiction
Rational fiction does not depend on the entire world being rational, only the main characters. Choosing to make the main characters unusually rational is no worse a sin than making them the "prophesied heroes of destiny," or any of the other special abilities usually given to protagonists. The rest of the world is free to be crazy—many plot points in Methods of Rationality, for example, develop as a result of thinking critically about the canon irrational magical world. (Magic itself isn't irrational, but the lack of characters exploiting overpowered artifacts like Time Turners and the Philosopher's Stone is.)
Rangi42··on In J, functions have inverses (2012)
In J, you can square a vector and get a vector of the squared entries. So "sum under square" really is doing "sqrt(sum(square(vector)))", and more generally "(a under b) x" does "b^-1(a(b(x)))".
Rangi42··on Ex-Googler says she exposed company-wide pay inequality with spreadsheet
An analogy that might help morale about the reverse split: "Instead of each getting eight pizza slices (opening price $0.25, strike price $1), you each get one pie (opening price $2, strike price $8)."
Rangi42··on Machine ethics: The robot’s dilemma
But then, to see what the allow-no-harm rule could accomplish in the face of a moral dilemma, he presented the A-robot with two H-robots wandering into danger simultaneously. Now how would it behave? ... In almost half of the trials, the A-robot went into a helpless dither and let both 'humans' perish.

So the A-robot is vulnerable to the paradox of Buridan's ass ("an ass which, confronted by both food and water must necessarily die of both hunger and thirst while pondering a decision"). In these cases, it can help to add more factors that make one option clearly better (is one human a baby? is one of them suicidal? is one dying of cancer anyway?), but if determining these factors is time-consuming and impractical, it would be better to just flip a coin.

Rangi42··on BASIC in C++
If you #define END as "return(0);}" and put "int main(){" at the bottom of basic.hpp, you can have a complete BASIC program with #include "basic.hpp" at the top as the only indication that it's C++.

    #include "basic.hpp"
    _10: LET X = 1;
    // ...
    _150: END
I think multiple data types could also be added in a way that mostly fits with BASIC syntax. GW-BASIC uses sigil suffixes on variable names to denote their type:[1]

    $  String variable
    %  Integer variable
    !  Single-precision variable (default)
    #  Double-precision variable
Something like this might be possible with unions (e.g. _10: LET X.D = 3.14; _20: LET N.I = 42;), or you can tolerate a few different LET macros (LETS, LETI, LETD).

[1] http://www.antonis.de/qbebooks/gwbasman/chapter%206.html

Rangi42··on Escaping VMware Workstation Through COM1
I disable any hardware in VMware guests that I don't need, like printers, speakers, or USB devices, to avoid exploits like this.
Rangi42··on Second-order logic explained in plain English
Try substituting a particular action like "hit." It becomes easier to imagine:

> If everyone hits everyone who hits them, then everyone is hit by everyone whom they hit.

Or: "If everyone hits back, then everyone gets hit back."

The other example is the same, but with propositions instead of people and "bearing" instead of hitting/unspecified human actions.

Rangi42··on “A Statement with My View on Curtis Yarvin and Strange Loop”
Which is not actually meaningless. Technical features like "root user" or "wheel group of root-capable users" have political implications. From `info su` [0]:

> Sometimes a few of the users try to hold total power over all the rest. For example, in 1984, a few users at the MIT AI lab decided to seize power by changing the operator password on the Twenex system and keeping it secret from everyone else. (I was able to thwart this coup and give power back to the users by patching the kernel, but I wouldn't know how to do that in Unix.)

> However, occasionally the rulers do tell someone. Under the usual `su' mechanism, once someone learns the root password who sympathizes with the ordinary users, he or she can tell the rest. The "wheel group" feature would make this impossible, and thus cement the power of the rulers.

> I'm on the side of the masses, not that of the rulers. If you are used to supporting the bosses and sysadmins in whatever they do, you might find this idea strange at first.

— Richard Stallman

My understanding of Urbit comes mostly from this writeup on Popehat [1] and an initial foray into the documentation of Nock and Hoon. However, the impression that I get of it enabling encrypted, distributed programs, does mirror Yarvin's proposed "Patchwork" system of nation-states [2], in the same way that a single root user mirrors a monarchy, and with analogous pros and cons between the technical and political systems.

[0]: http://unix.stackexchange.com/questions/4460/why-is-debian-n...

[1]: http://popehat.com/2013/12/06/nock-hoon-etc-for-non-vulcans-...

[2]: http://unqualified-reservations.blogspot.com/2008/11/patchwo...

Rangi42··on 97% environmentalist
"If Al Gore were so profoundly afraid of climate change, he wouldn't fly in a private jet or have a huge mansion with massive electrical consumption. Since he does those things, then he's obviously not convinced that human activity affects climate."

Nobody is claiming that climate change is a threat just because Al Gore says so, so the sincerity of his belief is irrelevant. Politicians are not the ones "selling the world" on climate change; they're the ones being persuaded (to varying degrees) by scientific evidence of a man-made threat, and they're in a position of power to do something about it.

As for what happens when politicians don't pay attention to climate change, just look at Florida: http://www.washingtonpost.com/news/morning-mix/wp/2015/03/09... Their senator and governor don't believe global warming exists, and they're already having to deal with rising sea levels. It's the politicians who don't take action that are harming their constituents, not those who do.

Rangi42··on Researchers Find Missing Link Between the Brain and Immune System
How does the discovery that one culture's beliefs about medicine were less accurate than expected, make you think that a different culture's beliefs are more accurate? It's not like eastern and western medicine are binary opposites, where if one is wrong the other must be right. Especially since this inaccuracy was only discovered through careful dissection and observation: what comparable practices did historical eastern medicine use, that should make it any more accurate than the equivalent old western superstitions? If "western" medicine has missed this detail up until now, I highly doubt that "eastern" medicine somehow accounted for it.
Rangi42··on Send more money (in Perl 6)
That makes more sense; I didn't think Perl was as slow as he claimed.

You can even get a similarly-structured program in C with macro abuse and C99's compound literals:

    #include <stdio.h>
    
    #define NUMARGS(...) (sizeof((int[]){__VA_ARGS__}) / sizeof(int))
    #define FOR_EACH_DIGIT(v) for (int v = 0; v < 10; v++)
    #define EXCEPT(v, ...) if (in(v, (int[]){__VA_ARGS__}, NUMARGS(__VA_ARGS__))) continue
    #define FOR_EACH_DIGIT_EXCEPT(v, ...) FOR_EACH_DIGIT(v) { EXCEPT(v, __VA_ARGS__);
    #define TEN(...) ten((int[]){__VA_ARGS__}, NUMARGS(__VA_ARGS__))
    
    int in(int v, int a[], int n) {
        for (int i = 0; i < n; i++) if (a[i] == v) return 1;
        return 0;
    }
    
    int ten(int a[], int n) {
        int v = 0;
        for (int i = 0; i < n; i++) v = v * 10 + a[i];
        return v;
    }
    
    int main() {
        FOR_EACH_DIGIT_EXCEPT(s, 0)
        FOR_EACH_DIGIT_EXCEPT(e, s)
        FOR_EACH_DIGIT_EXCEPT(n, s, e)
        FOR_EACH_DIGIT_EXCEPT(d, s, e, n)
        FOR_EACH_DIGIT_EXCEPT(m, 0, s, e, n, d)
        FOR_EACH_DIGIT_EXCEPT(o, s, e, n, d, m)
        FOR_EACH_DIGIT_EXCEPT(r, s, e, n, d, m, o)
        FOR_EACH_DIGIT_EXCEPT(y, s, e, n, d, m, o, r)
        int send = TEN(s, e, n, d), more = TEN(m, o, r, e), money = TEN(m, o, n, e, y);
        if (send + more == money) printf("%d + %d = %d\n", send, more, money);
        }}}}}}}}
        return 0;
    }
Definitely not idiomatic C, but at least it's fast (0.07 seconds).
Rangi42··on Send more money (in Perl 6)
A straightforward translation of the first program to Python 3 runs in 11 seconds:

    digits = set(range(10))
    
    def choose(choices, fn):
        for value in choices:
            fn(value)
    
    def guard(condition, fn):
        if condition:
            fn()
    
    def ten(*digits):
        return int(''.join(map(str, digits)))
    
    choose(digits - {0}, lambda s:
    choose(digits - {s}, lambda e:
    choose(digits - {s, e}, lambda n:
    choose(digits - {s, e, n}, lambda d:
    choose(digits - {0, s, e, n, d}, lambda m:
    choose(digits - {s, e, n, d, m}, lambda o:
    choose(digits - {s, e, n, d, m, o}, lambda r:
    choose(digits - {s, e, n, d, m, o, r}, lambda y:
    (lambda
    send = ten(s, e, n, d),
    more = ten(m, o, r, e),
    money = ten(m, o, n, e, y):
    guard(send + more == money, lambda:
    print("{} + {} = {}".format(send, more, money))
    ))()))))))))
Rangi42··on Hello, World
I made a table of all four possibilities:

    A_coin  B_coin  A_guess  B_guess
    H       H       ?        ?
    H       T       ?        ?
    T       H       ?        ?
    T       T       ?        ?
Then I tried to fill in the guesses, given that A_guess has to be based on B_coin and vice-versa. After making Alice guess the same as her coin flip, since that's a simple thing to try first, it was clear that Bob had to guess the opposite of his coin flip for each row to have exactly one correct match.
Rangi42··on Easing Functions
I expected that clicking on a easing function would use that function to transition to its detail page. Instead, it uses what looks like easeInOutQuint for all of them.
Rangi42··on Lawyers threaten researcher over key-cloning bug in high-security lock
There is value in doing your legal duty, even if some people think your duty is to do a bad thing. "I was just doing my job" is not considered a sufficient defense of Nazi actions because their actions were so terrible that being legally required to do them does not mitigate that. Threatening legal action, on the other hand, is an ordinary event that can be easily excused as "just what lawyers have to do for their clients."
Rangi42··on Scientists torture QWERTY layout into the wearable/smartwatch space
That screen looks too small for me to reliably input anything except bottom-left and bottom-right corner (1 bit per tap). In the long run it's probably easiest to learn a new input format. Some suggestions:

• Draw a shape with your fingertip on the watch face, and use OCR to tell which character it is.

• Map characters to sequences of simple up/down/left/right strokes, each of which conveys 2 bits of information (maybe include diagonal strokes too for 4 bits per stroke). This could work like Braille's dots or ASCII's bits, with N strokes per character, or use Huffman coding so common characters have shorter sequences. They could even try to match with the characters' shapes, e.g. up+down+up+down = M.

• Tap out Morse code on the watch face and press a physical side button to end the message.

Rangi42··on Piper Pied Imitates HBO’s Silicon Valley and Creates Lossless Image Compression
"The algorithm detects the face and then from there it can compress everything else but the face so that you keep the quality of the face while technically lowering the quality in a way that is not noticeable to the human eye."

That's the exact opposite of lossless compression. It is a creative way to implement lossy compression for a limited subset of images, though.

Rangi42··on Hilbert's Grand JavaScript School (2015 Edition)
Right. A simple example to show that induction does not work to infinity:

    0 < 1
    For any natural n, if n-1 < n, then n < n+1
    (proof: add 1 to both sides of the given inequality)
    By induction, for all natural n, n < n+1
But clearly this does not work for infinity, because ∞-1 = ∞ = ∞+1. So induction proves something about all natural numbers, but ∞ is not a natural number.
Rangi42··on Show HN: A tool that transforms your whole list with just one example
This is a great idea! It didn't behave the way I expected with some URLs as input, though:

    http://example1.org/path/index.html
    http://www.example2.org/path/index.html
    http://www.example3.org/
    https://www.example4.org/a/b/c/d/e/f/g/hijklmnop
The pattern I gave was:

    example1.org, path/index.html
So I expected to get:

    example1.org, path/index.html
    www.example2.org, path/index.html
    www.example3.org, 
    www.example4.org, a/b/c/d/e/f/g/hijklmnop
Instead, I got:

    example1.org, path/index.html
    wwwexample.2, org/path.index
    wwwexample.3, org/.
    wwwexample.4, org/a.b
A few feature requests: allow downloading the output as a text file; show a pseudo-code formula of how transformy interpreted the transformation, like "s/.+:\/\/(.+?)\/(.*)/\1, \2/"; and add support for common arbitrary transformations like "November"↔"NOV"↔"11", or "2"↔"2nd".
Rangi42··on Stop Fearing Artificial Intelligence
Making something intelligent does not automatically give it desires. But as you said, there is every reason to expect that we would build AI to achieve our goals, which means making it (a) desire to achieve a goal we share and (b) intelligent enough to succeed. (This is not anthropomorphizing AI; there's no need to make it feel desire the way we do, it just needs to tend to reach a state where the goal is achieved.)

The danger comes from our inability to accurately define our own desires. There is no doWhatIMean() function. A programmed goal can subtly differ from the one we want so that it passes the obvious test cases but breaks catastrophically in an unusual real-world situation. There's an anecdote[1] about a neural network trained to detect camouflaged tanks (I've also heard of it detecting Soviet versus NATO tanks); it ends up learning to detect objects with shadows, because the tanks were photographed on a sunny day and the non-tanks on an overcast day. Now imagine if the program had been prematurely instructed to attack the camouflaged tanks. You can call this "broken and useless software," but by the time we realize how it's broken it could be too late.

[1]: http://www.j-paine.org/dobbs/neural_net_urban_legends.html

Rangi42··on List of April Fools' Day Announcements
I had already set up our computer to mirror-reverse all websites for today, so ironically com.google looks normal.
Rangi42··on Hijacking is Buffer Overflow (2001)
Analogies are a good spur for creativity, even if they have to be sanity-checked afterward. Someone who didn't already know that cockpits are sealed might consider it by relating hijacking to buffer overflows. Your own analogies both suggest that some way of binding "pilotability" to the actual pilot would be useful -- maybe a retinal scan or DNA check before activating the controls.
← PreviousPage 3 of 5Next →