-= JOEY'S wTf AnarChic BloG =-

I didn't know the right way to blog so I'm doing it the wrong way. At least I finally started one.

~o~   Our code formatting conventions are whack - a cry for tabs and no line wrapping   ~o~

For a few years now I've had a computer capable of displaying more than 80 columns of text. Yet if I resize any of my editors wider than 80 chars, I am rewarded with a pretty right-hand margin of utter blankness.

I dislike wrapping code and text at column 80. I feel it destroys the semantic meaning of the newline \n, as well as throwing up whole load of unneccessary indenting concerns.

To make visual wrapping of unwrapped lines more elegant in my favourite editor, I have patched Vim with breakindent, avoiding the need for that brute gq. (Unfortunately the patch is a big buggy with recent Vim releases.)

I recall KWrite being able to do this well too. Unfortunately Eclipse doesn't offer a wrapped text editor mode... :f Java is an especially extreme case here: with its generics and long meaningful camelbean identifiers, you can quickly lose your code off the edge of the screen even with fairly simple statements.

~o~   Flooring integers in Javascript   ~o~

Investigations suggest that x | 0 is one of the more efficient ways to floor a number in JS (jsperf). I have adopted it because I like its brevity and appearance. But beware! Users of | must remember that its order of precedence is pretty low.

That means pretty much everything on the left and right of the | operator will be swallowed into its two operands (not just the closest operand). Whilst this saves you the trouble of bracketting the LHS, if you want to do more after the operation, then you must bracket the flooring expression to avoid the RHS being swallowed.

If you are creating a string for example, you must use brackets not before the | but around it:

var rnd = Math.random;

var goodColor = 'hsla(' + (360*rnd() | 0) + ',100%,' + (50+rnd()*50 | 0) + '%,' + rnd() + ')';   // Right.

var failColor = 'hsla(' + (360*rnd()) | 0 + ',100%,' + (50+rnd()*50) | 0 + '%,' + rnd() + ')';   // WRONG!

~o~   C preprocessor macros in Coffeescript   ~o~   Today Wed Feb 8 03:40:36 GMT 2012

EDIT: Pup informed me that C macros can accept and re-emit multiple arguments through a single var. This is done by appending an ellipsis .... For example #define LOG(Args...) console.log(Args...)


Today I reluctantly had to acknowledge that I couldn't put multiple statements inside my $ifDev() macro when using it in Coffeescript.

I usually process code like the following through the gcc preprocessor before running it as Javascript. The $ifDev macro decides at compile time whether or not to include the code. But if I try to pass this:

# Expose some vars for debugging, during development builds only:

$ifDev(

	debugStore.topLeftDir = topLeftDir
	debugStore.topRightDir = topRightDir
	debugStore.bottomRightDir = bottomRightDir
	debugStore.bottomLeftDir = bottomLeftDir

)

through coffee, it yields:

general.js:15:212: error: macro "$ifDev" passed 4 arguments, but takes just 1

This isn't really surprising: The only reason I can "use" the macro at all in Coffeescript is because CS interprets it as a function call. The macro isn't actually processed until the Javascript file is generated. (That's why I'm using $ifDev() in the first place, because there's no hope I can use #ifdef DEV in pure Coffescript!)

So ... how do we turn these multiple statements into a single expression, so Coffeescript will accept it as a function parameter?

$ifDev(

	(debugStore.topLeftDir = topLeftDir) &&
	(debugStore.topRightDir = topRightDir) &&
	(debugStore.bottomRightDir = bottomRightDir) &&
	(debugStore.bottomLeftDir = bottomLeftDir)

)

Yep that worked. Mwuhahahaha! The filth lives on...

It is worth noting that each command will only fall through to the next one if the result of the assignment is truthy. In this case with vector values, they always are, but if the values we were assigning were normal numbers, or Strings, null-like values would prevent the later assignments from happening. One workaround for this would be: ( (assignedThing = assignedVal) || true ) && .... This has now become pretty verbose. Can we create another macro to shorten this down?

A neater alternative is simply to use a quick anonymous function macro $fn to create a function wrapping, which will happily accept multiple statements, and call it immediately: $ifDev( $fn( ... )() ) However this is not suitable if you want to declare new vars in the dev block!