Archive for the ‘Cool’ Category

I am so sorry.

Thursday, January 24th, 2013

Yesterday, I made a mistake. Without thinking, I made a post on Hacker News in response to some other posts that other Hacker Newsers made, and I want to apologize.

I value blending in to society. I value making the pretense of caring about others. I value shutting the fuck up instead of arguing with retards about all the stupid retarded shit that happens in Hacker News comment threads, who should know better than to share their inane opinions about shit that happens in the universe and the open source communities. Yesterday, I went against these principles and posted on Hacker News, and now I’m ashamed. There are constructive ways to talk about subject matter, but that’s irrelevant on Hacker News because there’s always another moron who’ll reply to you in a way that betrays total incomprehension of what you were saying. I will be thinking about avoiding these

Okay, this parody is getting lame. So anyway, fuck this guy: http://programmingtour.blogspot.com/2013/01/im-sorry.html

He’s so sorry that people found out he’s a complete asshole. He was pretending to be nice for years and years on the internet, and now everybody knows. Everybody knows that he’s an asshole!

Let’s hate him forever.

Here’s a Hacker News thread about that apology. http://news.ycombinator.com/item?id=5107264 Specifically, read the posts by __cle.

Military-Grade Encryption Here We Go

Saturday, April 21st, 2012

Check out http://noplaintext.com/. It promises military-grade encryption, in the browser.

Here’s a fun game to play. Before visiting, try to guess what mistakes they made.

Then visit the site, and when you read exactly what they do, try to guess what mistakes they made.

Then look at the code and see what mistakes they made.

Then see what you missed (and what I missed).

So far:
- The encryption key is generated with 47.6 bits of entropy.
- It’s generated using Math.random().
- There is no message authentication. The server can flip individual bits within the message.
- Obviously we have to trust noplaintext.com to send us an uncompromised web page.
- It links to google-analytics, so we also have to trust the Google analytics people.
- It links directly to https://crypto-js.googlecode.com/files/2.5.3-crypto-sha1-hma…, so we also have to trust the crypto-js maintainer, and the googlecode.com people.
- The whole system depends on being able to share the URL securely. But if you can do that, you could have just sent the message securely over that channel.

Stupid Thinkpad Zealots

Friday, April 20th, 2012

There are some pictures out showing Thinkpads that have the chiclet-style keyboard previously seen on the X120e and X1. Now the X230, T430, T530, and W530 will have these chiclet-style keyboards instead of the previous generation of scissor-switch.

For example, see this thread: X230 picture – Lenovo Community

I am making this post to inform you that these people are completely retarded, of course.

What they’re really lamenting is their newfound inability too feel superior to other laptop users. Most people who have actually used the chiclet keyboard know that it’s just as good as, if not better than, the scissor-switch keyboard — for example, it’s more difficult for hair and dust to get lost between the keys. Also the mechanism is certainly less fragile, considering how fragile the scissor-switches are.

If you’re butthurt over the change of keyboard to something more affordable and reliable that doesn’t sacrifice key-press feel and maybe even improves on it, maybe you should look for other ways to feel superior to other computer users. You still have the smugness of the trackpoint (even though I’m using a Sony Vaio that has a superior pointing stuck), and also your laptop puts out a really nice and clean VGA signal, not one of those disgusting impure VGA signals produced by the otherbranded trash.

Another option is to get a Panasonic Let’s Note SX. It has a 1600×900 12.1″ screen or 1280×800 in some configs, so you can’t complain about resolution. It has this circular trackpad which people regard as stupid until they stop regarding it and start using it, at which point they know it’s better than any other mouse device. It has a built-in DVD drive IN THE PALMREST and it is lighter and allegedly has much better battery life than an X220. The keyboard is not some craptacular chiclet keyboard, in fact it has less row height than the Thinkpad keyboard, which is nice for your fingers, unless you’re too fat-fingered to hit the shorter keys. It’s even more durable than the Thinkpad, that’s right, your “magnesium roll cage” machine is not actually more durable than everything else, you whiny little shit. I don’t have one, because the base model costs $2600 and I’m not an idiot and I already have too many laptops. But you could have one, and then your laptop would be better than other people’s, and you’d be better than other people for knowing it’s better. Are you going to put a price on your own superiority?

Music

Sunday, March 4th, 2012

Programming music is annoying. The question of how to combine ideas of notes and instruments and waveforms into a song is probably more interesting than the art of concatenating strings into an HTML document. At first I thought I’d make things by combining arrays of samples using some array-of-samples-combiners and objects with this interface:

struct Music {
    // dumps [beg, end) of our sample region to out.
    virtual void Dump(vector<pair<int16_t, int16_t> >& out,
                      int32_t beg, int32_t end) = 0;
    // the length of this musical passage, in 1/44100ths of a second.
    virtual int32_t Length() = 0;
};

The problem with that is you can’t just tweak the shape of some sound without e.g. knowing how it’s normalized and such. Also it’s not the right toolkit for playing a note out loud.

Also it’s stereo. Do we want to support mono tracks?

So now I’m going with having some primitive sounds that have amplitude 1.0, frequency 1.0, and manipulators that can screw around with them, and then things can parameterize them into notes somehow. More details will be present within the next 13 hours.

void mainers

Friday, November 18th, 2011

There exists this disease on the Internet which is the set of people who react badly to things such as this:

void main() {
    printf("Hello, world!\n");
}

They’ll flare their hoods and puff out, “main should be declared to return int and not void because that’s what the C++ standard says, your code is non-standard and thus it’s bad!” Well gee, it would be just horrid if somebody porting the code had to change the return value of one function.

The problem with you, if you’re one of these people, is that you have nothing better to say.  This is the sort of thing where you sit in your chair at your computer like the little smugnesty you are and find some petty fault in the way other people do things.  Guess what: you’re unimportant and you don’t matter.  You should find something more important to bitch about, like problems with people’s code that actually matter.  Or problems with people bitching about code that doesn’t matter.

Speculation

Saturday, March 5th, 2011

From the wipe(1) man page:

I hereby speculate that harddisks can use the spare remapping area to secretly make copies of your data. Rising totalitarianism makes this almost a certitude. It is quite straightforward to implement some simple filtering schemes that would copy potentially interesting data. Better, a harddisk can probably detect that a given file is being wiped, and silently make a copy of it, while wiping the original as instructed.

Recovering such data is probably easily done with secret IDE/SCSI commands. My guess is that there are agreements between harddisk manufac‐ turers and government agencies. Well-funded mafia hackers should then be able to find those secret commands too.

ANTILISP

Sunday, January 9th, 2011

I’ve started working on a non-toy interpreted programming language.

http://antilisp.com/

Progress updates will be made over there, occasionally I might mirror worthy entries here.  (Most updates are gonna be like, “Oh, I got this and this done today,” which gets old.)

Post #572

Saturday, December 4th, 2010

I’m following the rule of posting one post per day, and unfortunately I forgot to schedule my post yesterday to be published at 5 AM this morning.  This means I need to write a post before midnight, today.

I write today to inform you of my disgust for the disgust I have of people who ask how to learn how to program.  I find myself thinking, “Gee, why don’t you just get a fucking computer and start programming?”  Download Q-BASIC and learn that way; it was good enough for me! There’s the whole I spent my childhood programming in TI-BASIC where we didn’t have functions and we evaluated subroutines by setting some variables and running another program, or was it Reverse Polish Lisp where we didn’t have variables? What a fun attitude to take.  But then, I remember getting introduced to C++ in one high school summer and I Just Didn’t Get It.  I asked somebody how to make an array (a feature I had picked up from Q-BASIC) and the response I got was, “Do you want to put it on the stack, or on the heap?”  At my look of puzzlement, the person decided I was an idiot for not knowing what a stack or heap was.

I’m sure he was thinking, “Stupid kid, go play with your toy languages.”  He was my age.

Looking back, that was a more innocent time.  I only cared about doing things, and I didn’t really care how I got those things done.  It didn’t matter that I couldn’t pass functions to functions in Q-BASIC or pass parameters to functions in TI-BASIC, all that mattered was that I get RACE or SIERPINS working as fast as I could get it.  This was with a screen that fit 8 rows and 16 columns of text.

And here I am now with a 1600×768 LCD feeling uncomfortable because it’s only 8 inches long.

So where were we.  Somebody comes asking about how to learn to program, and I get uppity about it?  Oh gosh, how could they not spend their time toiling the way I did?  To have the temerity of asking for advice? Oh my.  And they’re going to start with PHP?  The horror!  They should use Haskell and learn about abstractions!

No wait, that’s all bullshit.  That’s all some horrible attitude that has infected me and chewed up the newbie-loving part of my conscience.  It’s like I try to make myself feel special, like some kind of superior being, for knowing about monads or having good taste in software design.

Conclusion

I am a bad person.

The Worst Thing

Friday, December 3rd, 2010

The worst thing is when you get C++ constructors that look like this:

blah::blah(int block_id, size_t size, buffer_t *buf)
    : block_id(block_id), size(size), buf(buf) { }

This works fine — the buf variable gets initialized with the function parameter — but here’s what doesn’t work.

blah::blah(int block_id, size_t size, buffer_t *buff)
    : block_id(block_id), size(size), buf(buf) { }

Now buf or buff is misspelled, and we’re trying to implement buf with itself! Sure, Valgrind will catch this error, but still.

If you don’t end your member variable names with underscores, then end your parameter names with them.

Thank you.

P.S. Did you know that clock_gettime(CLOCK_MONOTONIC, ___) doesn’t perform a system call? Neither does time(NULL), at least on up-to-date Linux. Anyway, I didn’t know this. CLOCK_MONOTONIC is still absurdly slow. It takes 1300 nanoseconds the first time you call it, and a few hundred after that. Using the rdtsc instruction in an inline function gets you to 13 ns between calls. This is on a 2.3 GHz system.

(The timings of CLOCK_MONOTONIC were measured by calling it twice in a row, and then by calling it twice in a row again. Similarly for rdtsc. So if anything, the first call to CLOCK_MONOTONIC may be slower than I reported, if there is any cost prior to the rdtsc instruction.)

Fluff on asynchronous callbacks.

Thursday, December 2nd, 2010
One bad programming technique is that of asynchronous code designed
such that it always calls the callback.  That is, imagine a method as
follows:

    struct io_cb {
        virtual void done(void *buf) = 0;
    };

    void read(off64_t offset, off64_t len, io_cb *cb) {

        // If the buf is immediately available, calls cb->done(buf)
	// and then returns, if not, returns and later calls cb when
	// the buf becomes available.

    }

The problem with this sort of API is that if your bufs are all
immediately available, you can get unbounded mutual recursion.

Instead, here's a better API.

    struct tramp {
        virtual tramp *continue();
	void loopout() {
            tramp *t = this;
	    while ((t = t->continue())) { }
	}
    };

    struct io_cb : public tramp {
        void *buf;
    };

    struct nop : public tramp {
        void continue() {
            delete this;
            return NULL;
        }
    };

    tramp *read(off64_t offset, off64_t len, io_cb *cb) {
        if (/* the buffer is immediately available */) {
            cb->buf = /* the buffer */;
	    return cb;
	} else {
	    /* take ownership of cb and save it for later;
	       start the asynchronous operation. */
	    return new nop();
	}
    }

Then, to call it:

    read(off, 4096, my_callback)->loopout();

Use the right kind of smart pointers to make this better.  Then you
can also add debug variables and assertions in the destructor to make
sure the return value of a tramp never gets ignored.

Another way to do this is to just return a bool or a value that can be
NULL.

    void *read(off64_t offset, off64_t len, io_cb *cb) {
        if (/* the buffer is immediately available */) {
	    return /* the buffer */;
        } else {
            /* take ownership of cb and save it for later,
	       start the asynchronous operation. */
	    return NULL;
	}
    }

Then calling that looks like this:

    void *buf = read(off, 4096, my_callback);
    if (buf)
        my_callback->done(buf);

That gets annoying and makes you want to do the first technique
mentioned, which is bad.