Saturday, 1 March 2008

small, pythonic lisp

Grab it here.

It's < 256 LOC toy lisp. Nothing super-fancy. If you don't count unit tests and Guido's mm.py it's even < 128 LOC.

It's quite pythonic. When you write eval in LISP it's just a big cond. It translates directly to if/elif/elif/... which doesn't look good. I used dict of functions instead, which looks better in my eyes. Uses as many Python features as possible. Python functions, python lists. etc.

Talking about Python and lisp lists:

class slist(object):
class iterator(object):
def __init__(self, lst):
self.lst = lst
def next(self):
if self.lst:
result = self.lst.car
self.lst = self.lst.cdr
return result
else: raise StopIteration

def __iter__(self):
return slist.iterator(self)

def __init__(self, a, b=None):
self.car = a
self.cdr = b

def __str__(self):
return '(%s)' % ' '.join(str(elem) for elem in self)

list_123 = slist(1, slist(2, slist(3)))
a, b, c = list_123

Yes, this is just a linked list, not a true scheme cons, since it doesn't support improper lists, I posted it just to show how Python iterators are neat.

Friday, 29 February 2008

Lap year's WTF

Well, we all know phpBB is evil. Html code it generates makes you sick. It's a great example of spaghetti design antipattern. And it's written in PHP.

Today (it's 29th February) many phpBB by Przemo forums have blown. It's because of lap year and their "whose birthday is it" function.

Warning. Clicking link below may even make you vomit.
I'm ugly, think again

Yes, they didn't use standard date("L"), yes they did their own calculations (using sqrt?!?), and yes, they f*ck*d it badly. Awful switch full of magic numbers (hello, PHP is a junk, but it has loops and arrays) is just a minor ugliness.

Saturday, 9 February 2008

int *(*(*(*b)())[10])();

I've just read Terence Parr's post titled "How To Read C Declarations". The quoted "Golden Rule" makes reading declarations really easy even for a drunk ape, but it's one of the kind I dislike. It gives you some "magical" steps to follow (here are the same rules stated more verbosely in an awful, BASIC-ish GOTO-step-N manner) with no explanation why this way, no another.

Here is the missing explanation:

Declaration reflects how you use declared expression (how you get the value of it), so in int tab[]; tab is an array (you index it) of integers. int (*tab)[]; is a pointer to an array (you dereference it, then index). int *(tab[]); is an array of pointers — you have to index it, then dereference.

How about int *tab[]? You have to know operator precedence

It's not that hard as in looks like. In our case the rule of thumb is: "Postfix binds stronger than prefix.", so you read int *tab[] as array of pointers. "Postfix binds stronger than prefix" is the reason why you look right, then left, in "Golden rule".

Easy, isn't it? Now you know this post's title reads pointer to the function returning pointer to an array of pointers to functions returning pointers to integers. 10 is redundant in this case. (It's no 5 from here, I'm so lazy...).

Of course you'll find out that the Golden rule is an obvious result of sentences above. It's convinient to read declarations that way, but IMO it's very bad to actually think about declarations only in terms of now jump out of the parenthesis.

Friday, 1 February 2008

Vim stuff

Vim is great, but quite hard to master. My experience is that there usually is a lot of "how did you do that?" when working with another vimmer. There goes a random list of some useful commands I taught (or learned) recently:

^rX in command and insert mode.
Puts the content of X register. Typical use case: select something with * and then :%s/^r//new stuff/g

punctuation: ; and ,
repeats last tTfF motion, like everyone's favourite dot repeats last command

rectangle visual mode
^v or quadruple1 click. Often easier and faster, than macros

macros
q. Everyone know them :help q

^o
Jumps intro normal mode for one command. Typical usecase: editing middle of the line ^oo.

^v any_key in insert and command mode
Puts the Vim representation for that key. Useful for editing .vimrc

J in normal mode
joins current line and next line

^a ^x in normal mode
increment/decrement a number

& and \1, \2...
in to part of substitution

"*
X11 clipboard

^p ^n and ^xlot_of_keys like ^xf
completions

autocmds in your .vimrc
see .vimrc examples below

not a command: Wombat
My text is brilliant
My vim is pure.
I saw a Wombat.
Of that I'm sure.
[...]

You're beautiful. You're beautiful.
You're beautiful, it's true.




Some macros from my .vimrc that I found very useful:

" done with current line
inoremap <c-cr> <c-o&ht;o

"XML, HTML, JSP
autocmd FileType xml,html,xhtml,jsp,htmldjango inoremap <C-b> <Esc>"tciw<<C-o>"tp><CR></<C-o>"tp><Esc>O
autocmd FileType xml,html,xhtml,jsp,htmldjango inoremap <C-a> <Esc>"tciw<></><Esc>"tPF>"tPla
autocmd FileType xml,html,xhtml,jsp,htmldjango inoremap <C-s> <ESC>"tciw</><ESC>h"tPa<Space><Space><Left>


Side note: python syntaxfile file (at least in vim 7.0 in my SuSE) seems to be a little outdated:
autocmd FileType python syn keyword Constant True False None
autocmd FileType python syn keyword Keyword with


Meta tip:
type :help one_or_two_random_keys from time to time. prefix with i_ for insert mode stuff.


1 - yes. QUAD-ruple. Click, click, click, click. Four clicks in a row %-| . Open Office does have quadruple click too. Who uses mouse, anyway...

Monday, 14 January 2008

DSL for CppUnit tests

It's amazing what activities can one invent, just to have something to do but learn...
I've just written an external DSL to ease writing CppUnit tests. It's not finished, but it works.

There is one thing I particularly hate about CppUnit: you have to name every test in fixture at least twice - once when it's created, and another time when it's added to the suite. OK, it's C++, we don't have reflection to do this stuff automatically, preprocessor is to dumb to fix it too... but it still sucks. It's repetitive and error prone. And you can end with tests that are never called, because you have forgotten to add them to suite.

Blah. I think I'm clear.

I wanted to have something simple - generated code should be very similar to our source - tests bodies themselves should be just copied intro right places and so on. No full-blown C++ parsers... no C++ parser at all. Just something that is a little more than preprocessor macros.

And here it goes:

@includeHeaders

@beginFixture TestSum
Sum *sum;
@setUp {
sum = new Sum();
}
@tearDown {
delete sum;
}
@test "empty sum of nothing should be zero" {
CPPUNIT_ASSERT_EQUAL(0, sum->getResult());
}
@test "simple sum of 1+2+3" {
sum->add(1);
sum->add(2);
sum->add(3);
CPPUNIT_ASSERT_EQUAL(6, sum->getResult());
}
@endFixture

translates to

#include <cppunit/TestCase.h>
#include <cppunit/extensions/HelperMacros.h>

class TestSum: public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE( TestSum );
CPPUNIT_TEST( empty_sum_of_nothing_should_be_zero );
CPPUNIT_TEST( simple_sum_of_1_2_3 );
CPPUNIT_TEST_SUITE_END();

public:
Sum *sum;
void setUp() {
sum = new Sum();
}
void tearDown() {
delete sum;
}
void empty_sum_of_nothing_should_be_zero() {
CPPUNIT_ASSERT_EQUAL(0, sum->getResult());
}
void simple_sum_of_1_2_3() {
sum->add(1);
sum->add(2);
sum->add(3);
CPPUNIT_ASSERT_EQUAL(6, sum->getResult());
}
};

Simple as that.

Mercurial repo.

Time to finish this longish post before it took me more time to blog about it, than to actually write it...
cut!
My first post on my first blog is finished. Applause!