Tuesday, August 09, 2011

Dynamic Logic: The good parts

A while ago I'd bought a book on Dynamic Logic on a whim. I came to know of the existence of such a field through a dismissive comment from Spolsky (or was it Yegge?) and apparently thought it worth my money to see if it was indeed to be dismissed thusly.

The book lay unread in my book case in India for a few years until my wife brought it by mistake to Chicago, where it again lay unread. Finally as I returned to India, I put the book in the "throw/drop into building library" pile, but just couldn't do it because it was after all a book.

So while my favorite books took the slow way home via ship, this book that I didn't really care much for travelled with me and became my reading material for the initial days in India when I'd not yet unpacked and yet needed some material to read on my daily commute.

So what's dynamic logic all about? Turns out its a mathematical way of proving programs do what they're supposed to. The initial bit of the book is a refresher on the set and logic theory required to digest the rest of it, which is a whole lot of "here's how to prove that you can prove things about programs". I'm paraphrasing, obviously, but clearly it was a "How" book, not a "Why" book; which was fine because it was intended to be a textbook for Philosophy majors and CS PhDs apparently.

Since I was not reading it for those reasons, however, I applied Penrose's advice (cf Emperor's New Mind) of simply glossing over any math that I didn't understand and tried to glean the "Why" from the pile of "How". Here's what emerged:

  • Dynamic Logic harbors the hope of describing programs in terms of pure logic so that you can make assertions about the outcome of running them. I'm not sure how you could do that to real world apps.
  • However, the concept of attaching a first-order (or higher) predicate to a program so that the tuple (program, fact/predicate/rule) represents the duo of what the program is and what its execution means seems useful, especially in the kind of code analysis scenarios I'm interested in. It should be tempered with a suitable dose of allowance for leaky abstractions, however. Fuzzy logic maybe? I don't know.
  • Nowhere in the book did I see any attempt at interpreting anything larger than one program. And its a book of about 600-700 pages.
  • Towards the end was a section on Temporal Logic. This technique attempts to understand the dynamic nature of running processes by asserting their state at a particular point in time. This is markedly different from the Dynamic Logic method of analyzing the outcome of the finished process and is therefore suited to long (or always) running processes like Operating systems. To me this looked like an interesting way of modeling debugging.
I'm sure I'm missing a lot of the great parts in Dynamic Logic because of my engineering bias, but I'll take the program+fact tuple concept away with me.

Requiem for a capability-based UI framework

I recently bought a macbook and was somewhat surprised to be back in a world where you had to pay for software :). Needing an outliner and not wanting to buy one, I thought I'd build one myself; using that as an experience to try out Fantom - a language that I've been meaning to try out for some time now.

Fantom comes with its own UI toolkit - FWT - which is a wrap on the SWT framework; only since extended to handle Javascript output as well. Promising enough; so I set out to build my simple outliner. A few hours of copying from samples and looking up the API later, I had a basic tree displayed on my screen. That's when I hit the snag.

You see, FWT's Tree Control didnt allow editing the nodes, neither did its model. I didnt ask the Fantom community, but it looked like you had to build it. An outliner without an editable tree seemed pointless, so I stopped there.

More importantly, I stopped because building an editable tree control in FWT was at least one order of magnitude more difficult. Merely on my requirement for a directly editable tree control, the effort to build my app went from "Using FWT to quickly building an outliner" to "Figuring out how SWT does editable Tree Controls, then figuring out how the authors of FWT have chosen to interact with SWT ie, Fantom's FFI, making changes that fit with the rest of the FWT model/control concepts and optionally making sure it works on Javascript (if I wanted it to be a true FWT control)". From all the passive lurking I've done on the Fantom community, it's probable I'm a bit off in the level of effort and there's a better way than the doomsday scenario I've painted here, but my point is this:


  • Most UI frameworks are dichotomies: there are the standard controls and the custom ones. 
  • Standard ones are easy to use, custom ones are not. 
  • In fact the custom ones are not easy to build either because the UI framework typically provide a blank slate for display (aka the canvas) and a generic message pump (aka the event loop+event object hierarchy). Everything else is up to you-who-isnt-happy-with-the-standard-controls.
  • The upside: if the framework is popular/active, more custom ones become standard ones over time. So if you're willing to play the waiting game, you'll get what you want.
  • The downside: If you dont want to wait, or have the really cool interaction design that needs all-custom controls, you're down to building them from scratch yourself.
Aside: I measure UI framework maturity in terms of how close/far off it is from a standard editable tree+table control. All UI frameworks inevitably gravitate towards this control (because you WILL finally need one) and when you do, you're doing it because your customers/users need it - ergo you have reached maturity. I think I'll call this Vinod's UI Law - A UI framework is mature when it has a standard editable tree+table control :)

Capabilities
Anyhoo, the point of this post: Why can't UI frameworks be oriented more towards what the controls DO instead of what they ARE? Imagine a framework that describes its controls in terms of their attributes or capabilities; things like : 
  • Editable/Display Only, 
  • Aggregated (ie, represents a list of data elements at once), 
  • Drag/droppable, 
  • Executes a command, 
  • Selects a value (single/multi), 
  • Reads in text
Each of these capabilities brings to mind the set of operations that a control that has that capability should support. For example, an editable control should have a model.edit() and a view.onEdit().

The implementations of each of these operations are obviously dependent on the specific control, but the benefit of having controls defined this way makes them both easy to implement and replace/switch from. It also allows a "degrade path" for presenting controls. In a device with reduced resources, it might make sense to instantiate the simpler parent control that the much more capable child because they support the same interface.

Painting

Now onto the actual painting of the control itself. The common strategy by all frameworks is to provide a Canvas and a set of tools to draw on it. You can repaint() when you're done with the changes from recent events, and your control displays in the updated state. Can this be improved at all?

What if the painting of the control changes from a list of procedural steps to a description of the the final display? Eg, a button that was painted by drawing a rectangle, and then drawing some text over that rectangle would now be described as a "rectangle containing text blah". That way, low level APIs (think GL, SWT) would have to only be provided with the parsed form of the description as a set of draw instructions to execute.
Con: All this parsing will come at a price on performance

We don't need to stop there, however. What if version 0 of the control's entire display was an image, and each of its possible states were also images that are replaced (suitably scaled, etc) like sprites? We could even imagine the version 0 being retained to allow graceful degradation of the UI (in older versions of the device, for eg) similar to the Alt text in HTML. Another approach that the low-level API could take is to treat the description as the spec for an image map with regions that can be interacted with.

This still doesn't completely alleviate the "order of magnitude" problem I mentioned above. Somebody still has to write the low level API to translate the description of the control into actual display logic. However, it does make custom UI controls first class citizens, and it does so in an implementation-neutral way. As long as somebody writes a low level API that can parse the control's description, it can be displayed in a device.

Eventing
Onto Eventing. Eventing frameworks continue the dichotomy of standard and custom. Most (all?) UI eventing frameworks assume a standard set of events that are typically tied to the physical input and output peripherals that the system uses and provide direct support for their events. This is obviously useful in getting up-and-running quickly, but adding any new events is quickly relegated to the vendor providing the new input/output device/peripheral. Can this be improved? Consider the following contrasting ways of looking at the same event:

  • "Key pressed" vs "character input"
  • "Many keys pressed, followed by loss of focus" vs "string entered"
  • "value entered in day textbox within set containing month and year textboxes" vs "Calendar control's date region clicked" vs "Day part of day chosen"
  • "Save Button clicked" vs "Save Command chosen"
  • "Three finger salute" vs "Lock screen command chosen"
I've deliberately picked some known examples to highlight that we're already halfway there. We DO have "high level" events already in most frameworks. My suggestion is to elevate them to the only ones available via the API and provide a language for the compounding of low level (physical) events into such high level ones.
This way, the API is no longer tied to the specific capabilities and/or peripherals attached to the device in use.

So there you have it, my requiem for a capability-based UI framework:
  1. Describe controls in terms of what they do. The allowed set of operations on a control should be governed by a set of interfaces/mixins that its defined to follow
    1. Extending a control by adding a new interface/mixin should bring in default behavior of that capability
  2. Describe - not define - how the control should be painted. Let the implementation ABI know merely how to translate the description into the specific display
  3. Define the eventing API in terms or High level events and define a language to compound low level events into the high level ones. 

SICP: The beginning

Partly inspired by the recent HN survey on SICP and the related post about MIT moving away from it I looked for SICP at Sapna Book Stall the other day.

I was pleasantly surprised to find it at all considering the wall of computer books were decidedly career oriented; and more so because it was the indian edition that was priced at Rs.595 :)

So I've actually started reading it on my commute - and I'm beginning to see a glimmer of the difference to the approach that this book (and possibly Lisp) has to programming compared to other texts. Its speaking the same language, but not quite in the same way; not to mention that it manages to slip in some really cool things without even so much as a by-your-leave. Case in point: Page 21 has this exercise:
Observe that our model of evaluation allows for combinations whose operators are compound expressions. Use this observation to describe the behavior of the following procedure:
 (define (a-plus-abs-b a b) ( (if (> b 0) + -) a b )) 
Right there, without any ceremony is a statement returning a function - and an operator at that! And answering why is considered an exercise to the reader - nice :).

Hopefully, I'll be able to keep the steam up in reading this book; and possibly even trying the exercises out.

Bonus: A footnote had this gem from Alan Perlis: Syntactic Sugar causes cancer of the semicolon :)

Thursday, August 04, 2011

New paradigms in wiring code emerging

It seems to me that ideas happen at the same time to many people. I've been thinking of ways of wiring code other than stacking 'em one after the other, and I find Coplien talking about DCI (although in fairness his ideas are a bit old - I just discovered them now), and today this:

The title's a bit dramatic, and the content seems original but is probably not entirely new(Google and ACM search pending).

What excites me, however, is:
  • Wiring code is being treated as a first-class problem
  • Solutions are recognizing the problems of being in Nounland (thanks Yegge), but not knee-jerking into functionville entirely. Solutions are emerging that are somewhere between, where the common coder lives!

Wednesday, July 13, 2011

Tip: Disconnecting Chrome from IE's Proxy settings

Add --no-proxy-server to the command that starts up chrome. This way chrome will not use any proxy settings.

There's also a --proxy-server option if you do want it to use settings different from IE.

Thursday, June 30, 2011

Basic tools for analyzing Large Codebases


  • Graphs: Everything related to code is a graph at its core. Code has attributes, it relates to other bits of code in varying levels of hierarchy and entanglement, and the understanding of this requires graphs of various kinds to be built, visualized and used.
  • History/Telemetry/Timelines/Versioning: What happened to the code MATTERS. Especially since the translation from written to running code is a lossy process. From another POV to understand how the code reached its current state, you need to know its previous states. From yet another POV, to understand the running state of code requires maintaining history of its execution states
  • Visualizations: Plural emphasized. Code is a many-dimensioned thing. Not everyone can understand it in its entirety and not all the time. Slices of the beast are a must.
  • "Glue": Some language to annotate the code with to "fill in the gaps" from all the lossy translations involved. The simplest is human language in the form of comments.

Thursday, June 23, 2011

Flexible Software

Ever wonder how easy or difficult it would be to create a DIY version of anything?

America has a great DIY culture, so there's a lot of commercial support for kits that allow you to build or fix anything from reading glasses to whole kitchens. This is not how it works in other places where labor is cheaper and the tradespeople build and fix things. In such places, the interfaces (for lack of a better term) that products allow assume expertise on the part of the person using it.

Simple example: the bicycle is largely a recreation vehicle in the US. As such most of its parts are easily adjusted with knobs and such end-user friendly means. For the most part, you'll rarely have to go into a bike shop for a repair. They even have kits to clean your chain! This would be unheard of in a place like India mainly because there're tons of bicycle repair shops and people dont need the user friendly interface.

But I digress. The point I'm trying to make is that designing a product such that it can be broken down by somebody else than the original creator (or somebody skilled in the products innards) requires a different kind of thinking than just producing the product. A DIY robot kit is more difficult to make than a regular one. The key features added are:
  • the ability to be broken down into pieces with well defined interfaces
  • the ability to integrate with other pieces to form the whole product.
That's the physical world; and yet we have quite a large DIY capability in general.

Now take that same concept to the world of software. Why do we still not have long promised Software ICs? I think we know the answer to that one: because my concept of component that does logging (to pick a mundane, yet excruciatingly relevant-in-terms-of-my-point example) is not the same as yours :).

But there's more than one way to skin that cat. We dont necessarily need a universal agreement on what constitutes a specific component; we just need to ability to easily take components in and out of the software as often and appropriately as required. There in lies the rub, however. Our current means of doing this in increasing order of cost are:
  • Configuration: which is the hardwired ability to switch between known behaviors of a component
  • Code Change: which is the hard ability to change the behavior of a component from the current to the desired. This is the snapshot based development that I've blogged about before.
  • Integration: which is the tying together of fairly coarse components with known behavior to realize a larger, compound behavior. The integration itself could be via configuration (better) or code change (not so good)
There's a reason for integration being at a large enough scale: integration is hard due to the mine != yours problem mentioned above.

Is there a solution? I think languages should develop ESB-like capabilities, and allow code change to be applied descriptively instead of as a stream of editor actions.

More on this later.

Wednesday, June 08, 2011

First time parents: an app rollout story

I've seen that teams involved with the first time rollout of an app are like first time parents. So pardon me while I mix more metaphors that are required to get the message across:
  • Its MY baby, so how can you possibly know whats right? I let you hold it; doesnt mean you can code to it in any way except MINE
  • If the baby cries, it must be a critical. Doesn't matter that you're an experienced parent who's seen this before on your App, and know it affects less than 1% of customers, and therefore will feely admit that while the issue is a critical, it need not be addressed NOW
  • Related: My baby's needs come FIRST. That means before anything else. Especially yours. Because I said so. So there.
  • My baby is special, so it needs to be eased very very gently into anything new - especially the big, bad world. Maybe we can get him out of the door an inch a time, so he'll be ok with it. Oh you just went ahead and threw yours in the pool and he's doing fine? Well, we'll not have any of that around here.Our production launch will have many interim milestones, thank you very much!
I can keep going, but you see what I mean? I say read Ship It, and see how things work out. You might find the second time much easier. Unless of course, you are bent on doing everything right this time around so we have that perfect child :)

 The killer combination: A team made of some people who've never built anything and some that have built exactly one thing before and are dying to fix that in the successor!

Note: I've found that there are levels of noobie parenthood. People who are completely sane and rational at one level will make an exception and become noobs for that pet/key/most important project which apparently transcends normal levels.

A runtime that does static/dynamic analysis

Traditionally, code analysis has been done offline (statically) or online (debug or test in prod). In either case the effort has been to minimize the impact of analysis overhead on execution of code. Ironically, its this exact execution state that we need to know and understand better to improve and maintain software.

In the database world, its common for the runtime (ie db engine) to maintain statistics of query execution and use that to better plan future execution. Why not have a code runtime that does the same?

Again, not a new concept - cpus have had this for ages. What about App Servers, though? Imagine having a code analyzer attached to your running code that not just tells you where the hotspots are, but also points out the tangles in your code and so forth?

The advantages are obvious: no additional tools required, code analysis in running code, etc; as are the disadvantages: performance penalty being the main one. However, I really have to ask: We've come a long way from expecting "running on bare metal" mode. Why not this additional step? In a long enough time line wouldn't the benefits and advances in hardware outweigh this?

We've seen the advent of opinionated languages. I think its time for an opinionated App Stack.

Implementation note: Steal Fantom's concept of conceptual package = deployment package.

Sunday, May 15, 2011

Code as workflow


Code as workflow

At work, we have a couple of core components that are essentially workflow engines. I call them workflow engines because of the following properties:
  • The components house named business processes
  • The processes have granular steps and they are named, too
  • Data is passed between steps via a shared context - essentially a data bus
  • The processes may be long lived, and therefore have asynchronous steps
This model, while decidedly a leaky abstraction in implementation, got me thinking about plain old code, though:

Take the smallest organizing unit of modular programming - the function. It has a name, it has granular steps (although they are not named) and data is passed via a shared context - the stack.

I mention the similarity between the function and the concept of a workflow only to highlight that such a parallel is possible. In principle, any organizing unit - the class, the program, package or application could be modeled as a workflow, IMO.

I contend, therefore: At a suitably small scale, all code can be treated as workflow.

What benefit, if any, do we have with taking such a view of code, though? Business logic is expressed as workflow when we know the following:
  • The individual steps have meaning to the business
  • The overall process is likely to change over time, the implementation of the process is therefore required to change quickly to reflect the new reality.
  • The change usually causes reordering of steps, removal of steps, or introduction of steps. The process still remains the same, as does the implementation logic within each step.
It therefore behooves us to create a framework where the steps are named and their communication is through a standard data bus so that they can be easily removed/updated/added.

Now think of code in general, and read out the reasons I mention above for needing workflow engines. Except for the scale  and the "implementation logic remains same" part, they're the same reasons you have cod around as well. 
  • If you think each line of code doesn't have business meaning, you'v obviously not had a big impact bug that was fixed with a one-line change.Admittedly, not all lines have business meaning, however.
  • Code does need to change constantly to reflect business reality
  • All edits on code reorder the steps, remove them or add new ones. In addition, we also typically change existing steps in place. Aside from this difference, there's essentially nothing different between editing code and editing a workflow, and even that can be modeled as:
update = delete + insert
I'd go so far as to call normal code a form of "complied" workflow - it IS a series of steps that have business meaning, its just that we've deemed that particular series of steps as optimal enough that no change is expected. Until the next time we change our minds, that is.

What if we treated code as workflow?
 Imagine edits being made on code exactly as if it were a workflow where the operators available for editing are not at the character or word level, but at the step level. The developer would decide how to reorder steps to achieve the newly expected functionality, or if the better approach would be do away with the entire function (read superstep in a hierarchical workflow). Imagine the following kinds of operators:

  • Add step
  • Remove step
  • Update Step ( = remove + add)
  • Promote step  (up one level)
  • Demote step (down one level)
  • Coalesce steps
  • Explode step
As might be obvious, what we do today with our editors is the textual equivalent of these. The advantage of this conceptual hair splitting, however, is that we now have a semantic model for changes made on code. With suitable expansion, for example, it could be shown that promote step is the process of creating an abstract class (or interface).

Imagine next, an environment where changes to code are recorded as such a series of steps. That series of steps is itself a workflow. This opens up a lot of interesting possibilities:

  • A version control system that records changes to code as these workflow steps
  • A build/deploy system that allows code migrations similar to current forays into automated data migration (like Rails' activerecord). Essentially deploying a new version of code involves running code that changes the existing version in place, not replacing the old version with an entire new snapshot containing the new version
  • Pattern recognition applied to a set of such code edit workflows; and many similar code analyses that can now be done on the change stream itself, not just the end product.
  • This is obviously the tip of the proverbial iceberg.
All's not well in workflow world, though
In almost every workflow-based system/framework I've seen - be it in house like the ones mentioned above, or commercial ones like Webmethods, I've seen some major issues:
  • Polluted Data bus: Since the shared data bus is the primary means of communication, authors of individual steps have no trust on its contents as a whole. The do trust their immediate inputs, and will almost always take defensive copies of the input (in whole or substantial subsets of it). Its quite common to find multiple copies of the same data in the data bus, which obviously leads to inefficiencies and slowness.
  • Leaky Abstraction: Implementing a clean workflow is not easy. It requires discipline in using the data bus, and that alone as the communication mechanism. Any out-of-band communication between the steps means the premise of being able to take steps out, or reorder them is lost. Any framework built on a general purpose language will always have to contend with the sneaky programmer who got around the pesky data bus limitation :)
These are the reasons I shy away from asserting that code IS workflow. Its useful to think of code AS workflow, however. The baby in all of this bathwater is: "Can we use the concept of workflow to model changes to code in a useful way?"

I think yes.


The trail to the big ball of mud


  • Check out the first version of an app
  • Run code analysis tools like Structure 101 or Lattix on them, and setup rules for architectural violations
  • Repeat for each version to date
  • Project the results on a time-lapse display tool that shows change in architectural violations over time
This will show you:
  • The inflexion points where the implementation deviated from the original intent
  • Impact of adding new resources
  • Impact of not having policy manifested in the system/ not having documentation
  • Impact of tribal knowledge
I posit that this will also show you:
  • Why thought leaders that build great systems need not always make great teachers
  • Why tribes/inner circles are a bad idea
  • Why NIH is a bad idea
  • Why publicly available implementations/frameworks are better than proprietary ones in general
  • How a well documented proprietary framework with a clearly manifested policy could be a long way from becoming BBOMA. Although you might not find very many examples of such a framework :)

Monday, May 09, 2011

I would LOVE to be a tool developer, but...

developer faces a problem as part of normal app development
developer fixes the problem
developer faces the same problem again.
developer fixes the problem again.
developer faces the same problem 5 more times
developer builds a tool that automates the fix

time passes

tool gains popularity
developer now is a tool developer and spends all his time on the tool

time passes

tool gains even more popularity
developer is now part of (or owns) a company (or opensource project) whose product is the tool

another developer has a problem in his app domain that should be a feature on the tool
unfortunately original developer will never see this because his domain is now the tool itself.

Big Ball of Mud Architecture is like cancer; tools and policy are like chemo

..meaning they're the best answer we have, and all they can do is inhibit the spread.

Any enterprise has software that has technical debt, and it will keep increasing.

Tools that will help:

  • Visualization of the architecture - logical and deployment; show multiple views.
  • Tools that inhibit deviations from the blessed architecture instead of tribal control
  • Tools that embody promised features in the code
  • Code review via tools
  • Incremental code quality tools
Policy
  • Reduce impedence mismatch between the logical and the physical namespaces. eg: java package namespace is different from the deployed jars and that namespace.
  • Map source control artifacts and deployment artifacts - make it 1-1 as much as possible
  • Make setup and run for newbies as easy as possible. Not ok to have your bootcamp say "this is a difficult environment. Deal with it". Early success is a big confidence booster.

Friday, April 15, 2011

Evolutionary vs Snapshot development

When I suggested to somebody that they can implement a subset of the true solution for now, with the stated intent that the true solution will be implemented later, i realized that there was no way to retain in the codebase itself this future intent.

Current development is all snapshot based -and the tip version at that. There is no way to state - in the codebase - that we intend the current state to be a waypoint to some final architectural/design destination.

BDD is essentially a means of formalizing requirements into the codebase, and Devops is essentially a means of formalizing the deployment of code into the codebase; why not take the next logical step and add tracking the evolution of the code itself into the codebase? Why use an issue tracker for this?

Coming to think of it, why not make this a language feature?

Thursday, April 14, 2011

Nagivation

This is one of those slip-of-the-tongue things that stuck in my head. I happened to say (in my head) nagivation instead of navigation, and then it struck me that this misspoken word could well be a neologism.

Nagivation: Irritating steps that websites put between you and your goal to better their interests.

I can already imagine an eggcorn to it too:
Nagevation: Avoiding nagivation links

Isn't language fun?

Aside: This is why English is vibrant and alive and highly structure languages such as Sanskrit aren't.

ಸ್ಥಾವರಕ್ಕೆ ಅಳಿವುಂಟು ಜಂಗಮಕ್ಕೆ ಅಳಿವಿಲ್ಲ
as Basavanna would say!

Goldberg Maps

This is one of those wacky, no-practical-use ideas. You have been warned.

The idea is to create a map application (platform doesn't matter) that figures out the most contorted possible route - a Rube Goldberg route from A to B, if you will.

Extra points for using multiple modes of travel that makes things more difficult, or costly (like using toll roads most of the time even when A & B are round the corner from each other)!

Should be challenging, methinks :)

Sunday, April 03, 2011

Mirah: first impressions

I see Mirah in 3 perspectives:

  • As a simpler Java: I should review key features from Java to expand on this.
  • As a Ruby in Java: I should look at the Mirah implementation more to understand how this works, especially meta-programming.
  • As an experiment in language implementation with the plugin architecture of its toolchain. This is interesting from a language design/implementation perspective.
In all, an interesting language. I think abu will be a good candidate to use Mirah.


Thursday, March 24, 2011

Dependency Hell: There has to be a better way

I have just given up on trying to install Open Head Tracker - an open source eye gaze tracker. I've been researching head tracking software to see if my aunt who's currently paralyzed can use something like this, and naturally started checking out the open source offerings available; and given that she's in India, I wanted to look for a Windows solution as that's easier to purchase, service etc for non-technical people.

So open gazer is based on technologies that are cross-platform: Python, Numpy, OpenCV and Qt. The original was tested on Ubuntu, and the author expresses the sentiment that since all the underlying software is cross platform, and the software itself is in python, it should work on other platforms.

He's right in principle. In practice he is so wrong its not funny.

Unlike the linux world, you usually install binaries on windows; you just do. Its a wimpy, windows-y thing. Sorry. All windows software comes that way - and then you deal with Registry hell :)

And although each of the packages above were available as binaries, they were just not a compatible set. 2 days of trial and error later, I got the Mingw compiled release of the right version of each package to be installed and tested individually.

That didn't mean they worked together to show up Open Head Tracker's display. I still get a segfault on cvResize (after debugging through the source - thank god for scripting languages!) and I have no clue why. The only option remaining is to disable use of SSE.

The only way to do that? Compile from source.

If my experience with trying to build Chrome is any indicator, that's another wild goose chase into build-time dependency hell.

There has to be a better way!

Sidebar: The last two days have been a heady roller coaster ride through Numpy and OpenCV code, however. I dont understand most of it - mainly because I was just trying to get Headtracker to work, but there's some cool stuff in there, including in Headtracker's deceptively small codebase. Qt's demos make it look really cool too - too bad the days of the Desktop are done now. 

Sunday, March 20, 2011

Pinning PortableGit to the Windows 7 taskbar

Microsoft, in all its sagacity, decided that you couldn't pin batch files to the Windows 7 taskbar - something that people have been doing for ages, and have come to like.

Googling for the problem showed three main approaches:

  • Converting batch files to exe - bad
  • Putting all batch files in a folder and making a toolbar out of the folder - less bad but still yucky
  • Tricking W7 into thinking its an exe by opening up the hidden folder that contains the taskbar (Win-R, "Shell:user pinned" will get you there), and adding the shortcut manually. This didnt work except for briefly adding said shortcut to the taskbar, which disappeared soon.
Since all I needed was to have a one-click access to Portable Git, I thought maybe the executable could be called directly, so I ran git-bash.exe to test it out. pwd and exit would work, but not even ls. 

So then I looked at what git-bash.bat did extra. Turns out all it does essentially is to add some params to the call to the executable. So here then, is the solution:
  • Select %PortableGitHome%\bin\bash.exe, and drag it to the taskbar
  • Rt click to show the pin menu, and rt click again on bash to reveal the properties window.
  • Change the Target to "%PortableGitHome%\bin\bash.exe --login -i"
  • For bonus points, change the icon to a Git-specific one. You could use the one from GitGUI, or a free alternative one
Note: %PortableGitHome% is not a real variable, replace with your install dir.

Thursday, March 17, 2011

TDD is an all-or-nothing proposition

I've been reading "Growing OO Software with tests" and trying to implement TDD practices in my projects, and I arrived at the sentiment that's the title of this post.

Let me explain.

Non-TDD is easy and alluring because you can choose to ignore certain errors. This is decidedly unprofessional, but in the early stages of the project its invaluable. When you're trying to get your feet wet, and feel around the solution space, you DO want to know the big things in the design you're missing, but you dont want to know EVERY thing you're missing.

Since TDD implies executing code, you do have to fix everything that you've missed before you get to the interesting bits; and that is why I say TDD is an all or nothing proposition - you have to fix each and every bug in your straw man code before you can get it work.

Usually, some of this extra burden is taken care of by the TDD framework that you're using - a typical TDD tool assumes a particular environment (eg, Rails), and has the support that makes most of this go away, but for environments that don't have such support - Javascript-in-browser or console apps come to mind - building the framework while building the app gets to be tedious and frustrating.

That's not to say that even with TDD tools this burden doesn't go away - its just lesser. It'd be much nicer if you could "ignore" errors that aren't crucial to early stage prototyping. For now, I solve the problem by having a prototyping phase/spike which isnt TDD based where I flesh out the solution concepts in throw away code.