Monday, August 22, 2011

On Software Testing and the case for the Common Test Scenario Database


TL;DR


As a participant (and sometimes contributor of ideas) to Test Automation efforts (Strategy, tool selection and implementation), it has been my long-standing opinion that the true gains from automation can be achieved only when Test Scenarios (enshrined as exemplar test data) are a heavily reused resource across the organization. This page is an attempt to "arrive" at that opinion by progressively optimizing the software testing process.

I take the example of testing the hotel search feature and progressively optimize it through 4 stages to illustrate the value of each such optimization; and the value of shared test scenarios in particular.

What is Software testing?


Software Testing is the art and science of validating that a particular piece of software behaves as expected. Since most words in the previous sentence are loaded with meaning, I'll dissect it:
  • Art and science: Art because some of it is based on the skill of the tester and science because most bits are tractable into well-defined, repeatable procedures with predictable outcomes
  • Validating: This might involve the atomic step of input-process-output, or a sequence of many such atomic steps (typically known as "following a script"). Each such step (or steps) entails comparing an expected value (or more generally outcome) with a known one
  • Expected: This implies that there are some requirements that the software is supposed to meet which is an accumulation of the most important (or all) of the comparisons mentioned above.

A Concrete Example - Testing Hotel Search functionality

Any travel website has a hotel search functionality. You enter a destination, start and end dates and number of guests; and the website returns a list of hotels. Each hotel card has some details (name, location, address, picture, reviews, rating, description etc); and the list itself has some details (count, sort order, #pages, etc).

Notice also that there are some implicit inputs (eg: choice of POS, choice of currency) and some implicit outputs (eg: sort order).

To truly test this feature, you need to validate that:
  • The functionality is right:
    • The list is as expected (has the expected number of hotels which are in the expected order, paginated at the right place, etc)
    • Each hotel card is as expected (Has the name as expected, image shows up, description is correct, etc)
  • The display is right:
    • Visual characteristics for each data item is correct
    • No visual elements overlap
    • And so on
  • Adding the feature didn't break anything else:
    • tests on features that already exist pass
    • tests on features that are in-flight at the same time and targeted to the same release pass
  • The performance is within acceptable limits

Focusing on functional testing alone for a moment, we see that:
  • Each combination of values that we input produces a unique output; and
  • Each such output has details that need to be validated against expected values.

The universe of all things that need to be tested therefore is of the order:
             Number of input combinations  X  Size of output for each input combination
Now, for the hotel search scenario,
            Number of input combinations = Product of (Size of the set that an input belongs to) for all inputs.
And
            Size of each output = Size of result set details + Size of details for all hotel cards
Note: inputs include both implicit and explicit ones


Using the details mentioned above and ignoring the etc's for now,

Size of inputs for hotel search
Number of inputs = 2 implicit + 3 explicit = 5
Product of sizes
= Size of the set of destinations
X Size of the set of Possible Start dates (and invalid ones)
X Size of the set of Possible End dates (and invalid ones)
X Size of set of number of guests (subset of Integers)
X Size of set of POSs allowed (subset of integers)
X Size of set of Currencies allowed
 
= 50000 (assumed)
X 365 (assuming a year of allowed booking)
X 365 (assumed similarly)
X 4 (assumed to be max allowed guests per booking)
X 1 (assuming USPOS)
X 1 (assuming USD)
Size of each output
= 3 result set details + N x (7 hotel card details)
 
Where N = size of result set itself

If N = 100, the Test Universe = 50000 x 365 x 365 x 4 x 1 x 1 x (3 + 100 x 7) = 1E13 Tests
Onto this set of 1e13 Tests, we'll have to add the Regression, UI Validation and Performance Tests as well.


Sidebar for the mathematically inclined
 All testing can be considered validation of functions. Given an abstract function y = f(x), testing can be considered validation that for all x in X (the input set), there exists the expected y in Y (the output set)
The domain of the function represents the size of the input and the range of the function represents the size of the output. The Cartesian product is, therefore, the set of tests to be conducted to validate the function. 


Obviously, this is a lot of testing to do; and if we're actually able to do all of it, that would be Exhaustive Testing. Also obviously, anything larger than the simplest feature would quickly be intractable due to the combinatorial explosion of tests required; so we apply the "art and science" part and try to pare the problem down a bit. I'll focus on the functional testing here, but most of the concepts apply to UI validation and Performance as well.

Before we start, however, I'll define some factors to evaluate the efficacy of our optimization with:
  • The number of tests required to be run (or reduced as a result of the optimization)
  • The cost of running the tests (in terms of time, resources, $, etc)
  • The overall quality of the product is still within acceptable limits

Optimizing testing - Round 1: Scenario Based Testing

This optimization concept is very simple - reduce each set mentioned above to a representative subset. Each element of this subset would "stand for" or represent an entire class of values within the original set. A success or failure of the chosen value is deemed a success or failure of the entire class.

To continue the Hotel Search example, the inputs could be reduced to the following scenarios (for example):

Destinations
  • Top 10 destinations
  • 1 non-US destination
  • 3 destinations with "known issues" or special edge cases
Booking Dates
  • Last minute bookings (1 date in the next 3 days)
  • Planned bookings (4 dates in the next 2 quarters)
  • Peak date bookings (2 National holidays)
  • Weekend bookings (2 weekends in the next 2 months)
Guests

  •            4 is small enough a number to test all combos, but we could still pick a subset, say 1 and 4 only
With this, the input size drops to 13 x 9 x 2 = 234
And the test universe becomes 234 x (3 + 100 x 7 ) = 164,502

That's still a huge number, but 8 orders of magnitude less already! We could optimize this further by reducing the validation on the output values if we want to. Realistically, we can probably get away with checking 4 of the 7 details for the first 25 hotels; and checking the result set details just once throughout. So the test universe reduces to:
234 x ( 25 x 4) + 3 = 23,403

How has this impacted our evaluation factors?
  • The number of tests required to be run has obviously come down.
  • The cost of running each of the tests still remains the same; we haven't optimized that yet.
  • The resultant overall quality depends on the scenarios chosen. If we've chosen well; it should be within acceptable limits.

Note that there are more algorithmic ways of arriving at a subset of tests; Orthogonal Array testing to name one. I'll not elaborate on this further as the optimization is the same in principle - that of reducing the total number of tests required in validating a feature.

Similarly, on the regression testing side of the house, scenario-based reduction of tests can be done by carefully analyzing the areas that changed code is likely to impact; aka Impact Analysis.

Optimizing testing - Round 2: Automation

When you have many features similar to the one depicted above, scale effects come to bear:
  • The total number of tests to be run is still a large overall number
  • The cost of regression is a constant despite reducing the regression test suite using impact analysis.

The optimization to counter this is conceptually simple - relegate repeatable tests to a machine so that human cycles can be spent on the unique ones. This is easier said than done in practice; and the quickest way to get started is - surprisingly similar to BDD precepts - Outside In. That is, start at the outermost layer and automate tests at that layer. Work gradually inwards; or even not at all. Automating regression alone can have significant benefits.

One of the biggest issues with automation, however, is that you miss out on the human ingenuity bit. Scripts WILL break if data changes over time, so environments have to be stable; something that the human tester would easily sidestep by validating "outside the box" that the changed data is indeed still valid.

To continue with the Hotel Search example, assuming both the human and the machine take the same time for a test, the gain in human cycles due to various levels of automation are:

Feature
Manual Tests
Human cycles saved with 10% automation
25%
50%
75%
Hotel Search
23403
23404 * .1 = 2340.4
23404 * .25 = 5851
23404 * .5 = 11702
23404 * .75 = 17553.0

Reviewing our factors again, we see that with this additional optimization,
  • The number of tests required to be run by humans has come down again and the tests run by machines can be run repeatably so.
  • The cost of running each of the tests has reduced, but the cost of maintaining test environments went up as both manual and automated environments have to be kept running.
  • The resultant overall quality still depends on the scenarios chosen and our trust in our automated tests. If we've chosen well and trust our scripts; it should still be within the same acceptable limits.

Optimizing testing - Round 3: Component based testing

The cost of maintaining test environments mentioned above is typically the tip of the iceberg. All testing espoused to this point has been strictly end-to-end, ie, the environment has been a live one from the UI all the way to the database (or back-end). There is a non-trivial cost associated with maintaining these environments; and a collateral cost of maintaining scripts (or known data for use by the scripts) as those environments change. Additionally, some kinds of testing may not be possible in live environments. Booking scenarios are typically such tests - contractual obligations or the cost of test bookings may deter such tests from being done in a large scale or at all.

In addition, end-to-end testing forces the entire organization into a train wreck of dependencies. Since all testing is done from the UI, all code must be built and integrated before ANY testing can start. This not only delays testing, it also puts pressure on changes to the inner layers of the application - that code has to be completed WAY IN ADVANCE of the UI code, but cannot validate their output until the UI is done.
Component testing attempts to fix these issues by testing each component
at ITS interface, not at the final user interface. That way, the owners of that component know for sure that they produce valid output for given input; a large live environment need not be maintained; and the validation of a test scenario is spread across multiple component tests which together comprise the larger validation.

Component testing almost always predicates the mocking of dependent components because the cost gains are not realized otherwise. That is, if A -> B -> C is a string of components involved in a particular test scenario, C must be mocked out to test B and B must be mocked out to test A; otherwise we've taken on the additional job of maintaining a separate instances of A,B and C solely for component testing purposes, thereby increasing cost of maintaining environments more than without it.

Component testing also typically requires some means of creating mock data - manual means will not suffice; especially if the request-response payloads are huge object graphs.

The choice, adoption and usage of an organization-wide mocking framework is therefore a non-trivial task and I will not go into the details of how to achieve this. I will, however, analyze the impact of adopting such component testing on the evaluation factors mentioned above.

To continue the Hotel Search example, a hotel search typically involves a string of internal components:
                                                               |------------> GDS
UI -> Business  -> Business  -> Business  ->    Back End-------|------------> CRS1
Dispatcher        Facade     Logic Executor  Abstraction Layer
                                                               |------------> CRS2
(Some details may be missing; sorry. I'm trying to make a larger point here).

Let's take the following Test Scenario:

Input
Expected Output
Top Destination (LAS), Weekend (start: next Friday, ret: next sun), 1 guest
  • 1st page has 25 hotels
  • 1st hotel is Caeasar's Palace @ $100
  • 2nd hotel is MGM @ $125
  • …and so on
…and break it into component tests:


Component
Given a test script that provides this input
..should provide this output
..using this mock data
UI Layer
LAX, Next fri, Next Sun, 1 guest
  • 1st page has 25 hotels
  • 1st hotel is Caeasar's Palace @ $100
  • 2nd hotel is MGM @ $125
  • …and so on
  • Business Dispatcher response containing the 25 hotels
Business Dispatcher/ Facade
LAX, mm/dd/yyyy,mm/dd/yyyy,1
+ other Dispatcher required params
Arraylist of Business Layer objects
  • Executor response containing the 25 hotels
Business Logic Executor
LAX, mm/dd/yyyy,mm/dd/yyyy,1
+ other Executor required params
Arraylist of Executor-specific objects
  • LAX-to-internal-location-object response
  • Back end Abstraction Layer responses
Back end Abstraction Layer
LAX, mm/dd/yyyy,mm/dd/yyyy,1
+ other Back end required params
Arraylist of Back end Abstraction Layer objects
  • Back end-specific responses (1 per link)

We'd have to do a similar exercise for each such scenario identified before as required, but if we did, the impact on the factors would be:
  • The number of tests required to be run by humans has come down again and the tests run by machines can be run with lesser resources.
  • The cost of running each of the tests has reduced; so has the cost of maintaining test environments as live environments no longer need be maintained.
  • The resultant overall quality now depends largely on the fidelity with which the end-to-end scenarios have been mapped to component tests. If there is a high correlation between the two, overall quality should still remain within the original acceptable limits.

This last is not easy to do for various reasons:
  • There needs to be a coherent effort to ensure scenarios matchup between components; else component owners could define their sphere of influence differently from the scenarios deemed organizationally important.
  • The larger the size of mock data to be created, the more difficult it is to create it with high fidelity. Shortcuts such as record-replay mechanisms might help, but only if they've been sanitized to remove volatile data and then made generic to match the expected scenarios.
  • Ownership is shared; so division of labor should be clearly defined via policy. For example, each component owner should be responsible for her front end, ie, provide mock data and a set of regression test scripts to his clients; she can therefore rely on her dependents to do the same. Without such a policy, key pieces of the puzzle will be missing and the overall quality will suffer.

Optimizing testing - Round 4: Common Test Scenario Database

These issues with implementation of component testing may even lead to a regression back to manual testing. The crux of the problem is that the cohesive force of the end-to-end test is lost in component testing very easily.

The central idea with the common test scenario database is retain the benefits of component testing while bringing back that cohesion via data: we need to ensure that test data that is distributed across the various component test scripts still have the same tie-in to the original scenario. That way, every component owner in a particular scenario refers to the same scenario using the same language. While we're at it, it would also be beneficial to change the mock data in two ways:
  • Replace significant pieces of live data with values that stand for the class of test data that we will use in the specific scenario. E.g., the destination data item when used in a scenario where it represents a top destination could be given the canonical name "Top Dest1". Alternatively - assuming this is clearly understood company-wide - a real value can be used as a canonical one ; eg, in this case "Las Vegas" could stand for top destination; but then it shouldn't be used in any other scenario.
  • Clear out any recorded values from the mock data so only known values remain. This eliminates side effects from remnant data but requires a higher degree of discipline.

The larger change would be to introduce full-fledged exemplar data sets for application domain concepts that cannot be confused with live data, but clearly denote the exact scenario in which they can be used; and use policy to drive adoption of these exemplar data sets as the mock data backbone.

To continue on the hotel search example, the first step would be to define the following exemplar data:

Concept
Exemplar Data
Comment
Top Destination
LAS

Regular Destination
USDEST1

Special Destination
Acme Cozumel
Added "Acme" to Destination to call out that this is a test value
Next Week Friday
(Computed Value)
Mock data framework should be able to generate such values and respond appropriately
Hotel Chain
Acme Hotels LLC

Hotel
Grand Acme Ritz Chicago

Top Hotel @ Top Destination
Acme Hotel and Casino


The component test from before can then be rewritten like so:

Component
Given a test script that provides this input
..should provide this output
..using this mock data
Web-wl
LAS, Next fri, Next Sun, 1 guest
  • 1st page has 25 hotels
  • 1st hotel is Acme Hotel & Casino @ $100
  • 2nd hotel is Acme MGM @ $125
  • …and so on
  • TBS response containing the 25 hotels
    (Note: other hosts required to bring wl up ignored for now)
TBS/Plugin
LAS, mm/dd/yyyy,mm/dd/yyyy,1
+ other TBS required params
Arraylist of BookProduct objects
  • HSE response containing the 25 hotels
HSE
LAS, mm/dd/yyyy,mm/dd/yyyy,1
+ other HSE required params
Arraylist of objects
  • Market/Markup response
  • Supplier Link responses
SL Host(s)
LAS, mm/dd/yyyy,mm/dd/yyyy,1
+ other Supplier Link required params
Arraylist of objects
  • SL-specific responses (1 per link)

More importantly, when a second scenario has to be mapped to component tests, the exemplar data table above should be checked to see if the concepts in that scenario already exist, and if so they should be reused.

So, to convert the following scenario:

Input
Expected Output
Top Destination , Peak Weekend, 4 guest
  • 1st page has 25 hotels
  • 1st hotel is Acme Hotel & Casino @ $100
  • 2nd hotel is Acme MGM @ $125
  • …and so on

...into component tests, the following data items will have to be reused:
  • Top Destination (LAS)
  • Top Hotels (Acme Hotel & Casino, Acme MGM)
…and some new data items will have to be added:
  • Peak Weekend (Thanksgiving dates, for eg)

…which will further be reused when automating the scenario:

Input
Expected Output
Top Packaging Destination , Peak Weekend, n guests
  • Acme Mexico Dest1
  • Labor Day Weekend dates
  • 2 guests
  • 1st page has 25 hotels
  • 1st hotel is Acme Cozumel Resort1 @ $100
  • 2nd hotel is Acme Cozumel Resort2 @ $125
  • …and so on
.. Which will further require new data items to be created, and so on.

When a new feature is added, say separate pricing for children or prepaid hotel rooms, that's the time for a completely new set of hotel chains and hotels to be created.
Over time, this practice of reusing test scenarios results in the creation of the Test Scenario Database which becomes the lingua franca across the organization when talking about Quality issues.

Let's see how our measuring factors score with this optimization:
  • The number of tests required to be run by humans hasn't changed since the last round.
  • The cost of running each of the tests remains as before. If there were any collateral increase in costs of using live environments due to inability to trust component tests, that is removed however.
  • The resultant overall quality still depends largely on the fidelity with which the end-to-end scenarios have been mapped to component tests; but there's a direct correlation possible because the organization now has the "common language" of the scenarios enshrined in the test data. This is the killer quality of the common scenario database.

Notes on implementation


  • Just as with automation, creating a Test Scenario Database is easier said than done. Policy from "up top" will certainly help; but a grassroots approach is also possible because the database can be built one scenario at a time. It does require a few enthusiastic converts, but some key component owners being convinced will create the kernel of good, reusable (and reused) test scenarios which can then be supported via policy.Once their use is common, network effects will take care of their popularity.
  • The Quality Organization should own the Test Scenario database and gate-keep use and reuse. Developers may create test scenarios, but should get approval from Q.
  • Component owners should be responsible for their component and their front end interface; and expect their dependents to do the same. That way they have the responsibility towards their clients and expect the same from their dependent servers.


Todo

  • Create a Test Scenario database tie-in for the Robot Framework

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.

Saturday, March 12, 2011

Testing RIAs using pure javascript: the return of Selenium Core

As I try to use TDD to build Fluent, I was drawn to the concept of keeping the environment pure: Fluent is intended to be a Javascript only project, so I didnt see the point of having tools that were not javascript. To this end, I wrote cuke4jas - so that I can write my feature specs in javascript. That still leaves the gaping hole of DOM testing - which most people seem to fill using something like Selenium.

Except Selenium isn't  javascript alone - it minimally need Java (for Selenium RC) to run.

Or does it? Selenium core - the central piece of Selenium is STILL pure javascript; but over the years its been wrapped with the other Selenium bits to make it a complete solution that its no longer available as a separate download even. This is not without reason - the same origin policy ensures that Selenium Core will work only when you've installed it alongside the app that you want to test, which is usually not the case.

Except in cases like mine - where the app is completely in javascript, or at least completely in the browser.

It is possible to use the raw dom functions, or even libraries like Prototype, JQuery or RightJS directly with jasmine to test the DOM, but Selenium core brings to the table the full-fledged support of automating all the user's actions in a browser (with wait versions as well), so that feature specs can be written with true user actions, not imitations of those actions by calling the functions that would eventually be executed.

Design notes:

  • Extract out only the selenium-core bits from any Selenium-RC package. This would be the in selenium-remote-control-xxx\selenium-server-xxx/selenium-server.jar/core
  • Subclass the TestLoop class (see HTMLTestRunner for a good implementation), and implement at least the nextCommand(), commandComplete(), commandError() and testComplete() functions. That should allow for a simple executor of selenium commands.
  • Of course, TestLoop requires a CommandFactory, but the core has a default implementation that does most (all?) of the work.
  • Finally, the subclass will have to take in an array of commands to execute, which nextCommand would provide when requested.
The good part of all this is that you don't need to depend on the TestRunner.html, and therefore can contain all of this within Jasmine/Species/Cuke4jas's Specrunner.html, or even open up a new window and display the app running there.

Caveat:

  • All of this still requires a web-server; the same rules prevent file:/// resources from being used with selenium. I've fixed it with a simple webrick script, although any other web server would work just fine.
  • Once more, this will work only on files served up from the same server as the selenium files are served up from.

Sunday, March 06, 2011

The need to code - my version

JaccquesM (long timer on  Hacker News) posted about his need to code in a passionate article that resonated with me a lot.

My experiences were similar, if not the same.We had some simple computer classes in school which were mostly spent playing Digger and Frogger, but we wrote some basic programs too. There was something visceral about writing something on a screen, and seeing it come live. Basic as a language and DOS Basic as an environment nailed that aspect - and how! You started the pc, typed basic on the prompt and were dropped into an editor that let you type programs that just ran! And BASIC made no presumption of modularity, so you could just use graphics commands in your program because the language had them.

Compare that to any attempt these days to teach programming to kids - all bound up libraries to be imported before the first step taken - and i'm including specific attempts like shoes et al.

When it came time to pick an elective for Pre-University I decided to pick up Computers simply because I didnt want to do Biology, and the other option - electronics - I was neutral about. The instructors were indifferent, and the syllabus was not that great, but I was hooked. I found a friend who also knew basic and we devoured the Peter Norton book on x86 programming. We'd write assembly programs using Peek and Poke in Basic - mainly TSRs for the fun of it. Our other project was writing a 2D graphics editor in Basic. This took us all year because we wrote it on paper using pencils (to erase out and rewrite lines of code that needed to be shifted), and went to another friend's house to use his dad's pc to enter the programs and see it run. There were a lot of GOSUB XXX lines (read sphagetti code), but we pretty much carried the code in our heads and didnt stop talking about it. We finally did manage to get it working, and I believe I still have the batman portrait I drew using it. Have you ever printed anything by calling the DOS interrupt to dump the screen to the printer? That was what our editor's print function did :)

We graduated to Pascal from there because it was in our syllabus, and quickly discovered the joys of Turbo Pascal and all its cool extensions - especially the asm blocks and the graphics libraries. Of course, we wrote fractal programs and marveled at fractint.

From there it was to Turbo C - to revel in the freedom of C. I remember my first C program being pretty mundane - it converted a number into words. The challenge was that it had to print out the number in the Indian way of doing so which is not the simple thousands, millions, billions model. Instead we have the thousands, lakhs, crores model; and I remember agonizing over it to make it work. Mind you I still didn't have a computer, so this was all still paper and pencil and mental debugging.

Here's why I completely agree with Jacques that coding is a drug: I was so happily engrossed in doing it that I didnt get good enough overall scores to get into a CS bachelors. So I picked mechanical instead, and focused on the areas that were computer centric - Finite Element Method, Graphics etc. My interest in graphics had led me to read up the Schaum's book on Computer Graphics and I already knew the vector math for those pieces long before we did vector math. When we started doing engineering drawing using pencil and paper, projection systems were already familiar to me - because I was on my way to build my own 3d Graphics engine using Turbo C++. All thanks Robert Lafore for making OO click for me. No other book since has made it so lucid, at least for me.

That's the other thing - books. Unlike today, there was no easy access to books in India. My best source were the scores of street booksellers who sold old books - and what a treasure trove of books they had. I learnt of Russian expert systems and computer architectures like nothing else, of APL the language in a book written by Iverson, tons of old British computer magazines that introduced me to editors like Brief and Hypercard-clones, and whole lot more - in all a heady whiff of the ocean of opportunity that lay outside the staid old land of E.Balaguruswamy and Yashwant Kanetkar (these are probably still revered in Indian academia). Sadly, those booksellers now exclusively sell pirated Harry Potters and self help best sellers, but thankfully there are Indian editions of good books nowadays.

But I digress. Throughout my undergrad my only access to computers was at college - so most of it was spent trying to get as much lab time as possible. Lots of social engineering went into this endeavor (sucking up to the CS Dept head to allow use of their lab, helping the lab assistant in the Robotics lab to use the only Sun machine, etc), and pretty little code came out, but it was a heady time because anything was possible. I did manage to get the basic 3D graphics engine working (it proudly spun a sphere around, IIRC), and managed to present a paper on (what is now obviously basic) AI at the Computer Society of India Student convention while doing mechanical engineering.

Fast forward to today: I've been an IT professional for 13 years now. I still code as much as possible at work (architecture/design decisions or helping my teams with complex fixes), but I have a healthy github account, and some more side projects at work. Coding makes me happy. I dont want to stop.

Thanks JacquesM for helping me remember why I do this.

Sunday, February 27, 2011

Idea extension: The dead letter box framework

This is an extension of the idea for the delicious replacement. The idea is to treat accesses to a website as messages dropped off - dead letter box style.

Dead letter boxes allow communication to happen without meeting using a pre-agreed signal or format. The idea is to use a web server's log file as a dead letter box for various types of messages. Like so:

404 GET /dlb/tweet/my_tweet_as_an_underscored_resource_name
404 GET /dlb/todo?task=do%20something&priority=high&context=@home
404 GET /dlb/post-blog-entry?title=A%20Blog%20Title&body=A%20uuencoded_string_as_long_as_log_will_take_goes_here

Again, the way it would work is that a job wakes up regularly, greps the web server logs for these error messages, and does what's actually expected from each of these.

Subversion of http's actual intentions? Maybe. But it sure produces a very decoupled way of working - no high capacity web server with custom code to handle all these operations need exist, and new operations can be added in a very decoupled way.

The best advantage of all? As long as you're able to hit a web server - you can tweet, log a todo, post to your blog, etc, and much more. No more need to be connected to each of these different sources.

Next: do the same with email, so that the same functions are available when you send an email. Although you could implement that as an actual email processsor.

Not entirely addressed yet: security. Maybe making it https would suffice?

Sunday, February 20, 2011

Idea: An acceptance test framework for command line programs

This is an extension of the standard acceptance test framework pattern to the world of command line programs.
If you specify:
  • a set of scripts to run, 
  • a set of inputs and expected outputs, 
the framework runs them, and prints out the results of running the tests like so:




I have most of the framework working in another project that should be easy to extract out and make into a standalone project

Saturday, February 19, 2011

The problem with TDD for custom development

I had an idea for a cool app today. I wrote up the initial set of requirements, and came up with the high level "here's how the guts will work" to convince myself it can be done, and naturally started thinking of the architecture.

Soon as I had enough of the pieces "working" in my head, I thought "well  great, let's write some code. But maybe I should do it the TDD way. Hmmm..."

Here's the problem: TDD tools don't exist for what I'm trying to do. Its not a webapp, and it most probably is not in Ruby or Java. Or maybe I should write it in one of those languages then? I dont know.

My point is that TDD is probably not appropriate when you're still doing exploratory architecting of the application itself. You want to see the core pieces work, or you want to figure out what the core pieces even are, TDD will get in the way for one or both of two reasons:
  • You'll get hung up on the specification and miss out the architecting
  • You'll put your actual project on hold while you build out the TDD tools :)
Now TDD purists would say the specification will extract the architecture or clarify it, but IMO TDD is at its best when the second D implies automation.

As I've been writing this, I'm thinking there's another alternative: Plan for TDD - decide when you'll start doing it and with what tools, and which parts of the app are appropriate to use it for - but dont do it just yet until you know the architecture itself.


Thursday, February 17, 2011

Installs should be hudson-simple

Idly musing about the causes for Google Wave to reach the place it did, it stuck me that its new incarnation - the yet-to-be-unveiled "Apache Wave in a Box" - should be dead simple to install if it has any hope of adoption.

My gold standard for java apps that are dead simple to install? Hudson or now Jenkins.It should be as simple as downloading a jar and running it. Everything else should flow from there - including updates.

Idea: InstantQ

It struck me as I was waiting at the bus stop the other day that in urban living is a lot of standing in queues. The bus stop follows the honor system by default, and people are generous to a fault (at least where I live in Chicago), but could technology help?

What if you could start a queue using your smartphone when you arrive at the stop? Anybody arriving after you would look for your queue, and join it.When the bus arrives, it automatically notify each person in the order in which they joined the queue that it was their turn.

Now this might be too slow for a bus stop where once the bus arrives, everyone gets in in a few seconds, but any other place that involves waiting in a queue, this might help avoid queue anxiety.

And now for the commercial version: Any organization that needs to provide service to people has these elaborate systems that show the "Now serving" display could just buy the InstantQ software that would run on a PC and "host a queue". Anybody with a phone could join, and as long as we provide the ability to join a queue via text, we could cover most of the population.


Tuesday, February 08, 2011

Jack/Webster/Fluent: Use YAML as the text format

YAML seems like a nice fit for a text-based format for Jack or Webster/fluent. The things that attracted me to YAML are:

  • Strings dont need to be quoted unless absolutely required. This is a huge advance over json
  • YAML has references.
it still might not be the best way to represent code as data, but its close.

Sunday, February 06, 2011

Reality Driven Development

I've started reading Growing OO Software - Guided by tests, and two paragraphs in Chapter 1 struck me as interesting constrasts:
The catch is that few developers enjoy testing their code. In many development
groups, writing automated tests is seen as not “real” work compared to adding
features, and boring as well. Most people do not do as well as they should at
work they find uninspiring.
and a few lines later:
If we write tests all the way through the development process, we can build
up a safety net of automated regression tests that give us the confidence to make
changes.
It seemed to me that the first is grounded in reality and the second aspires to a idyllic future.

What if we came up with a methodology that actually assumed reality, and while we're at it, the worst possible one? The concept is nothing new - for eg, network design assumes the worst always - the internet's architecture is replete with strategies against the untoward happening while expecting it to.

So, any methodology expecting to better the software development process should expect that:

  • The average programmer doesn't want to write tests
  • The code developed will outlive any one person involved in its creation and maintenance
  • The architecture, design and implementation will always represent the forces that were in effect at the time of their being decided upon, and therefore will be exactly what those forces required them to be
  • Forces will change over time, and will pull/push the architecture, design and implementation in ways not expected originally
  • Architects, Designers and Developers are forces on their own right, and will do things "in their own way" despite any official or external mandate .
  • Evolution of the software will be more akin to frankenstein-in than darwinian, ie, all software will gravitate towards a Big Ball of Mud
  • Average developers will prefer tools to better practices, i.e prefer fixing instances of bad behavior to changing them
  • In a large enough organization, average developers are not cross-functional. They have a niche and are very happy in it. The exceptions do prove the rule. 
  • The average developer will tend to narrow the definition of his niche because his world is constantly expanding and its difficult to keep up.The only possible exception to this rule is interview time, when the developer will make an all out attempt to project an air of being a generalist.
I could keep going, but you get the general idea. That then, is Reality Driven Development.Nothing new here, I just gave a name to something we all know - kinda like Ajax :)

How to practice RDD, you ask? Well you already ARE - this is the status quo :).

If you're intent on changing that status quo for a better reality however, the first step is to accept the reality. This might be easier for the actual developers to see as that IS the reality, but for people intent on changing that reality it might be a little bit more difficult. I personally am someone trying desperately to close my eyes to this reality because it doesn't fit the ideal world of "how programming should be done". I'm guessing that proponents of Design Patterns, proponents of best practices of any kind, mature developers and TDD/ATDD/BDD practitioners would feel the same way. "If only we could get Joe Developer to see the light" seems to be the underlying sentiment; but accept we must.

Once we accept that this is how we actually build software, we can move in quite a few ways towards a better outcome, and again by extension from fault-tolerant network design, I present some ideas:
  • Quality doesn't have to be absolute: However your app currently works, it does. Don't let your next step be 100% quality. Instead focus on the next 5% increment.
  • A model of layers of reliable quality built over ones that aren't: Remember the OSI model where each layer did one thing right but was expected to do others not so well? And how layers above did those things right? This is an extension of that idea. I don't have exact suggestion yet on how this should be applied to the list of problems above, but it seems like this is the approach that any solution should adopt. 
  • Support over prescription: This particularly addresses changes in behavior such as TDD and BDD. Asking developers to change their workflow on its head is not likely to be accepted except by those already predisposed to changing it. Instead, make the adoption easy by providing support. For eg, why not create a tool that records the outcome of any debug session as a junit test automatically instead of expecting the developer to hand-write the test?
I realize that the ideas above are not exactly fleshed out, but I'm alluding toward an approach to software development that's grounded in reality, and aims at improving the overall maturity and reliability over time. I don't mean something like CMM, however, because its interpretation has almost always meant handing off the quality responsibility to an external auditor. I'm leaning more towards something like the agile manifesto, but grounded in reality. 

Note on CMM and its interpretation: I have found that CMM is more often than not interpreted as an organization compliance initiative, not as a means to measure maturity and improve. This is exactly opposite of the CMM's stated intent, and therefore can be ascribed to flaws in the interpretation of the model. The most visible parts of the CMM machine, however are always big, up-front audits and compliance checks.Its no surprise, therefore, that the average developer treats the CMM process with suspicion, and its outcomes even more so.

Note on interpretation in general: TDD, Agile and such best practices suffer the same issue of the gap between espoused ideal vs interpretation of that ideal by practitioners. RDD is a response to this gap.

Concept: Treat requirements as external forces, especially non-functional requirements

Along the lines of my idea to use FEM-like analysis on code, I realized that it should be possible to model the things that cause the architecture and design of the software over time as physical forces.

Case in point: My team is currently working on adding multi-lingual and multi-currency support to a fairly large app. Adding this predictably requires changes across the board, and led me to visualize all the places we're pushing and pulling at the current design/architecture to make this happen.

Could this instead be considered a single external force acting on the elements of the system? Can we study the "material properties" of the code under such forces and "sum up" the forces?

If we could do that, it would certainly move us out of the current dark ages where cost of change is still measured as a list of things to change per a specific change plan.

Saturday, February 05, 2011

Maintainability of code

Most of my career has involved maintaining code built by others. I'd wager that most developers' career has been the same, even if they didn't want to admit it. Sometimes maintenance goes under the name of updating your own code, so people delude themselves into thinking they're not maintaining code, they're just creating the next version. From a maintainability POV, any code that's built is legacy.

And yet most (all?) methodologies of software development either address completely start-from-scratch greenfield development, or propose ideal practices that mature, passionate developers who are in the field for the love of programming.

The reality, however, is that most development involves enhancing or maintaining code - usually somebody else's, and mostly crufty; and in all likelihood the crufty code is from somebody who's presence in the industry is a happenstance rather than a planned event. If you're lucky it merely represents somebody's state of maturity at the time of writing, and that person has now improved.

A comprehensive methodology for maintainable software, therefore, must:
  • To address the legacy code angle:
    • Provide mechanisms to create "good enough" comprehension of the code
      • But avoid attempts at large scale or totalitarian model-driven comprehension. Such attempts will always fail in the real world simply because there will always be something outside the model
      • That is, allow for leaky abstractions
      • That is, allow for manual steps. There will always be manual steps. The methodology should allow for that by exclusion or explicit statement.The former is easier.
    • Help identify what changes and what doesn't. Easier: help identify what has changed and not in the past and let the humans extrapolate to the future.
    • Provide a means to migrate from what is to what should be that's incremental.
  • To address the maturity concern:
    • Allow for different levels of maturity
    • Allow for the ability to define "good enough" architecture, design and code; and the ability to easily enforce it
    • Allow quick enough comprehension of these definitions
    • Allow for gradual adoption, and a means to measure progress
The usual solution is to relegate this to Software Engineering, which typically spirals into talks of CMM and suchlike - process heavy, people agnostic.

The reality, however, is that software development is largely a human effort, and precisely because it lacks the usual shackles of other human endeavors. A mechanical, electrical or electronics engineer will always hit upon some natural limit. Not so the software engineer. His limits are the limits of the mind. If you can think it, you can make it.

And therein lies the problem. If you can think it, so can a multitude of other software engineers; and each such mind can think of at least one variation to the same problem using the same essential solution. This is why I believe we will not see Software ICs any time soon. Most process oriented methodologies tend to gravitate towards this concept, or to the equivalent one of "resources tasked to do X will repeatably produce output of increasing metric Y".

Meantime, in the real world, human programmers are finding ways to game that system. 

As software practitioners, what are we doing to better this? There seem to be promising starts with the BDD and (to a smaller extent) TDD movements, and (in a less focused, but generic scale) with the general move towards declarative programming. There're some incremental gains from tooling in general, but those gains are largely in the area of reducing the steps that the interface requires you to go through to achieve any particular task. There's also some progress in architecture analysis, validation and enforcing that constructs such as DSM and its ilk provide - if practiced regularly.

However, all of these lean toward the mature, self-aware programmer. By the time it reaches Joe Developer, its an organization mandate, not something he WANTS to do. So the gaming cycle begins. This time, however, its insidious because it projects the impression that code quality has improved. We therefore need tools and methods that "work in the trenches". I don't have a good enough answer, but here're are some interim steps that I can think of:
  • Allow for easy documentation of what exists, and in such a way that the document follows changes. Working diagrams are a good way of documenting the subset of the code that's understood. 
  • Use tagging as a means of collation of documentation created thus. Its easy and "good enough".
  • Don't loose what you gain. Developers gain a lot of system knowledge during debugging. There's no easy way of saving that for posterity, so the knowledge is lost. Do not expect developers to write a wiki page - they don't have the time. This area is ripe for tools such as 
    • bookmarking and code traversal trails being saved. 
    • A "tweet my XApp-fu" app is what's required here.
    • A way to share all of this that's searchable
  • Make creating tests a 1-click affair. Any run of the software should be convertible into a test, especially a manual  during the normal write-compile-test cycle that the developer engages in.
  • Allow cheating on setting up the context. In most production systems, its not easy to inject mocks or test doubles. Test automation should allow for as little of the system being mocked out as possible.
  • Mindset changes:Somebody on the team needs to evangelize these:
    • "Works on integration box" is less useful than "PROVABLY works on any box". This implies CI without requiring buying into the CI religion.
    • Exemplar test data is better than just test data. Exemplars are test data sets that "stand for" a scenario, not a particular test run. 

Webster/Fluent/Jack: Create a text-based syntax as well

I realized that while I'm trying to usher in better programmer tools, most programmers might already be comfortable with their existing ones. So to foster better adoption, the simpler idea might be to allow a text-based syntax as well.

Hopefully, they wont be able to escape the wily wares of better tools for too long!

Friday, February 04, 2011

Idea: Queues: a visualization of work queues

I have been thinking about the concepts mentioned in Product Development Flow, and visualizing a dashboard based on the Queues mentioned in that book. An agile team could be represented minimally by a queue - the list of tasks in its backlog, and how the team processes that list. If we had a visualization of this, it would be easy to represent how well/efficiently the team is working

Extending this downwards, the team's performance could be measured in different ways: as a summation of each team member's work queue (which would allow per team member productivity and efficiency estimation), or as a summation of work completed, or (even interesting) as a summation of the different workstreams it's currently undertaking.

Extending this upwards, a set of teams or the entire organization could be measured in terms of the queues for each team, and the attributes of each queue chosen to be measured.

Speaking in software terms, I'm thinking of creating:

  • A system that allows the creation of a queue, and a visualization of it.
  • The ability to create parent and child queues
  • The ability to "sum up" based on arbitrary attributes of each queue

Monday, January 31, 2011

An easy launcher for redcar on Windows

I just (re)discovered Redcar, and have been playing with it. I love it so far (especially the seamless git integration, and the tree-document-view concepts) but I find unnecessary windows irritating, so I obviously didn't like that Redcar needed a command window open in addition to its own SWT one. Here's how I made launching Redcar a 1-click affair.
  1. Install redcar and make sure it works on its own. ie, typing redcar on any command window should start it up.
  2. Convert the redcar icon from png to ico using imagemagick. You obviously need a unix box for this, or have imagemagick installed on windows. Online tools are also available, but this seems the most programmable and quick - especially if you have a unix box around :)
     [user@box]$ convert -resize x16 -gravity center -crop 16x16+0+0 redcar-icon-beta.png -transparent white -colors 256 redcar-icon-beta.ico
  3. Create a windows shell script (redcar.vbs) that loads up redcar without a command window
        Set WshShell = CreateObject("WScript.Shell")
        WshShell.Run chr(34) & "redcar" & Chr(34), 0
        Set WshShell = Nothing
  4. Open up a launch folder of your choice. Mine is the Quick Launch bar.
  5. Rt click on the folder, New -> shortcut, and in the wizard that shows up, enter the following:
    1. Location: drive:\path\to\redcar.vbs
    2. Name: redcar
  6. Rt click on the shortcut -> Properties. Then change the following:
    1. Change Icon -> Look for icons in file: drive:\path\to\redcar.ico
  7. In the folder (or in my case, on the Quick Launch bar), Click on the Redcar icon. Redcar should now load up straight to the splash screen.
    Notes:
    • The one drawback with this is that you no longer see the debug information that the command window provides. I could not have know that Redcar looks for git during its launch without that output. So there's still reason to launch redcar from the command line. This method doesn't prevent such launches.
    • I noticed that there's a github project creating a windows launcher for redcar, but it seems to me like the steps above could be easily automated and the artifacts added to the redcar core distribution for a simpler launcher.Maybe I'll fork redcar and add them :)
    • If you're using Portable Git on Windows like me, the key to having redcar find git outside MinGW is to add the following to your path:
    drive:\path\to\PortableGit-xxx\cmd

    Tuesday, January 25, 2011

    Jack: Javascript should be the base language

    It just struck me today morning as I was getting ready that the base language for Jack - my idea of the next gen programming language - should be Javascript. The good parts, of course, but definitely javascript.

    This ensures that it has the widest spread of runtime environments, has the functional bits built in, and - as long as we keep the base concepts to the good parts -  none of the ugliness

    Monday, January 24, 2011

    Idea: A textmate rewrite in Fantom

    Textmate seems ripe for a rewrite to a platform outside of Macs, and what better language than Fantom?

    Sigh. Another project idea that'll have to wait.

    Sunday, January 23, 2011

    Idea: More Effective Workspaces

    Workspaces are invaluable in keeping focus on the job at hand. I've been used to Workspaces on Linux Desktops for a long time, and recently discovered a Windows powertoy - MSDVM - that does the same on windows. This idea is a couple that I've had that can make them more effective:
    • A per-workspace todo list: So that when you form a plan of what to do in that WS, the plan is visible always
    • A "Send todos to workspace X" feature: I frequently find myself remembering to do something official while I'm on my personal workspace. It would be nice to be able to send a todo to that todolist without losing context.
    • An "I'm stepping out" button with tickler for when you return : Click on the I'm stepping away shoudl allow you to enter quick text on what you're currently doing, so you have a high visibility "This is what I was doing before I stepped away" note on the workspace when you return. I constantly find myself doing this using a new notepad instance even though i have other todo lists - just so its front and center when I return. It would be nice if the workspace did it for me.
    Of course, all of this can be done with current software and some manual setup, but it would be nice if the todo lists were workspace-aware, so this works out of the box.

    Tuesday, January 18, 2011

    A goal for Fluent

    Fluent, pka Webster is the Web-based DSL metalanguage+editor I'm working on currently. It seems like the language workbench challenge would be a good fit for a goal to work towards.

    Monday, January 17, 2011

    True BDD for Webapps

    Current BDD implementations have a "core" language they support. How about a bdd framework for ANY webapp?

    "Outside in", the core BDD concept implies that you start with the outer layer of the app and implement inwards. Well, why not apply that starting with the html, going inwards to js, refactor js to make it mvc etc.

    So the true BDD implementation for Web Apps should load in a browser, and allow any browser action to be validated naturally.

    Implementation Ideas:
    • a html based runner of the spec a al jscoverage (which should be rewritten in js, btw) is required, so your spec can be loaded in html, and runs the target app in html as well
    • spec will be in a cucumber/robot syntax - very english-y, which will be converted into functions in javascript. Nothing new here, this is what all existing BDD implementations do anyway. We'll just leverage the best Javascript one.
    • building html must use zen coding for example so its easy to do so.
    • Adding behavior will involve writing a spec for it, and adding the basic js code for it, then refactoring it to use an appropriate framework (mvc, etc) and so forth.
    • As that progresses, the main spec becomes more detailed, and contains nested specs for specific layers. Eg, the javascript layer could be tested directly using rhino, etc

    Wednesday, January 05, 2011

    Simple Admin Tool

    Most applications have configuration defined in files. This idea is to automatically wrap a simple admin tool around the configuration file instead of building one from scratch.

    So, for eg, a java properties file when input to this tool would automatically generate a website that allows  values in the properties file to be created, display, updated and deleted.

    Not in scope: updating in-memory variables with the new values. Although a simple reloadProperties() call can be supported.

    Wireless Projection

    You go to a meeting room, and typically connect up your laptop to the projector or plasma screen in it.
    But do you really need to? Why cant you connect wirelessly to the display?
    That then, is the core of this idea.

    If the projector/plasma is connected to one machine, others can connect to it wirelessly and display the content of their screens on it.

    Alternately, the one connected attendee can then easily enable other attendees to use his machine to remotely display their screen contents! This has the added advantage of allowing anybody to use the display, not just the one person connected to it - without the hassle of disconnect/connect/key combo to show etc; not to mention the chance of allowing group participation through easy passing of the display baton.

    Implementations possible:
    1. Xserver on a box that's physically connected to a projector/plasma.Wrapper server & client programs that allow Webex/vnc-style connect-ability to project local display onto that display.
    2. VNC client/server setup with client in listen mode
    3. Custom wrap of xserver or vnc that automates all this.

    Tuesday, January 04, 2011

    Metalysis

    Metalysis: The analysis paralysis that results from thinking about meta and meta-meta programming. A prime sample
    language = domain model + syntax (template + css)
    the model till now describes:
        - the elements of the language
        - how to display/edit it
    but the editor's interaction model is fixed based on the meta model   

    so true language editor is
    language editor = domain model + display model ie syntax (template + css) + interaction model (javascript behavior)

    now this behavior could be modeled as a domain language itself, but for it to be useful, it would need something that can execute the domain, not just understand and allow its editing

    so true language = domain model + editing model (display model + interaction model) + executor (interpreter/compiler)
    :
    So I should just create the meta model and its interpreter, and running it will spit out my language editor, ready to run!

    This is when I came back to the ground and started writing an event loop and handler. Nothing like normal GUI programming to make you realize you're nothing special!

    Saturday, December 25, 2010

    Webster: switch modes instead of making it hybrid

    I just had a brainwave: I have been mulling about ways to bypass the creation of a hybrid editor, when it seems like there's an easier way: allow fluid change to text mode of the whole document.

    When you dont want to treat the code as code, just switch to text, and use text semantics. Simple :)

    Of course, change "whole document" to "part of document" and you get a hybrid editor for free.

    Which of course, goes back to the "islands of one language floating in a sea of another" idea that I've been mulling about. What if the "document" was actually a disjoint data structure held together by multiple instances of small editors? Each such editor would handle its own language fragment.

    More thought required, obviously :)

    Friday, December 24, 2010

    Idea: Photo to Graphviz diagram: an android app

    Take a picture of a whiteboard diagram with your android phone.
    This app converts it into a graphviz diagram.

    A delicious alternative

    Delicious is the one intenet resource I use, and that is now on the verge of being sold or shutdown. Here's my idea of an alternative. As always, I like them to be self-sustained, and preferable controllable by my self.

    All we need is a web server, and hits to a particular url in which the link to be saved is contained. The url doesnt even need to be active; it just needs to log to the web server's logs. An offline job runs as frequently as needed, trawls the logs, extracts the links and stores it.

    Entry and viewing of the link database is mediated through a browser plugin as now, because that's the most common usage anyway.

    Simple, and as long as you have a web server (which you should anyway), you're good. The only custom component is the offline job.

    Idea: Photo to Graphviz dot file for android

    Finally posting this idea from last year. The idea is that you'd take a picture of your latest-n-greatest app architecture that you just scrawled on the whiteboard (as you usually do nowadays at the fag end of that big architecture meeting), and this app would automagically convert it into a graphviz dot file.

    Simple, huh :)

    Thursday, December 23, 2010

    Things that I'm really interested in

    This is one of those big picture posts. Here're the "hard problems" I'd really like to solve:

    • Code Comprehension: How to understand a new codebase easily. If i wrote an oreilly book it would be called "Understanding Code"
    • Code creation and maintenance: A lot of this is manual, repetitive, lossy and tedious. Programmers should use the tools (that they make for users) for their own use. And: less snapshot-based development, more fluid one.
    • Applying AI techniques to code itself.

    Wednesday, December 15, 2010

    Slots: It's like freemind converted to twitter :)

    Pardon the cheeky title.


    The idea is to have an app that will allow you to take a piece of text, and define "slots" in it. Essentially something like the "Its like x for y" sentence above. It then stores the template sentence, names for each slot, and the values. Once these are stored, Slots then allows for them to be queried using the template sentences. My previous idea of the app to remember where things were could then be just an application of slots.

    Further development of the idea:
    • It need not have any specific interface; it should embed itself into other apps or work on clipboard text.Input is therefore any text. This means that it could be an android app, or browser extension and still work the same.
    • Storage can be local our cloud.
    • Once a match is made, action can be taken in any/many ways to actually do something

    Sunday, December 05, 2010

    OT + Grammar = New way of defining languages?

    Operational transformation is a way of defining documents via the series of steps required to create the document - among many other things.
    Language grammars are usually defined by rules on how to recognize a document once its created.

    What if the latter was done in the former's style?

    Need to think this through but if the rule set is not prohibitively large this would be a nice way to achieve incremental parsing, not to mention the ability to have "islands of known information" mixed with WIP unknown fragments, methinks