Monday, November 29, 2010

Thursday, November 11, 2010

I had it turned on just to see if I could ever generate some spare change from my minor musings, and in the some 3 years I've had it on I think I've accrued no more than $20 revenue.

The unfortunate thing is each time I change countries, Google tells me I have to cancel my account and re-open a new one. Yet without a balance over $100, they won't bother sending you any money, and whatever it is you made just reverts to their general coffer.

The bottom line is, unless you intend to pursue blogging as a (part-time) job, there is no point whatsoever in having adsense turned on -- it just makes your blog look petty.

Monday, November 1, 2010

I've read a couple on-line arguments about whether to have children or not; how the decision affects one's quality of life and whether or not there are moral implications to the decision.

Some felt children cause an undesirable revolution in one's entire lifestyle; others felt a life without children was shallow and unfulfilling. The most interesting part of the discussion, I felt, was the observation that people (couples) who had decided not to have children often felt they were somehow judged to be "selfish" for their decision, and countered that what was really selfish was insisting on bringing a bunch of new "mini-me"s into an already overcrowded world. What was interesting was I somehow agreed that there was some part of being electively childless that felt selfish, but couldn't immediately put my finger on why.

My choice is obvious. I have a daughter, and couldn't imagine a life without my family. However, I think if you really feel you don't want children, you shouldn't have some just to satisfy some reactionary outside pressure to conform; that's not doing anyone long-term good. So why then do I feel there's something "off" about couples choosing to be childless?

"Selfish" means making or taking advantage for one's own benefit. If anything, those who insist on making mini copies of themselves to have run about the world could be considered "selfish". Childless couples on the other hand are "self-centred": principally considering one's own point of view. They seek to avoid the sacrifice to their lifestyle involved in having kids.

Society is primarily defined as a network of responsibilities owed to one another that knits us together and makes us stronger as a group than as individuals. And responsibility is primarily a matter of sacrificing our individual desires to ensure our responsibility is met.

We begin this process from birth, where our most immediate need is immediately translated into a responsibility for someone else to satisfy -- our consciousness is only capable of comprehending and expressing our own self-need. As we grow older, we learn about sharing (suppressing our need for acquisition and ownership for the benefit of others), chores (suppressing our free playtime for necessary duties), discipline (suppressing immediate gratification for delayed gratification), work (exchange time in unrewarding tasks for money) etc. We learn about family (before our selves), make friends (before our family), have girlfriends (before our friends), get married (one mate before all others), raise kids (before our mate) and so on. Our entire lives are spent learning how to strip a piece of our soul and use it as mortar for the future of our shared society. And when children grow up, they will take the foundation we left them, and start the cycle over again.

In the end, this is what people instinctively react to: electively childless couples have decided contribute to and enjoy the benefits of present society, but have abstained from helping build our common future. They are not dedicating the next 20 years of their life energy making sure the next generation is healthy and well adjusted; they're dissipating it for their own benefit.

I can guarantee you, no one looks at a childless couple who invents the cure for cancer as "selfish". No one thinks the childless couple who volunteers to teach children in Africa are "selfish". But maybe, just maybe, if you're a hipster spending your dual income on lattes, studio apartments, and purse-sized "dogs", someone might look down their nose at you when they stayed awake all night wiping the snot from a sick child's nose. And I don't think the genetic origination of said child matters; only that the child represents the next generation of our society.

Thursday, August 12, 2010

Friday, July 16, 2010

An opinion offered by an actual woman in technology (eponymously known as "Jessica Boxer"; taken from a blog post I otherwise disagree with).

Firstly, I think the main reason women are less inclined to work in tech is because, as a general rule, women are much more sociable than men. I am sure you are aware of the good, evolutionary reasons why that is so. I believe this is more than a nurture thing, I think it is also to do with the way their brains are wired, which is notably different than the way men are wired. (This isn’t some handwavy opinion, it is a physiological fact.)

Because they are more social, they tend to want to do things that involve sociability more. The scientist or programmer tends to be a lone wolf, spending most of his time talking to his computer or test tube, rather than interacting with people. This fits in considerably less well with the preferences of women. it is also why women who are in computing tend to drift toward the more social jobs, such as testing, tech support, management and GUI design.

Secondly, because computing has tended to be dominated by males, the systems and processes that are in place tend to be more male oriented. for example, design meetings tend to be confrontational rather than consensus oriented, aesthetic is eschewed for functional, individual preferred to group. None of these are intrinsic properties of programming, neither are death marches for that matter. But the dominant class has set the system to their preferences, and so there is a feedback loop that decreases the attractiveness of programming to the less dominant group.

Friday, June 4, 2010

I never really knew what "self esteem" was supposed to mean. It always seemed to translate into "I think I'm better than others", and I regularly failed to see why that would be a good idea to be teaching that to kids. I guess this excellent discussion of status makes it clear that "better than others" is precisely what self esteem is.

I've often felt that modern society is somehow unhappier than a perceived simpler past, and this article helps explain why I feel so: If status is self-esteem, and status is relative, then how we feel about ourselves is relative to what we have. And modern humans have a lot.

We feel rewarded when we gain some relative improvement in our lives. In a simpler world, there is a more direct line to incremental status improvements. Being the best in your village means besting only dozens of challengers for esteem.

In a world where the simple achievements are common-place, we seek improving status in ever more circuitous, arduous routes. Even grand accomplishments seem hollow when you're comparing yourself to the global population. Even scaling the worlds highest mountain is blase -- a friend's brother is doing it right now!

This is what makes buddhist philosophy more relevant today than ever, because it teaches us to find "status" in the things that are already around us, and quit searching out "hollow" status in harmful pursuits. Given our current pace of exploitation, what was once the "high-status" of possessing a clean source of water may yet come back in fashion due to scarcity.

"Status" is a thing of our creation, and we can choose to find it where we will; if we can tame a relentless nature.

Saturday, May 29, 2010

After struggling with Boost.Spirit for a couple days, I've finally gotten my head around the parser component (Qi) enough I thought I might share.

Most of the trouble getting things working is the same trouble one gets from most template-based libraries often found in Boost: since template programming is not based on a solid methodology (such as OO) that one can build intuition upon -- rather on C++ tricks or compile-time side effects, and the errors the compiler issues are nigh unreadable, when something goes wrong it's hard to know where or why.

However Spirit is quite redeemable because frankly I'm not sure how many ad-hoc parsers I wish to write in my life-time. Spirit is a recursive descent parser, where the grammar is specified directly in C++, using C++ operators to build the parser. This means Spirit could be a quick and simple way to add parsing to your projects without a lot of effort. Spirit is limited to LL(k) grammars, but most grammars one encounters are fairly simple, so this fits the bill quite ably.

There is some good documentation and examples on the Boost site, so I won't be writing a tutorial. Instead I'll try to give you advice and help you conceptualize what's going on, so you have an easier time reading the tutorials.

Now using the grammar operators, we can recognize the following statement:

{0xbeef}

as 48879 with the following grammar:

char_('{') >> string("0x") >> hex >> char_('}')

If we had a list of such bracketed numbers, we could place a Kleene star in front[2] of the whole expression to recognize the list. The full detail of built-in parsers and grammar operators can be found in the documentation.

Spirit has another interesting idea called a skip parser. Basically this is what's used to help tokenize the input by deciding what is not semantically relevant. Usually the skip parser skips space and comments.

For example, if comments are "//-to-eol" delimited, the following may be your skip grammar:

ascii::space | "//" >> *(char_ - eol) >> eol;

So now we have handled white-space and comments, and recognized our number, how do we read 48879 into our program?

Each parser has an associated "attribute" that, in the case of terminals, is easy to deduce. For char_ it is char, for int_ and hex it is int, in the case of *double_ it is std::vector<double>, and so on.

Wait, how did that vector get in there? Good question. You see, the operator not only joins parsers together in a new modified parser, it joins the attributes together into a new modified type. For example if parser p has attribute a of type A, then parser *p has an attribute of type std::vector<A>

Each operator has its own modifier, and this is where things start to get messy. If you have built up recursively a fairly large grammar, the attribute type of the final grammar can be a mammoth unwieldy beast. This type (whatever huge amalgamation it may have turned out to be) is your output AST. Even with simplifying rules, this is a bit of an unwieldy representation.

The documentation tells you define your own sub-rules and sub-grammars so you can get a handle on the complexity, but my recommendation for non-trivial grammars is to skip this automatic attribute generation entirely, and use semantic actions to manually construct your own custom intermediate representation. The result will be more verbose boiler-plate code, but a cleaner representation and ultimately more readable, understandable code.

Quite simply, a semantic action is a callable object which is executed on successful recognition of a token. The parameter of the call is the attribute type. Since you are attaching functions to parsers at a low level, we don't have a problem with huge aggregate types.

Going back to our original example, given the following grammar:

*('{' >> lit("0x") >> hex >> '}'))

and the following test input:

// my data!{0xabba}{0xfeed}{0xbeef}

if we add a semantic action ("got_it()") as follows:

std::list<int> list;

void got_it (int n) { list.push_back (n); }

*('{' >> lit("0x") >> hex[&got_it] >> '}'))

We have a our own custom made representation built in easy to debug steps. Reading this is simple: "when a hexadecimal number is recognized, call a function which pushes the number onto a list".

[1] Actually terminal doesn't appear to inherit from boost::spirit::qi::grammar at all.[2] Because it's the C++ deference operator*() overloaded, it goes in front, not behind as is traditional.