Latest articles

GOLD Wiki is Back Up

A few weeks ago I switched this semitwist.com domain from a shitty shared web host (right, as if there's any other kind of shared web host) to a Linode VPS, which is absolutely fantastic in every possible way. Along the way I also switched from the shared-host-mandated Apache to the quite wonderful Nginx.

I spent a great deal of effort ahead of time, via trial runs in a local VM, to make sure the actual switchover went as smoothly and quickly as possible. And it did: Everything went smooth as silk.

Except I completely forgot to take care of the GOLD Wiki. Even in my trial runs. It spent weeks just spitting out a 403 error page. Errrmm...Oops!!

So anyway, I've fixed it up, and the GOLD Wiki is now back up and running again. Please let me know if you find any problems with it. Sorry for my screwup!

Read more


Toaster Style Regulations

Is there some some federal regulation that all toasters sold in the US must be 50's retro? Or are you just not permitted to design a toaster unless you're a die-hard 50's fan?

Don't get me wrong, I think it's awesome you can go buy a toaster that looks like it belongs on the set of Grease. But it would be even more awesome if you could get a quality toaster that didn't.

Read more


Template Primer, In D

While generics have become fairly common in many languages, the similar (but more general) concept of templates are fairly uncommon among languages. As such, many people have only a passing familiarity with them. It doesn't help that the most well-known example of templates, those in C++, have...well...they're earned a reputation for being an advanced concept.

This is unfortunate, because at their core, templates are really both very simple and very powerful. Especially if you use D.

Here's a little template primer I initially wrote in response to a newsgroup post:

A template is just a clean way of generating code instead of manually copy-pasting a bunch of times (which would end up being a maintenance nightmare).

Suppose you have this:

int add(int a, int b) { return a + b; }

That's called, of course, like this:

add(7, 42);

Suppose you then want another version of the same function, but with double instead of int:

double add(double a, double b) { return a + b; }

Called like this:

add(3.14, 5.73);

Now you have two functions that are exactly the same, just with one little thing changed. If you need to modify one function, you'll have to remember to modify the other, too. God help you if it's a really big function and you accidentally make a mistake copying it. It just gets to be a big problem. It violates what we call DRY: "Don't Repeat Yourself".

Some languages, like Java or C#, try to solve this issue by making everything an object (or in dynamic languages, a variant). Then they pass around those "boxed" versions instead. This might be done manually, or it may be automatic via autoboxing or generics. Either way, there's a problem: performance. These boxed types, whether objects or variants, are not free: They require extra time and memory. In same cases, the difference is negligible, but in critical sections it can easily add up. So you have to be careful about where and when you use this form of generic code.

Let's step back into first grade for a minute: Have you ever drawn or painted with stencils? You make one design, once, by cutting it out of paper. Then you can easily draw and redraw the same design with different colors: Just place the stencil on a new piece of paper, choose a color, fill it in, lift the stencil, and boom! Suddenly there's another copy of your design, no matter how intricate, in whatever color variation you want.

Templates are stencils for code. Heck, even outside of code this is true, too: "Template" is just another word for "stencil".

So here's how you make a stencil for an add() function. Just "punch out" whatever you want to change, by making it a template parameter:

// Make a "stencil" template myTemplate(T) { // This is what's inside the "stencil" T add(T a, T b) { return a + b; } }

Notice how the add() function is exactly the same as before, but the ints were changed to T (for "Type").

Now let's stamp down some add() prints:

// The dot in between is because "add" is *inside* the template "myTemplate" myTemplate!(int).add(7, 42); myTemplate!(double).add(3.14, 5.73);

That too, is almost exactly the same as before. I've only added that myTemplate!(int) and the similar myTemplate!(float). The compiler turns those into:

int add(int a, int b) { return a + b; } double add(double a, double b) { return a + b; }

And then calls them:

add(7, 42); add(3.14, 5.73);

Those are exactly the functions we were manually writing before! Not only that, but unlike generics or dynamic types, there's no time or memory overhead, so it's perfectly safe to use this in performance-critical sections!

A technical side-note: Truthfully, there is a small amount of extra memory used simply because we're generating code for another whole function. But that's much less of an issue than it may seem. First of all, a Java-style or dynamic-style "generics" version of the function would involve extra code being generated, too - the extra code to detect and handle the types of the variables at runtime. Secondly, the extra memory here is "per function generated", not "per variable". You could juggle millions of variables in template version, and it still wouldn't increase memory usage. But that's not necessarily true of a non-template "generics" version.

Suppose now we want to use add() with ulong and BigInt, too. Instead of manually copying the function and changing the type, we can just let the compiler copy the function and change the type:

myTemplate!(ulong).add(7, 42); myTemplate!(BigInt).add(BigInt(7), BigInt(42));

The compiler, of course, automatically generates:

ulong add(ulong a, ulong b) { return a + b; } BigInt add(BigInt a, BigInt b) { return a + b; }

And then calls them:

add(7, 42); add(BigInt(7), BigInt(42));

You can also add more stuff to the template:

// A bigger "stencil" template myTemplate(T) { T add(T a, T b) { return a + b; } T mult(T a, T b) { return a * b; } }

So now the compiler will turn this:

myTemplate!(int) myTemplate!(double)

Into this:

int add(int a, int b) { return a + b; } int mult(int a, int b) { return a * b; } double add(double a, double b) { return a + b; } double mult(double a, double b) { return a * b; }

And you can use them like this:

myTemplate!(int).add(7, 42); myTemplate!(double).add(3.14, 5.73); myTemplate!(int).mult(7, 42); myTemplate!(double).mult(3.14, 5.73);

You can put other things inside the template, too, like structs and classes, or even variables:

template anotherTemplate(T, int initialValue) { struct Foo { T value; int someInt = initialValue; } T[] myArray; } // Use the array: anotherTemplate!(string, 5).myArray = ["abc", "def", "g"]; // Declare a variable "myFoo" of type "Foo": // Foo's "value" should be a string // And Foo's "someInt" should start out as 5 anotherTemplate!(string, 5).Foo myFoo; if(myFoo.someInt == 5) myFoo.value = "Hello";

Notice that we've added another parameter to the template this time. But this one's an int, rather than a type! Templates can take any type as a parameter like that. You also use alias (as in template(alias foo) ... ) which will accept any symbol: The name of a type, a variable of any type, a literal, or even another template!

Admittedly, this all gets rather wordy, so D offers some convenient tricks:

Using that myTemplate and anotherTemplate all over is a bit of a bother. Why should we have to? D has a shortcut for making and using templates:

T add(T)(T a, T b) { return a + b; }

That's nothing more than a convenient shortcut for:

template add(T) { T add(T a, T b) { return a + b; } }

Or we can define the struct like:

struct Foo(T, int initialValue) { T value; int someInt = initialValue; }

Which is a convenient shortcut for:

template Foo(T, int initialValue) { struct Foo { T value; int someInt = initialValue; } }

The same trick doesn't work for variables like myArray though (but that will likely get fixed in the future). For now, you'll have to manually write them as:

template myArray(T) { T[] myArray; }

Note that (as was true before) each instance of this template is a different array. So myArray!(int).myArray and myArray!(double).myArray are two different arrays. (If you want a single array that can hold anything, you can just simply make an array of Variants: Variant[] variantArray;)

Here's an even handier trick: Since the name of the template and the "thing" inside the template is the same, you don't have to repeat their names (The technical term for this is an "eponymous template"). To use them, all you have to write is:

add!int(7, 42); add!double(3.14, 5.73); add!BigInt(BigInt(7), BigInt(42)); mult!int(7, 42); mult!double(3.14, 5.73); mult!BigInt(BigInt(7), BigInt(42)); myArray!string = ["abc", "def", "g"]; myArray!int = [1, 2, 3]; myArray!double = [1.5, 2.70, 3.14]; Foo!(string, 5) myFoo; if(myFoo.someInt == 5) myFoo.value = "Hello"; Foo!(float, 1) bar; if(bar.someInt == 1) bar.value = 3.14;

This, in fact, is how templates are usually used in D. Looks pretty simple, doesn't it? Barely any different from the non-template versions. That's because it really is simple, as it should be. After all, they're just stamps.

And there's yet one more frequently used convenience: A special thing D has called IFTI: Implicit Function Template Instantiation. It sounds intimidating, but again, it's really very simple. It just means D lets you call the functions above like this:

add(7, 42); add(3.14, 5.73); add(BigInt(7), BigInt(42)); mult(7, 42); mult(3.14, 5.73); mult(BigInt(7), BigInt(42));

Look ma! No types!

  • D already knows that 7 and 43 are int, so it automatically uses the add!int version.
  • D already knows that 3.14 and 5.73 are double, so it automatically uses the add!double version.
  • D already knows that BigInt(7) and BigInt(42) are BigInt, so it automatically uses the add!BigInt version.

Now these really are identical to using the old non-template versions!

So ultimately, if we start with this copy-paste mess:

int add(int a, int b) { return a + b; } double add(double a, double b) { return a + b; } add(7, 42); add(3.14, 5.73); add(BigInt(7), BigInt(42)); // ERROR! You have to write a BigInt version *manually*!

We can turn it into a convenient "stencil" with just a trivial little change:

T add(T)(T a, T b) { return a + b; } add(7, 42); add(3.14, 5.73); add(BigInt(7), BigInt(42)); add( /+ anything else! +/ );

That will automatically stamp out any add() function you need, when you need it. And we can do the same for structs, classes and variables!

For more details on templates and D, check out:

UPDATE (2012-05-12): Added a couple paragraphs about the non-template approaches used in most languages, basic syntax highlighting, and a few minor updates and wording tweaks.

Read more


The Perfect Browser is Easy! Yet It Still Doesn't Exist...

All I want is a modern Firefox with a FF2+Winestripe[1] UI. You know: Modern efficiency, reliability and standards-compliance, but with a classic UI. A UI that doesn't even try to ape the idiotic look and feel of the world's ugliest web browser: Chrome.

Is that really so hard to ask for?

Apparently so. It would seem that if I want an efficient, reliable, "modern-standards" browser, I'm required to take it with the god-awful ideas that are "modern browser UI design".

Fuck that shit.

But let me be clear: I really don't mind if you like those "modern" browser UIs. That's fine, whatever floats your boat. What the hell do I care? Nothing.

Interestingly though, I've noticed that people do seem to care very much what browser I use. I bet that means I'm special and adored by everyone. Hmm, or maybe it's because unlike those people, I've chosen the wrong browser: Firefox 2.

Yup, and I'm a web developer, too. A web developer with an "ancient" browser.

I don't give a rat's ass what browser you use. It's none of my business. But judging from my past experiences on message boards, chances are your nuts are chafing right now over the knowledge that I use Firefox 2, the "wrong" browser.

That's good. Let those balls chafe for a moment...But consider this proposal before you reach for that "Bitch that someone on the Internet made the wrong choice" button (aka "Submit comment"):

I'd love to just jump into the code myself and put a proper UI back in. And it's fully been my intent to do so. But my plate, honestly, is overflowing. I just haven't had the time and I won't for the foreseeable future. There are, however, people who are already neck-deep in web browser source code. People who may even be paid to do so. People who work at Mozilla, for example.

So, since my choice of browser is so offensively wrong, how about enticing me to join your collective by tossing in a "Non-trendy UI" option? Hell, even call it "Old Fart UI", as long as it's there: No toolbar minimalism, no unified forward/back dropdown, no "smart" this or "smart" that, no AwfulBar look or feel, no non-native window skinning (or misuse of buttons as tabs *couch*Opera*cough*)...And most of all, NO asinine "What the hell is wrong with you dumb trolls who refuse to love our obviously and objectively superior new UI?" bullshit.

Modern technology, classic UI.

That's all I ask. That's not such a terrible request, is it?

If you're wonderful enough to do that for me, I'll happily jump on board your modernism train. Heck, once there, I'll even apply some salve (figuratively, of course - don't get too excited!). Sounds like a great deal to me, for both sides.

But wait, there's more!

I'm not gonna shut the others out from this deal-of-a-lifetime: Mozilla may have a leg up, but I'm game for some ship-jumping with anyone who can close the gap. Simply keep in mind that I'll hold onto FF2 well into the 2060's before I give up the following plugins:

Those are absolute minimum. I won't even consider your browser without those. Also mandatory is a complete lack of stealth/piggyback/background software (ex: I'll never install Chrome as long as SRWare Iron exists). Extra brownie points if I don't have to give up these:

So how 'bout it? Fair enough? Excellent!

[1] Winestripe: A FF1.x theme for FF2 that makes FF2 look non-ugly. Doesn't work on FF3 and up. I'm talking the real one here. The newer remakes just don't fit the bill: There's too many changes in FF3+ they still fail to revert.

Read more


Goldie Parsing System v0.8 - Support DMD 2.058

A minor update to Goldie, v0.8, is now released.

Goldie is a series of open-source parsing tools, including an optional D programming language library called GoldieLib. Goldie is compatible with GOLD Parser Builder and can be used either together with it, or as an alternative to it.

In this version:

(Tested to work on: DMD 2.052 - DMD 2.058, and partially DMD 2.057 as described here - but see this note regarding RDMD)

  • Added support for DMD 2.058.
  • Calculator samples now require at least DMD 2.054.
  • StaticLang: Static-style languages generate a proper compile-time error when used with a different version of Goldie than the one they were created with.
  • Now uses SemiTwist D Tools tag 'goldie-v0.8'.

Links:

Read more


"Gay" has TWO meanings, really!!

Consider things like Partridge Family, Brady Bunch, or The Sound of Music. Now, somebody refers to one of those with "That's really gay!" I bet you're jerking your knee right now over some notion of sexual discrimination.

Anyone who isn't a complete moron is aware the word "gay" has two meanings:

  1. Happy (albeit altered in modern times to "disturbingly ultra-happy")
  2. Homosexual

As an exercise to those of you who read "That's really gay!" as referring to homosexuality: Point out the homosexuality in Partridge Family, Brady Bunch, and The Sound of Music. (I'll give you a cookie when you find it.)

Obviously there is none. But they are extremely well-known for depicting "happy, happy, happy!" to a freakish degree.

Therefore, when someone uses "That's gay" to refer to those or other such shows, music, etc., there are two possibilities:

  1. They're calling it "disturbingly ultra-happy" and making zero reference to homosexuality.
  2. They're a complete and utter moron who is so unbelievably stupid they can't even comprehend what "homosexuality" actually is.

Bottom line:

  • If you consider "That's gay" to always refer to homosexuality, you're a moron.
  • If you use "That's gay" to refer to things that obviously aren't homosexual but still intend it to be a homosexuality reference, you're an even bigger moron.
The more you know...

Read more