Tuesday, May 22, 2007

[off topic] Driving Principles of Programming: Ignorance

Well, I have already talked a bit about laziness and egoism, but now time have come to mention - after all - the last (as I count them) third principle: ignorance.

I was pitched to write this after whole week of meetings with two engineers, whose many questions may be rephrased as "what if sky falls down?" After several days I was ready to scream "As heck I care!!!" (and this is really polite form of what I actually wanted to say.)

I have a function to do task A. WTF shall I care here about B, C and D??? Some people just do not get it.

IGNORANCE. The ignorance which is bliss. As programming concerned, ignorance allows programmer to concentrate on particular task, ignoring ever-changing environment his program is ought to work in. Otherwise, if one would try to track all new requirements and developments, his/her attention would be diverted from original task. End result? Task would be always in half finished state.

Egoism and ignorance are very similar. Egoism tells us to ignore other's opinion (a.k.a. critics). Ignorance tells us to ignore other's problems (a.k.a. new requirements).

Like with other two principles, all is good in moderation. Pushing any of the principles to the limit of course goes against the laziness principle. And being too lazy would mean that you are not egoistic. And being too egoistic would mean that you can't ignore yourself. You see now? That's vicious circle of software development. ;)

P.S. How to use ignorance in practice. Ignorance normally results in task-oriented applications. You do not try to do everything - since you ignore everything - but concentrate on precisely the task/job you want to accomplish. Often such applications might look as hairy agglutinations of functions - and they are really functional and do what you want from them. Though lazy guys like I am would find them short on ergonomics ^_^

Sunday, May 20, 2007

[off topic] Perl v. Python: Python Sucks!

Results of my non-scientific research: "Python sucks". Or rather Python performance does suck big time. Or rather lack of performance.

Simple test.

$ cat a.py
print "Hello world!"
$ time python a.py
Hello world!

real 0m0.039s
user 0m0.032s
sys 0m0.008s
$

Compare to this:
$ cat a.pl
print "Hello World!\n";
$ time perl a.pl
Hello World!

real 0m0.008s
user 0m0.004s
sys 0m0.004s
$

or this:
$ cat a.c
#include <stdio.h>
int main()
{
printf("Hello World!\n");
return 0;
}
$ make a && time ./a
gcc a.c -o a
Hello World!

real 0m0.003s
user 0m0.000s
sys 0m0.000s
$


I mean, what Python does those 40ms? Compared to Perl's 4ms? Or C's ZILCHms?

Absolute values seem to be small enough to be disregarded. But the same cliche can be seen in bigger applications.

For example Gentoo's tool chain - emerge - many Gentoo users are familiar with. Its DARN slow. Even compared to Debian system - apt-get - which does so much more and often labeled by jealous RedHat folks "amateurish" - works magnitudes faster (and even on junk hardware).

Or SCons. SCons take 1.5 seconds to just start up and print help message. It's Perl's sibling cons/pcons in the time manages to compile several sources.

Wednesday, May 16, 2007

[link] Vi Lovers Home Page

Vi Lovers Home Page - terrific resource for everybody. Piles of links - tutorials and FAQs.

Must read.

[link] Gentoo's VI guide

Learning vi

Pretty good for beginners - just like about any other document I have seen from Gentoo.

Friday, May 04, 2007

[off topic] Divide and Conquer (DaC) vs. Model-View-Controller (MVC)

Thinking about team work organization, I was constantly humming "Divide and Conquer" (DaC) principle. That's pretty obvious since it is guiding principle how big teams are taking on large problems - by splitting them into many smaller ones. (Small enough for single person to solve.)

Turning back to work, my eyes have met again with several of my constructs loosely based on MVC model.

Sudden enlightenment: MVC is another application of more general DaC.

How DaC works. A (simple) problem is split into three (primitive) problems:

  • 2 smaller problems of original bigger problem and (one more piece everybody forgets about)

  • problem of integration the two smaller solutions into solution for bigger problem.

The third part - often forgotten line connecting two blocks - is very important and often play crucial development organization role. Recurrently applying DaC we can slice problems until they reach manageable size.

How MVC works. A problem is split into three problems:

  • stateful part containing all data/state (model),

  • stateless part containing all utilities needed to work with model (view) and

  • controller part which best exemplified by UI to manage the data of model using the utility of view.

MVC generally drawn as three blocks, with model being independent, view depending solely on model and controller depending on both model and view.

Similarities are obvious.

On high level, MVC's controller is the interface connecting the two pieces of problem - model (state) and view (functions). (Bigger problem split into two smaller problems - model and view - with controller playing role of integration problem.)

On lower level, MVC looks like DaC splitting original problem into three smaller problems and plus three more integration problems (view to model, controller to view and to model).

Tuesday, May 01, 2007

Clever tricks from VIM's Bram Moolenaar

The page where I found tip for the annoying PuTTY problem, also had great tip:

:help usr_12.txt
There you will find clever tricks you can do with VIM to accomplish simple yet sometimes needed tasks. And overall page has lots of simple hints. Very good reading.

VIM vs. PuTTY keypad

The problem was annoying me for very long time: under PuTTY, applications (e.g. less, vim) using tek window (alternative terminal screen) had totally screwed keypad. Solution was found here.
Apparently, PuTTY tries to do something smart. And fails.
Workaround:

  1. Change function key/keypad mapping from standard "ESC[n~" to "Linux".
  2. Disable application keypad mode
Apparently only second is required, but first is also recommended.
The options, as usual to all options of Windows applications, change their location in settings dialog periodically so I cannot give their precise locations. Go through PuTTY setting and you will find them.

Monday, April 30, 2007

[off topic] Driving Principles of Programming

I often asked on how software development works. To most people unfamiliar with all stinky innards of development process, figuring out how to get anything out of developers is very very tricky. Sometimes people see logic behind what I do - but often they are lost when trying to deal with me.

So as an insight into developer's head I would explain shortly here two of my software development principles. "Shortly" and "two" - because I have managed to date to formulate only one (second) of them and first was well know before I was even born.

1. This is grand principle which regulates lion share of decisions made by software developer. LAZINESS. Some think of it as of bad habit, but in as old programmers' proverb goes to find simplest solution to a problem, assign the problem to laziest programmer you have. In development and programming, laziness is source of all simple decisions which are often by outsiders are seen as "original" or even "genius". To programmers - it's just N days of work saved.

1a. Corollary. In development team with no lazy people, one would hardly see any innovation - or properly working program. After all, non-lazy people can make even pigs flying.

2. It just dawned on me recently and I have managed to formulate my second most used programming principle. EGOISM. (I would claim nothing and rather expect that somebody already did research that before me.) The principle is very simple: make something what would be useful to you and most likely others would find it also useful. Check the Unix made of thousands of small and big utilities - most of the utilities were initially developed for particular purpose of its author himself. But later were also found by others to be useful. Well, Unix itself was made for very particular purpose - and none of its developers even thought that Unix would catch up. Yet it did. Why? Because first and foremost it was useful to its creators. They didn't cared much what others did with it - how egoistic of them!? ;)

2a. Corollary. Excessive non-egoistic programming results in piles of abstract interfaces made to abstract other interfaces which abstract other interfaces. They do not do anything in particular - they are written often because people are told to write something. It is hard to make something useful - if you are just a little gear which needs only to mesh with other such gears. And to mesh better - we need more interfaces, abstraction layers and level of indirection. It also happens to be a generic sickness of many successful projects which in beginning "just work", but authors along the way get bored and start adding needless minor features (by request of vocal user minority) which in the end obstruct core functionality. Program was started as something working - thus became popular. Later on to satisfy needs of few others (here ended the egoism!) features added were not needed by authors themselves (nor (as usually!) were properly communicated by end users to developers) thus ended up being implemented poorly.

That's it for today.

Monday, April 09, 2007

[off topic] [rants] GNU Make - missing features

  1. For all "declaration" nature of make, it is still very very hard to build your own rule out of predefined ones found in make database. e.g. making a rule for new file extension to call existing rule for older file extension is only possible with dumb copy-and-pasting. Now imaging project with hundreds makefiles - all at different times doing such copy-and-pasting: one hell to do maintenance.
  2. Arithmetics. I was really surprised to find that make doesn't have any internal facility for arithmetic expression calculation. Even more so I was surprised when I learned that GNU project doesn't even have such library. Best call - is to call external optional program 'dc' or hope that bash is installed and do arithmetics through it. That bars many accessibility features like progress counter for long build processes. Also obviously renders makefiles unportable.
  3. Clean mechanism to overwrite rules. That's actually what makes proper dependency check implementation impossible. E.g. if you have dependency "a: b" and "a: c" that would really mean "a: b c" - and there is no way to cancel the "a: b" dependency.
  4. List and string routines. Again, mere convenience, yet has performance impact. To put it simply: it is very stupid when to transform file name I have to call several external programs. String manipulation is needed for file name transformations. List routines are needed for proper management of list of targets scheduled to build.
  5. Recursiveness. The dead horse was beaten many times before. Lack of proper recursiveness support bars use of make on very large projects. Or leads to arcane make files understood by few thus having very very low accessibility. One can't require everybody on project to be a make specialist.

Looking at all the rants, my mind instantly points out that the list is precisely difference between make and cons. Last update to cons - pcons - was in 2001 and (thanks to that fact that it was written in Perl) it still works perfectly in all situations I have been to.

I had very ridiculous accident: people using pcons were told to switch to make ("Of course there is no reasons to it - it is just our corporate policy"). Case looked bleak: dumbing down build system back to stone age of make wasn't problem - problem was the lost functionality (the list above). I have advised (and it actually worked) simple solution: put pcons right along with sources and create makefiles with all targets calling cons instead. Worked beautifully - thanks to slim nature of cons/pcons which is written in Perl and has little/no external dependencies.

[off topic] One-liner to make GNU Info usable

Something like this should be shipped along with GNU Info documentation system - to make it any useful:

$ cat ~/usr/bin/iinfo
#!/bin/bash
info --subnodes --output=- "$@" 2>/dev/null | less
$


Option "--subnodes" tells info to dump everything it has - w/o frigging inhuman document structure. Option "--output=-" tells to dump that all on stdout. The bit "2>/dev/null" is to shut up the stupid useless stuff info spits on stderr. And '| less' bit tells it to behave like proper "man".

Rants. Ironically, even the one-liner cannot make GNU tools any better: they show their age, were not updates in years and do not support most modern things one expects. Searching internet generally brings more and better results than digging outdated GNU documentation. (N.B. GCC of all GNU tools is kind of exception.)