Sunday, 20 November 2011

#Occupy

"We have nothing else cheap left to exploit. We are completely in danger from lack of culture. We were all trained up to be consumers...throw away the past, the future will take care of itself, catch the latest thing and suck it up." -- Vivienne Westwood, addressing Occupy activists (http://www.bbc.co.uk/news/uk-england-london-15806945)
 "There is no doubt in 1933 that the collapses of the older systems which we witness are probably irrevocable. Sir Auckland Geddes, the British Ambassador to the United States of America, foresaw them when he said in 1920: 'In Europe, we know that an age is dying. Here it would be easy to miss the the signs of coming changes, but I have little doubt that it will come. A realization of the aimlessness of life lived to labour and to die, having achieved nothing but avoidance of starvation, and the birth of children also doomed to the weary treadmill, has seized the minds of millions.'" -- Science and Sanity, p. 49, Alfred Korzybski
What does 'human' mean? What differentiates human from animal? Alfred Korzybski suggested we classify life on Earth as follows:
  1. Plants: static, synthesize sunlight and other chemicals in order to grow. Hence we define them as 'chemical-binders'.
  2. Animals: like plants, they synthesize chemicals to grow, but also have the ability to move around. This movement in 'space' differentiates plants from animals and hence we define them as 'space-binders'.
  3. Humans: like plants, synthesize chemicals to grow, and like animals move around in space. Humans add to this the ability to learn from previous generations - one generation can start from where the previous left off. This ability to transmit knowledge across time leads to the definition of humans as 'time-binders'.
Korzybski argues first in Manhood of Humanity, and later in Science and Sanity, that this definition of humans as 'time-binders' describes functionally what humans actually do. One only needs to look around to verify the claim. The presents from the past rest all around us.

The time-binding capacity of humans means that I can learn from Korzybski, despite the fact that he died 60 years ago. I can learn from Einstein, despite the fact he died 60 years ago. I can learn from Aristotle, despite the fact that he died 2000 years ago. Civilization arises because of the time-binding capacity. Imagine a world where every generation starts afresh, unable to use the fruits of the previous generations' efforts. We would still be living in the trees, picking flies off each other.
"NYPD & Brookfield have taken the People's Library again. and we love you all." -- https://twitter.com/#!/owslibrary/status/136970287601291265
By building a People's Library, the Occupiers in NY implicitly recognized the uniquely human capacity of time-binding. Bringing together books in that way honours the time-binding capacity that defines humans. What does destroying them signify?

So far, the mass media has focused on the occupation of 'space' in cities all around the world. But this space-binding activity is incidental to the more important time-binding activities, the creation and propagation of memes.


OWS Teach-In with Douglas Rushkoff from Douglas Rushkoff on Vimeo.

Pepper spray doesn't work against ideas. You can't kettle a meme. Animalistic, space-binding tactics may work in the short-term, but in the long-term, human-nature, the time-binding capacity, will assert itself.


To live life as a human means to live life in order to learn and progress, not simply to labour and die. To live a life of culture, rather than consumerism. To exercise the uniquely human time-binding capacity.

Sunday, 14 August 2011

Literate Programming with Marginalia

Here is the source code of the project I'm working on at home, formatted by Marginalia: http://neillalexander.github.com/rtm-clj/uberdoc.html.

I love it. Having something so beautifully formatted really motivates me to write comprehensive documentation. I'll be using it in all my Clojure projects from now on.

The set up was fairly straightforward, so I won't go through it in depth here. Once I had it working, I wanted to find an easy way to publish the updated documentation, and make it easily readable on-line. The solution was GitHub pages, and git submodules.

Here's what I did:
  • Added that branch as a submodule of the main source code in the docs directory.
  • git submodule add git@github.com:NeillAlexander/rtm-clj.git docs
    cd docs
    git checkout gh-pages
    
  • Created index.html which redirects to uberdoc.html
  • Back up to the parent directory and run 'lein marg'
Running 'lein marg' creates a new version of uberdoc.html in the docs directory, which is actually the gh-pages branch of the overall project. Pushing the change therefore makes it available at http://neillalexander.github.com/rtm-clj/uberdoc.html

    Saturday, 13 August 2011

    Simple Arity Checking Using Higher Order Functions

    As a learning exercise I'm writing a little command line tool to connect to Remember the Milk using Clojure. The idea is that the tool is a mini shell (or repl) which reads commands, executes them, and prints the result.

    The commands are written as simple Clojure functions. When I type something at the command line, the command is looked up in a map and, if found, executed, passing the rest of the arguments.

    For this to be safe I need to check the arity of the function matches the number of commands entered at the command line.

    For example:

    When I type 'help' then all the available commands are returned:
    rtm> help
    (echo exit help)
    

    If I type help with an argument, then it still works, because help is multi-arity, and has an implementation that takes an argument:
    rtm> help command
    Help for command
    

    If I type help with more than one argument, the arity check kicks in and refuses to call the function:
    rtm> help won't work
    help: wrong number of args
    Help for help
    

    It took a bit of thinking to work out how to do this, but I eventually came up with the following solution.

    ;; higher order functions rock!
    (defn arity-check
      "Returns a function that evaluates to true if the arity matches the count"
      [arglist]
      ;; special case - if arglist is of zero length then no need to check for & args
      (if (= 0 (count arglist))
        #(= % 0)
        (let [arg-map (apply assoc {}
                             (interleave arglist (range 0 (count arglist))))]
          ;; if & args found then number of args is >= the position of the &
          ;; otherwise it's just a simple size comparison
          (if ('& arg-map)
            #(>= % ('& arg-map))
            #(= % (count arglist))))))
    
    
    ;; this builds a collection of functions, one for each of the arglists
    ;; which evaluates to true if the number of args matches the arity of the
    ;; arglist. it then applies each function in turn against the size of the
    ;; args, and determines if any of them returned true. if at least one of
    ;; them returned true, then we can safely do the call
    (defn arity-matches-args
      "Returns true if the args match up to the function"
      [f args]
      (let [arity-check-fns (map arity-check (:arglists (meta f)))]
        ((set (map #(% (count args)) arity-check-fns)) true)))
    

    The arity-check function takes an arglist, as returned from the meta-data of a function. This is a higher order function which returns a function that evaluates to true if the number passed in is assignment compatible with the arity of the arglist.

    e.g. if the arglist is [x] then 1 argument is expected. If it is [x y] then 2 arguments are expected. If it is [& args] then any number of arguments >= 0 are expected. If it's [x & args] then any number of arguments >= 1.

    The arity-matches-args function calls the arity-check for each of the arglists in the meta data of the function, and stores them in a sequence, arity-check-fns. It then calls every one of those functions passing in the number of arguments in args, and generates a set of the results, which will be either true, false, or nil. It then uses the set as a function to see if it contains true. If it does then at least one of the arglist arities matches the number of arguments that have been entered.

    There is probably an easier way to do this...but I'm still proud of this solution. It opened my eyes to the power of higher order functions

    The source code is at https://github.com/NeillAlexander/rtm-clj

    Saturday, 6 August 2011

    Will Clojure Ever Be 'Finished'?

    Clojure, as a Lisp dialect, is an extremely malleable language. The lack of syntax lends itself to creating domain specific languages. The built-in meta-programming (macros) means that anyone can add new language features. In contrast, adding new language features to Java requires a lengthy process of negotiation and compromise via the JCP.
    If you give someone Fortran, he has Fortran. If you give someone Lisp, he has any language he pleases.  -- Guy Steele
    Will we hit a point where Rich and the Clojure/Core team regard the core language as complete? In other words, will Clojure hit a stage where it is rich enough (no pun intended) that there is no further work required, other than to write new libraries? This seems plausible to me, and perhaps even desirable.

    I'd be interested to hear Rich Hickey's view on this.

    Update (18th November): at the Clojure / Conj last week, I had the opportunity to put this question to Rich. He broadly agreed with the point, saying that the core language is basically done, and that the remaining work is mostly around the edges.

    Sunday, 31 July 2011

    Lazy Sequences

    I like this a lot:
    ;; define a function with a side effect to show when it is called
    (defn square [x]
      (do
        (println (str "Processing: " x))
        (* x x)))
    
    ;; define map-result which is result of calling square for every item in the list
    (def map-result (map square '( 1 2 3 4 5 6 7 8)))
    
    First time, enough of the lazy sequence is evaluated to generate the result:
    practical-clojure.chpt5> (nth map-result 2)
    Processing: 1
    Processing: 2
    Processing: 3
    9
    
    The next time, with the same args, the previous calculation was cached, so nothing to evaluate:
    practical-clojure.chpt5> (nth map-result 2)
    9
    
    The next call it needs to evaluate a couple more of the lazy sequence:
    practical-clojure.chpt5> (nth map-result 4)
    Processing: 4
    Processing: 5
    25
    
    And again, this is cached:
    practical-clojure.chpt5> (nth map-result 4)
    25
    
    This is possible because a sequence looks like:
    first --> (rest)
    first --> (first --> (rest))
    first --> (first --> (first --> rest))
    
    Rest is only evaluated when it is required.

    Auto Save a File in Emacs

    Download http://www.litchie.net/programs/real-auto-save.html to .emacs.d, and then:

    ;; real auto-save - forces auto save mode
    (require 'real-auto-save)
    (add-hook 'text-mode-hook 'turn-on-real-auto-save)
    (add-hook 'muse-mode-hook 'turn-on-real-auto-save)
    (add-hook 'slime-mode-hook 'turn-on-real-auto-save)
    (add-hook 'emacs-list-mode-hook 'turn-on-real-auto-save)
    (setq real-auto-save-interval 5) ;; in seconds
    

    Fixing Git Remote Reference

    Did a 'git pull' and saw this:

    Your configuration specifies to merge with the ref 'master'
    from the remote, but no such ref was fetched.

    A quick bit of googling turned up http://stackoverflow.com/questions/4297795/configure-git-so-that-git-pull-instead-of-git-pull-origin-master, which indicated I needed to edit my .git/config file to contain this:

    [branch "master"]
            remote = origin


    The remote = origin line was missing, therefore git didn't know where to pull from.

    Saturday, 30 July 2011

    Auto Complete in Clojure

    This is awesome. My one concern about switching from Eclipse to Emacs for Clojure was losing the handy auto-complete stuff in Eclipse. I no longer have that concern:



    Install the auto-complete mode (M-x package-install, auto-complete if using ELPA).

    Download ac-slime from here: https://github.com/purcell/ac-slime

    Here is the config required to set it up:

    ;; auto complete
    (require 'auto-complete-config)
    (add-to-list 'ac-dictionary-directories "~/.emacs.d/ac-dict")
    (ac-config-default)
    (setq ac-delay 0.5) ;; eclipse uses 500ms
    
    ;; configure auto complete to work in slime
    (add-to-list 'load-path "~/.emacs.d/ac-slime")
    (require 'ac-slime)
    (add-hook 'slime-mode-hook 'set-up-slime-ac)
    (add-hook 'slime-repl-mode-hook 'set-up-slime-ac)
    

    Tuesday, 5 July 2011

    Counterclockwise Eclipse Plugin

    I'm going to run with Counterclockwise for now, since I'm already very comfortable with Eclipse. Having had a quick play with it this evening it seems to do everything I want, and will only get better.

    The list of key bindings is defined at: http://code.google.com/p/counterclockwise/wiki/EditorKeyBindingsFeatures

    Balanced brackets only seem to work in strict mode on Ubuntu.

    Unfortunately Ubuntu 11.04 has some system key bindings which interfere with the Counterclockwise bindings:
    • Shift-Alt-Up: bound to Compiz scale windows. Install compizconfig-settings-manager, run "ccsm", and find Scale under Window Management, and disable the key binding. 
    • Ctrl-Alt-T: launches a terminal in Eclipse. Disable via System -> Preferences -> Keyboard Shortcuts

    Sunday, 3 July 2011

    Cljr

    Well this is new: https://github.com/liebke/cljr. A very simple way to move from zero to a working Clojure REPL. All it took was:
    wget http://incanter.org/downloads/cljr-installer.jar
    java -jar cljr-installer.jar
    export PATH=/home/neill/.cljr/bin:$PATH
    cljr repl
    

    Clojure Revisited

    In the first half of 2010 I did a bit of programming in Clojure, using it to write a simple debug proxy for SOAP. Although I wrote many lines of Clojure code for that project, by the end I had the nagging feeling that I hadn't written idiomatic Clojure code.

    And so, to stop that feeling from nagging, I am going to try to approach Clojure once again with beginners mind. My weapon of choice for this new assault is The Joy of Clojure. I have high hopes that this will help my understanding of the language to move up a level. I hope to be thinking in Clojure by the end of it. And I'm going to record the journey for posterity here.

    Saturday, 30 April 2011

    Reverse Incremental Search in Bash

    I learned a new trick this week. Reverse incremental search through bash history using the up key. This blog post outlines it nicely:

    http://codeinthehole.com/archives/17-The-most-important-command-line-tip-incremental-history-searching-with-.inputrc.html


    Using these bindings, I can type 'git', then hit the up-arrow to search back through all the recent git commands I've used. This is a really quick way to improve productivity at the command line.

    For future reference, just in case the above linked blog entry disappears.

    In ~/.inputrc:
    "\e[A": history-search-backward
    "\e[B": history-search-forward
    "\e[C": forward-char
    "\e[D": backward-char
    
    In ~/.bashrc:
    export HISTSIZE=1000000
    export HISTFILESIZE=1000000000
    

    Thursday, 28 April 2011

    Make it Work First...

    ==========
    Pragmatic Thinking and Learning (Neill Alexander) (Hunt)
    - Highlight Loc. 1277-83  | Added on Saturday, April 23, 2011, 10:06 AM

    Author Anne Lamott is an advocate of purposefully creating a shitty first draft. That is, it's better to complete a shitty first draft than to never complete a perfect one. In her book Bird by Bird: Some Instructions on Writing and Life, Lamott explains the dangers of perfectionism: "Perfectionism is the voice of the oppressor, the enemy of the people. It will keep you cramped and insane your whole life, and it is the main obstacle between you and a shitty first draft. I think perfectionism is based on the obsessive belief that if you run carefully enough, hitting each stepping-stone just right, you won't have to die. The truth is that you will die anyway and that a lot of people who aren't even looking at their feet are going to do a whole lot better than you, and have a lot more fun while they're doing it."
    ==========

    Make it work first, then make it better.

    Tuesday, 26 April 2011

    Deliberate Practice

    ==========
    Pragmatic Thinking and Learning (Neill Alexander) (Hunt)
    - Highlight Loc. 1067-69  | Added on Friday, April 08, 2011, 08:16 PM

    Skills and abilities that you constantly use and constantly practice will begin to dominate, and more of your brain will become wired for those purposes. At the same time, lesser-used skills will lose ground. "Use it or lose it" is perfectly accurate in this case, because your brain will dedicate more resources to whatever you are doing the most.
    ==========
    Pragmatic Thinking and Learning (Neill Alexander) (Hunt)
    - Highlight Loc. 1070-73  | Added on Friday, April 08, 2011, 08:16 PM

    Perhaps this is why musicians practice scales incessantly; it's sort of like refreshing dynamic RAM. Want to be a better coder? Practice coding more. Engage in deliberate, focused practice as described in the sidebar (here…). Want to learn a foreign language? Immerse yourself in it. Speak it all the time. Think in it. Your brain will soon catch on and adapt itself to better facilitate this new usage.
    ==========

    Over the last couple of years the majority of my personal programming time has gone into 2 largish applications; Sponge and Meditation Helper. The main aim of the first project was to write something substantial in Clojure, and the second to do the same for Android. Both were fun projects to work on. However, I have now decided to change my approach.

    Instead of embarking on another application, I am instead using my personal programming time to practice scales. I am writing toy classes to learn apis, libraries etc that I haven't had much experience with, or that I want to learn in more depth. I want to improve as a programmer, and the only way to do that is practice, practice, practice.

    Sunday, 24 April 2011

    Unknown Unknowns

    ==========
    Pragmatic Thinking and Learning (Neill Alexander) (Hunt)
    - Highlight Loc. 376-89  | Added on Thursday, April 07, 2011, 07:58 AM

    When you are not very skilled in some area, you are more likely to think you're actually pretty expert at it. In the paper "Unskilled and Unaware of It: How Difficulties in Recognizing One's Own Incompetence Lead to Inflated Self-Assessments" [AUOIHDIROOILTIS] , psychologists Kruger and Dunning relate the unfortunate story of a would-be thief who robbed a bank in broad daylight. He was incredulous at his prompt arrest, because he was under the impression that wearing lemon juice on your face would make you invisible to security cameras. The "lemon juice man" never suspected that his hypothesis was, er, suspect. This lack of accurate self-assessment is referred to as second-order incompetence, that is, the condition of being unskilled and unaware of it. This condition is a huge problem in software development, because many programmers and managers aren't aware that better methods and practices even exist. I've met many younger programmers (one to five years of experience) who never have been on a successful project. They have already succumbed to the notion that a normal project should be painful and should fail. Charles Darwin pegged it when he said, "Ignorance more frequently begets confidence than does knowledge." The converse seems to be true as well; once you truly become an expert, you become painfully aware of just how little you really know.
    ==========

    Friday, 22 April 2011

    Baby Steps

    ==========
    Practices of an Agile Developer (Neill Alexander) (Hunt Subramaniam)
    - Highlight Loc. 1850-55  | Added on Monday, April 04, 2011, 07:24 AM

    When you're driving on a long trip, does it make sense to hold the wheel firmly in one position, stare straight ahead, and then just floor the gas for a couple of hours? Of course not. You have to steer. You have to be constantly aware of traffic. You have to check your gas gauge. You have to stop for fuel, food, and other necessities, and so on.[30] Don't code for hours, or even minutes, without stopping to make sure you're on the right path---by testing what you produce. Instead, code in short increments. You'll find that coding in increments helps you refine and structure the code as you go along. The code is less likely to become complicated or messy; you build the code based on the on-going feedback from writing and testing in increments.
    ==========

    At university, there were people who used to code and code and code and code and code and code and code and code...

    Then they'd hit the compile button and wonder why they had so many errors. A lot of them thought programming was 'too hard' because of this.

    Wednesday, 20 April 2011

    Commenting Code is like Eating Peas

    ==========
    Practices of an Agile Developer (Neill Alexander) (Hunt Subramaniam)
    - Highlight Loc. 1786-88  | Added on Monday, April 04, 2011, 07:19 AM

    Code will always be read many more times than written, so the little extra effort that is required to document your code when writing it will pay you back handsomely in the end.
    ==========

    When I was a kid, I used to leave my vegetables until last. At the end of my dinner I'd be sitting there with an enormous mound of peas, with my mother breathing down my neck, demanding that they be finished before I could leave the table.

    I hated peas.

    When I was at university learning how to program, there were people in my class who used to leave commenting code until the end. They used to write their entire computer program, then go back at the end and add comments, because they'd lose marks if they didn't provide any.

    They hated writing comments.

    What I didn't understand as a kid was that peas aren't so bad when you eat them in combination with the rest of your food. In fact, now I think they are delicious. I wouldn't like to eat a giant mound of them by themselves though.

    Monday, 18 April 2011

    ORM is a Solved Problem

    ==========
    Practices of an Agile Developer (Neill Alexander) (Hunt Subramaniam)
    - Highlight Loc. 864-66  | Added on Friday, April 01, 2011, 08:47 AM

    For instance, if you have a hankering to develop your own persistence layer, remember Ted Neward's remark that "object-relational mapping is the Vietnam of computer science." You can spend more time and effort building only what you need to build for your application---the domain or application-specific stuff.
    ==========

    This made me laugh, because I built a persistence layer for a project, then realized after the fact that I should just have used Hibernate. It was a valuable lesson.

    The thing is, at one point during the project I was talking to the project manager who expressed his concern at the length of time it was taking to complete the work. I said to him, "Don't worry, I'm not trying to re-implement Hibernate!". Shortly after that conversation I realized that I was, in fact, trying to re-implement Hibernate. It all started very naively - I implemented a solution using Spring JDBC, and then saw an opportunity to extract some higher level abstractions. That process continued to the point that I found myself writing a DSL that would enable me to express the various object relationships, and map them to the database structure.

    Hmmm. Object relational mapping you say. That rings a bell.

    Object-relational mapping is a solved problem. There are multiple solutions out there. Pick one and use that. Even if you need to learn it from scratch, it will still be quicker than writing your own version.

    Saturday, 16 April 2011

    Rooting for the Underdog

    I installed Cyanogen 7 onto my HTC Desire this week. Along the way I changed the partition table to free up some space for applications. I now have a phone running the very latest version of Android, and space for plenty more apps.

    The ability to customize my phone in this way is very important to me. I will never buy a phone that does not allow me to have root access, or that prevents me from installing ROMs with mechanisms such as signed bootloaders. I didn't know about any of this stuff when I jumped from the good ship Apple (see Operation Bad Apple). I bought an HTC Desire because it seemed like the best Android phone at the time. Had I known about custom ROMs and rooting, I probably would have gone for the Nexus One, because for a while it wasn't possible to get full root access to the Desire. It was only when Alpharev came along that this became possible.

    Which is why this link is so important - http://unrevoked.com/rootwiki/doku.php/public/root_friendly. It's a list of phones that are amenable to rooting. You'll notice all the newer HTC phones appear in the "poor choices" category. That's because HTC have started signing the boot partition, making it impossible to install custom ROMs. In my eyes, in the space of a year, HTC have move from being the plucky underdogs who need to be supported. to the dicks that need to be ignored. Although I am very impressed with my HTC Desire, there is no way I will be buying any of the newer HTC phones.

    Meanwhile, Sony Ericsson have announced that all their new phones in the Xperia range will have unlockable bootloaders. They even provide a web-site to enable you to unlock the bootloader (see http://unlockbootloader.sonyericsson.com/). This is fantastic news, and is likely to win Sony Ericsson a lot of hardcore Android fans. You'll note that the new Sony phones appear in the "root friendly" section of the unrevoked list.

    Hopefully this is a sign of things to come, and more manufacturers will follow Sony's lead. If I were in the market for a new phone right now, I'd probably go for the Sony Arc. This kind of enlightened behaviour from phone manufacturers needs to be encouraged.

    Context Matters

    ==========
    Practices of an Agile Developer (Neill Alexander) (Hunt Subramaniam)
    - Highlight Loc. 373-75  | Added on Friday, April 01, 2011, 07:53 AM

    There is no absolute best, only better. Despite the popularity of the term, there is no such thing as "best practices," only better practices in a particular situation.
    ==========

    In General Semantics we talk about non-elementalism i.e. don't split verbally what cannot be split in actuality. The classic example is talking about 'space' and 'time' as opposed to space-time. Another example might be 'body' and 'mind' as opposed to the organism-as-a-whole.

    Everything has a context and must be evaluated in relation to that context.

    Thursday, 14 April 2011

    Speak Up!

    ==========
    Practices of an Agile Developer (Neill Alexander) (Hunt Subramaniam)
    - Highlight Loc. 329-32  | Added on Friday, April 01, 2011, 07:49 AM

    We all have some good ideas and some bad ideas, and everyone on the team needs to feel free to express them. Even if your idea is not fully taken up, it may help shape the solution. Don't be afraid of being criticized. Remember, everyone who became an expert started somewhere. In the words of Les Brown, "You don't have to be great to get started, but you have to get started to be great."
    ==========

    Even if the idea that you come up with isn't adopted, it may trigger someone else in the room to come up with a better idea. And that may in turn trigger someone else. Inspiration comes from the funniest places.

    I've read a few Edward de Bono books in my time where he talks about using nonsense words to trigger lateral thinking e.g. foo a bike with square wheels might lead someone to think about active suspension in a bike.

    Tuesday, 12 April 2011

    Dealing with Problems

    ==========
    Practices of an Agile Developer (Neill Alexander) (Hunt Subramaniam)
    - Highlight Loc. 206-11  | Added on Thursday, March 31, 2011, 09:02 AM

    You may not believe this, but not everyone always has the outcome of the project as their top priority. Not even you. Consider your first, "default" reaction when a problem arises. You might inadvertently fuel the problem by saying things that will complicate things further, by casting blame, or by making people feel defensive. Instead, take the high road, and ask, "What can I do to solve this or make it better?" In an agile team, the focus is on outcomes. You want to focus on fixing the problem, instead of affixing the blame. Blame doesn't fix bugs.

    ==========
    Practices of an Agile Developer (Neill Alexander) (Hunt Subramaniam)
    - Highlight Loc. 221-24  | Added on Thursday, March 31, 2011, 09:03 AM

    On an agile team, the situation is different. If you go to an agile team member with a complaint, you'll hear, "OK, what can I do to help you with this?" Instead of brooding over the problem, they'll direct their efforts toward solving it. Their motive is clear; it's the outcome that's important, not the credit, the blame, or the ongoing intellectual superiority contest.
    ==========

    Sunday, 10 April 2011

    Compass

    I read about the Compass Project in the book Modular Java. When I next need to add search functionality to a Java application I will definitely be checking it out.

    Friday, 8 April 2011

    Over Learning

    ==========
    Pomodoro Technique Illustrated (Neill Alexander) (Noteberg)
    - Highlight Loc. 646-56  | Added on Sunday, March 27, 2011, 12:49 PM

    Never switch activities in the middle of a Pomodoro. If you finish an activity halfway through a Pomodoro, spend the rest of the time over-learning. For example, if I finish early, I review what I have done, I repeat what I have learned, I see whether I can enhance my work, or I note new conclusions on paper---until the kitchen timer rings. Over-learning is when we continue to study or practice even after attaining proficiency. Malcolm Gladwell argues that this is necessary if we want to be really good at something: "Once a musician has enough ability to get into a top music school, the thing that distinguishes one performer from another is how hard he or she works. That's it. And what's more, the people at the very top don't work just harder or even much harder than everyone else. They work much, much harder.".[32] So, you're not allowed to impulsively switch activities in the middle of a Pomodoro. In fact, just having the option to switch in the middle is a recurring disturbance. You can't just stop in the middle of a Pomodoro and take a break either. Then you will lose the rhythm. And since the stopped Pomodoro was shorter, it will not be compatible---in terms of tracking---with other Pomodori.
    ==========

    I hadn't heard or read the phrase 'over-learning' prior to reading this book. It makes sense, and is something I am looking to adopt to improve my technical / programming skills.

    The Pomodoro Technique is, 1 week later, proving to be a useful addition to my personal productivity.

    Wednesday, 6 April 2011

    Double Trouble

    ==========
    Backgammon For Dummies (Chris Bray)
    - Highlight on Page 78 | Loc. 989-91  | Added on Monday, March 14, 2011, 07:33 AM

    In a game you may make up to 30 decisions about how to move your checkers, but you’re likely to make only two or three doubling of decisions, so taking the time to get them right is worth it. As Paul Magriel said, in his 1976 book Backgammon, ‘Good checker play will never compensate for serious errors of judgement in doubling.’
    ==========
    Backgammon For Dummies (Chris Bray)
    - Highlight on Page 99 | Loc. 1245-49  | Added on Monday, March 14, 2011, 08:06 AM

    One of the keys to winning backgammon is to double when you have a strong threat, not after you’ve executed that threat perfectly. Remember, your opponent has to have some chance of winning in order to take your double. Winning just one point when you may have won four (via a doubled gammon) won’t make you rich, or leave you satisfied. Of course, sometimes you double and your opponent turns the game around and wins it. You just develop the knack of living with that possibility. If certainty is what you seek, backgammon is probably not for you. If, however, you want excitement, you’re playing the right game!
    ==========

    I have come to the conclusion that backgammon is a solved problem. For any particular roll of a dice there is a statistically best move you can make. Neural net based backgammon bots have proved this. However, you can play a match making the best moves all the way and still lose due to bad dice luck.

    So I'm putting my short-lived online backgammon career behind me.

    Monday, 4 April 2011

    Do it Properly

    ==========
    Code Complete (Steve McConnell)
    - Highlight Loc. 27111-19  | Added on Thursday, February 24, 2011, 07:19 AM

    Making code readable is not an optional part of the development process, and favoring write-time convenience over read-time convenience is a false economy. You should go to the effort of writing good code, which you can do once, rather than the effort of reading bad code, which you'd have to do again and again. "What if I'm just writing code for myself? Why should I make it readable?" Because a week or two from now you're going to be working on another program and think, "Hey! I already wrote this class last week. I'll just drop in my old tested, debugged code and save some time." If the code isn't readable, good luck! The idea of writing unreadable code because you're the only person working on a project sets a dangerous precedent. Your mother used to say, "What if your face froze in that expression?" And your dad used to say, "You play how you practice." Habits affect all your work; you can't turn them on and off at will, so be sure that what you're doing is something you want to become a habit. A professional programmer writes readable code, period.
    ==========

    This comes back to integrity. You do something because it is the right thing to do, not because you're afraid of being found out. I have to admit, there is some code in the Android application that I wrote that isn't too pretty. I justified it to myself by saying that I was the only person looking at the code, therefore it didn't matter if it was a bit ugly. Of course, I ended up cursing myself when I returned to make a change or add a new feature!

    It's amazing how quickly you forget about code that you have written. That's why it's important to do it properly the first time (with comments) even if you are the only person that will be looking at the code.

    I write this not to convince you, dear reader, but to convince myself. You, I am sure, write perfect code every time.

    Saturday, 2 April 2011

    Pomodroido Tasker Integration

    Last weekend I read Pomodoro Technique Illustrated and decided to give it a try. A while back I adopted Getting Things Done to organize my life. GTD is great for organizing and remembering tasks, but doesn't help with actually doing the work! Procrastination is still a problem. Pomodoro helps in that respect because it uses the idea of time-boxing to create artificial deadlines to help focus the mind. Combining GTD and Pomodoro seems to me to be a very promising personal productivity approach.

    Anyway, since I have an Android phone, I had a look around for an application that would help me adopt the Pomodoro technique. Pomodroido fits the bill nicely.

    The thing that really impressed me with the application was the integration with Tasker. Tasker is one of those apps that I've had on my phone for a long time, but never really found a use for. It's the swiss army knife of applications - you can do almost anything with it. I just never bothered learning how to use it properly.

    When I bought Pomodroido I compared the free version with the pro version. The pro version promised Tasker integration. Intrigued, I bought it to try it out. And when I tried it out I realized I'd missed a trick with my own application, Meditation Helper. You see, Pomodroido triggers an event when a Pomodoro starts, and another when it ends. Tasker knows about this event, and therefore you can change the settings of your phone during a Pomodoro.

    Here's what I did.
    • When a Pomodoro starts I change the display timeout to 10 seconds, disable the screen lock, and switch off the radio. This means that during a Pomodoro I will not be disturbed by telephone calls, I can switch the screen on to see how much time is left in the Pomodoro without having to unlock the phone, and the screen will switch off again after 10 seconds.
    • When a Pomodoro ends I revert these changes back to their defaults, and also switch the screen on as a further indication to me that the Pomodoro has ended.
    This is really clever. In Mediation Helper I added options to enable airplane mode during a meditation, to disable the screen lock etc. Instead of doing this, I could simply have fired an event when the meditation session started, then fired another when it ended, and allowed the user to customize their experience using Tasker.

    Although I have put any further development on Meditation Helper to one side for the meantime, I have added 'Tasker Integration' as one of the main new features that I will introduce in the next version.

    Update: here are links to the Tasker profiles I created.

    Friday, 1 April 2011

    Estimation

    ==========
    Code Complete (Steve McConnell)
    - Highlight Loc. 26756-72  | Added on Wednesday, February 23, 2011, 07:44 AM

    If management applies pressure to change your estimate, realize that ultimately the decision whether to do a project rests with management: "Look. This is how much it's going to cost. I can't say whether it's worth this price to the company—that's your job. But I can tell you how long it takes to develop a piece of software—that's my job. I can't ‘negotiate’ how long it will take; that's like negotiating how many feet are in a mile. You can't negotiate laws of nature. We can, however, negotiate other aspects of the project that affect the schedule and then reestimate the schedule. We can eliminate features, reduce performance, develop the project in increments, or use fewer people and a longer schedule or more people and a shorter schedule." One of the scariest exchanges I've ever heard was at a lecture on managing software projects. The speaker was the author of a best-selling software-project-management book. A member of the audience asked, "What do you do if management asks for an estimate and you know that if you give them an accurate estimate they'll say it's too high and decide not to do the project?" The speaker responded that that was one of those tricky areas in which you had to get management to buy into the project by underestimating it. He said that once they'd invested in the first part of the project, they'd see it through to the end. Wrong answer! Management is responsible for the big-picture issues of running a company. If a certain software capability is worth $250K to a company and you estimate it will cost $750K to develop, the company shouldn't develop the software. It's management's responsibility to make such judgments. When the speaker advocated lying about the project's cost, telling management it would cost less than it really would, he advocated covertly stealing management's authority. If you think a project is interesting, breaks important new ground for the company, or provides valuable training, say so. Management can weigh those factors, too. But tricking management into making the wrong decision could literally cost the company hundreds of thousands of dollars. If it costs you your job, you'll have gotten what you deserve.
    ==========

    And once you have given them your honest estimate on how long a piece of work will take, pray that they have heard of the 'Mythical Man Month'.

    Estimation is a difficult thing to get right. The best advice I ever read about providing software estimates was to use suitable units of estimation. If you think something will take 3 days, estimate 'a week'. Chances are your 3 day estimate is hopelessly optimistic anyway.

    And always keep in mind Hofstader's law, even though it will make no difference:
    "Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law."

    Wednesday, 30 March 2011

    And For My Next Trick...

    ==========
    Code Complete (Steve McConnell)
    - Highlight Loc. 26555-58  | Added on Wednesday, February 23, 2011, 07:25 AM

    We become authorities and experts in the practical and scientific spheres by so many separate acts and hours of work. If a person keeps faithfully busy each hour of the working day, he can count on waking up some morning to find himself one of the competent ones of his generation. — William James
    ==========
    Code Complete (Steve McConnell)
    - Highlight Loc. 26597-99  | Added on Wednesday, February 23, 2011, 07:35 AM

    If you're working in a competitive software market, half of what you now need to know to do your job will be out of date in three years. If you're not learning, you're turning into a dinosaur.
    ==========

    Could everyone please stop inventing cool new things so that I can catch up? Thanks.

    Monday, 28 March 2011

    Integrity

    ==========
    Code Complete (Steve McConnell)
    - Highlight Loc. 26538-42  | Added on Wednesday, February 23, 2011, 07:24 AM

    Programming work is essentially unsupervisable because no one ever really knows what you're working on. We've all had projects in which we spent 80 percent of the time working on a small piece we found interesting and 20 percent of the time building the other 80 percent of the program. Your employer can't force you to be a good programmer; a lot of times your employer isn't even in a position to judge whether you're good. If you want to be great, you're responsible for making yourself great. It's a matter of your personal character.
    ==========

    Saturday, 26 March 2011

    Brace Yourself

    ==========
    Code Complete (Steve McConnell)
    - Highlight Loc. 24021-30  | Added on Wednesday, February 23, 2011, 07:14 AM

    After I published the first edition of this book, Hank, one of the programmers who reviewed the manuscript, said "I was surprised that you didn't argue more strongly in favor of a brace style that looks like this: for ( ...)    {    } "I was surprised that you even included the brace style that looked like this: for ( ...) { } "I thought that, with both Tony and me arguing for the first style, you'd prefer that." I responded, "You mean you were arguing for the first style, and Tony was arguing for the second style, don't you? Tony argued for the second style, not the first." Hank responded, "That's funny. The last project Tony and I worked on together, I preferred style #2, and Tony preferred style #1. We spent the whole project arguing about which style was best. I guess we talked one another into preferring each other's styles!"
    ==========

    I was forced to switch brace style once. It was a valuable lesson in egoless programming. At the time I found it really painful. That was the bite of ego. Now I look at the old brace style I used and think it was stupid. But I would switch back if a project mandated it.

    Thursday, 24 March 2011

    The Medium is the Message

    ==========
    Zen and the Brain: Toward an Understanding of Meditation and Consciousness (James H. Austin)
    - Highlight Loc. 3994-95  | Added on Monday, February 21, 2011, 07:13 PM

    The bar code on the jacket of this book is an example.
    ==========

    Book?

    Tuesday, 22 March 2011

    Egoless Programming

    ==========
    Zen and the Brain: Toward an Understanding of Meditation and Consciousness (James H. Austin)
    - Highlight Loc. 3695-97  | Added on Sunday, February 20, 2011, 12:51 AM

    Joshu Sasaki-roshi: Form or rules are very important. We are not trying to keep you inside of them but to cut off your ego. This is very important as a way of teaching. To cut off your ego is the first step in Zen practice. Joshu Sasaki-roshi1
    ==========

    Cutting off your ego is also an important step in programming practice. Don't be precious about 'your' code. Chances are, it's not 'your' code anyway. It's code that someone else has paid you to write.

    If someone points out a better way to solve a problem, the correct response is to thank them and learn.

    Sunday, 20 March 2011

    This Computer is Stupid

    ==========
    Code Complete (Steve McConnell)
    - Highlight Loc. 7804-7  | Added on Saturday, February 19, 2011, 01:18 PM

    If you often find yourself suspecting that the compiler or the hardware made an error, you're still in the realm of superstition. A study conducted many years ago found that only about five percent of all errors are hardware, compiler, or operating-system errors (Ostrand and Weyuker 1984). Today, that percentage would probably be even lower. Programmers who have moved into the realm of understanding always suspect their own work first because they know that they cause 95 percent of errors.
    ==========

    I've certainly been in this position in the past. In my early programming career I would often cry tears of frustration, convinced that the computer was stupid and wasn't doing what I'd told it to do. Because of course, I always write perfect code.

    Now I know that if I find myself railing against the stupidity of the computer, then I've probably made a stupid mistake somewhere in my code.

    Wednesday, 23 February 2011

    Dealing with Complexity

    ==========
    Code Complete (Steve McConnell)
    - Highlight Loc. 5564-67  | Added on Thursday, February 17, 2011, 06:28 AM

    Reduce complexity. The single most important reason to create a class is to reduce a program's complexity. Create a class to hide information so that you won't need to think about it. Sure, you'll need to think about it when you write the class. But after it's written, you should be able to forget the details and use the class without any knowledge of its internal workings.
    ==========

    Code Complete (Steve McConnell)
    - Highlight Loc. 5871-76  | Added on Thursday, February 17, 2011, 06:43 AM

    Reduce complexity. The single most important reason to create a routine is to reduce a program's complexity. Create a routine to hide information so that you won't need to think about it. Sure, you'll need to think about it when you write the routine. But after it's written, you should be able to forget the details and use the routine without any knowledge of its internal workings. Other reasons to create routines—minimizing code size, improving maintainability, and improving correctness—are also good reasons, but without the abstractive power of routines, complex programs would be impossible to manage intellectually.

    ==========

    And not just classes. If you find complexity anywhere in a software system, find a way to modularize it and hide the complexity away.

    Monday, 21 February 2011

    Abstracting

    ==========
    Code Complete (Steve McConnell)
    - Highlight Loc. 5558-63  | Added on Thursday, February 17, 2011, 06:27 AM

    On programming projects, the abstractions are not ready-made the way Shape is, so we have to work harder to come up with clean abstractions. The process of distilling abstract concepts from real-world entities is non-deterministic, and different designers will abstract out different generalities. If we didn't know about geometric shapes like circles, squares and triangles, for example, we might come up with more unusual shapes like squash shape, rutabaga shape, and Pontiac Aztek shape. Coming up with appropriate abstract objects is one of the major challenges in object-oriented design.
    ==========

    Your abstractions need to model the domain accurately. I worked on a project where the abstractions didn't model the domain correctly, and it caused us terrible problems. It was a blotter application used in a bank for Credit Default Swaps. When we added new functionality to handle unwinds, we didn't understand that an unwind was an event on an existing deal. In our abstraction, we modelled the unwind as a separate deal.

    As we came to understand the business better we realized that we had painted ourselves into a corner. It made adding new functionality incredibly frustrating and difficult, with really convoluted code required to bridge the gap between our model and reality.

    If your map doesn't accurately represent the territory, you will either take longer to reach your destination, or lose your way entirely.

    Saturday, 19 February 2011

    Beautiful Code

    ==========
    Code Complete (Steve McConnell)
    - Highlight Loc. 3303-7  | Added on Monday, February 14, 2011, 07:55 AM

    When I am working on a problem I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong. — R. Buckminster Fuller
    ==========

    Programming into a Language

    ==========
    Code Complete (Steve McConnell)
    - Highlight Loc. 3021-31  | Added on Monday, February 14, 2011, 07:41 AM

    Visual Basic didn't support this convention directly, but my use of a simple programming convention—programming into the language—made up for the language's lack of structure at that time and helped keep the project intellectually manageable. Understanding the distinction between programming in a language and programming into one is critical to understanding this book. Most of the important programming principles depend not on specific languages but on the way you use them. If your language lacks constructs that you want to use or is prone to other kinds of problems, try to compensate for them. Invent your own coding conventions, standards, class libraries, and other augmentations.
    ==========

    Programming into your language, according to McConnell, means not limiting your thinking only to the concepts automatically supported by the language. Instead, think about what you want to achieve and how you want to achieve and then, if your language doesn't automatically support that way of working, define conventions that you will use to meet your objectives.

    This is a powerful concept, and something that every software craftsman should strive for. It's about personal discipline. Everyone knows that it's possible to write really hairy Perl code. It's also possible to write really beautiful Perl code.

    Clojure Complete

    ==========
    Code Complete (Steve McConnell)
    - Highlight Loc. 2851-56  | Added on Monday, February 14, 2011, 07:30 AM

    In the case of natural languages, the linguists Sapir and Whorf hypothesize a relationship between the expressive power of a language and the ability to think certain thoughts. The Sapir-Whorf hypothesis says that your ability to think a thought depends on knowing words capable of expressing the thought. If you don't know the words, you can't express the thought and you might not even be able to formulate it (Whorf 1956). Programmers may be similarly influenced by their languages. The words available in a programming language for expressing your programming thoughts certainly determine how you express your thoughts and might even determine what thoughts you can express.
    ==========
    Code Complete (Steve McConnell)
    - Note Loc. 2855  | Added on Monday, February 14, 2011, 07:31 AM

    think about clojure in relation to this. you define your own language.
    ==========

    Top of my list for personal development this year is to re-visit Clojure. Although I spent a few months programming in it last year, I have the nagging suspicion that I was actually programming in Java in Clojure. I want to learn to think in Clojure, and program in it idiomatically.

    This quote from Code Complete caught my attention because of the idea that in Clojure you write the language that you want to write your application in. Clojure is, in many ways, the ultimate language for writing a DSL, since there is minimal syntax and thus any functions and macros you write in effect extend the language. You are not limited to the words provided by Clojure - you can invent new words to express your thoughts.

    This is the sort of thing that I want to investigate further.

    I am very hopeful that the upcoming Joy of Clojure will help me to attain Clojure enlightenment.

    Apprenticeship Patterns

    ==========
    Apprenticeship Patterns (Dave Hoover and  Adewale Oshineye)
    - Highlight Loc. 668-70  | Added on Friday, January 28, 2011, 07:03 AM

    The journeyman is focused on building an ever-larger portfolio of applications that demonstrates his progress in the craft; he moves between projects and masters, seeking to diversify and deepen his portfolio; he seeks to elevate his status within the community; and he strives to become ready to be a master.
    ==========
    Apprenticeship Patterns (Dave Hoover and  Adewale Oshineye)
    - Highlight Loc. 1184-86  | Added on Friday, January 28, 2011, 07:44 AM

    Take the list of items from Expose Your Ignorance and strive to learn each one, crossing them off the list as you do so. This new knowledge you have may reveal gaps you hadn’t noticed before; don’t forget to add these things to your list.
    ==========

    I enjoyed reading Apprenticeship Patterns more than I thought I would. It provides some really great advice on how to progress in a career in IT, with a particular focus on ultimately becoming a software craftsman.