Tuesday, January 31, 2006

What if...

Having just explained to a friend what I have learnt using the Spring framework, one thought came to me: an object's methods are divided into three groups. These groups are:
  • methods which are part of an interface implementation,
  • methods which express depedencies,
  • ancillary methods which matter only for the inner workings of the object at hand (and of its hierarchy).
So, what if these three groups where used instead of the classic visibility modifiers (public, protected, private, package etc.)?

Monday, January 30, 2006

Inspecting javascript (Rhino) closures

I've spent some time unraveling the Mozilla Rhino codebase. My goal was to know how to serialize closures without resorting to java.io.Serializable.
I was biased toward static analysis and it took me some time to realize that there was no such thing (static analysis of dynamic programs is, by definition, a though problem -- sometimes you know something but you don't understand it until it jumps right to your face, sigh!).
So it's quite simple (I'm just talking for Mozilla Rhino in interpreted mode but my findings hint that compiled mode must not be different): I have to serialize the scopes stack, that's from where the values are coming. So, given a closure (which, being a Javascript object, implements Scriptable), you juste have to serialize closure per se, closure.getParentScope(), closure.getParentScope().getParentScope(), etc. up to top-level.

Thursday, January 12, 2006

Really Simple Decentralized Code Management , part 2

Okay, I left the thoughest part: handling conflicts.
Set up: three repostories (Alice's, Bob's and Clint's), Clint's polls changes from Bob's and Bob's from Alice's and Alice's from Bob's.

Scenario:
Alice commits a patch "A" to her repository. Bob commits a patch "B" to his.
Bob syncs his repo with Alice's. Applying "A" to his repo fails ("A" and "B" are conflicting). Bob solves the conflict, it results in the patch "C". (Using an informal formalism, I may write C = A / B -- not sure it makes sense.)
What must Bob publish as his patch feed? B then A? B then C?
If he publishes "B then A" then Clint's repository will fails to apply A after B in the same way Bob's had.
If he publishes "B then C" then how to tell Alice not to apply C after having applied B ?

I have to read this again, it may shed light on the problem at hand.

Wednesday, January 11, 2006

Really Simple Decentralized Code Management

Recipe:
  1. on the server repository:use CVS/SVN triggers to generate ATOM/RSS patches feeds (one feed per branch) in an apache-served directory.

  2. on the client repository:create an agent which polls the incoming feeds from the server repositories, try to apply the incoming patches on an up-to-date working copy (need to maintain a list of the already applied patches, <atom:id> element would be handful for this purpose). If the patches had been applied successfully then commit the modifications else notify the repository maintainer to fix it.

  3. set up the other way round (the client becomes the server and the server becomes the client)

  4. set up more repositories

  5. profit!

Caveats:
  • after applying a patch from another repository, the local repository MUST use the original id for this patch when putting it in the patch feed, this to allow repositories to detect already applied patches and, hence, to not apply them again.

  • must define when to remove a patch from the patch list or a way for the client repository to request the server repository for all patches since last poll. Clever use of HTTP headers may be useful: ETag, Vary and If-None-Match would allow to generate feed containing at least all the requested patches and to efficiently use caches.

  • must agree on the patch format

Metcalfe's law

(à propos de : http://en.wikipedia.org/wiki/Metcalfe's_Law)
Stumbling once again over the Metcalfe's law (the value of a network equals approximately the square of the number of users of the system) made me rethink of a pet pondering: at work, we once chose CPS over Plone.
I was a Plone proponent, I made it clear but I didn't try to argue further because I wasn't going to work on this project and one of those who were was feeling far more comfortable with CPS (partly because of a greater amount of documentation written in French -- Nuxeo, the company behind CPS is french).
CPS and Plone features are very similar. To close to tell. So I was left with only three arguments: community size, community size and community size. So, according to Metcalfe's law, the gap between the communities is wider cause the communities "have to be squared".

...And, by the way, the Plone's default ui is far better than CPS's one!

Friday, January 06, 2006

digest: Starbucks Economics

(à propos de : http://www.slate.com/id/2133754/)
The British supermarket Tesco has a "value" line of products with infamously ugly packaging, not because good designers are unavailable but because the supermarket wants to scare away customers who would willingly spend more.

Emile Dupuit's quote: "It is not because of the few thousand francs which would have to be spent to put a roof over the third-class carriage or to upholster the third-class seats that some company or other has open carriages with wooden benches ... What the company is trying to do is prevent the passengers who can pay the second-class fare from traveling third class;
it hits the poor, not because it wants to hurt them, but to frighten the rich ...
And it is again for the same reason that the companies, having proved almost cruel to the third-class passengers and mean to the second-class ones, become lavish in dealing with first-class customers. Having refused the poor what is necessary, they give the rich what is
superfluous."
("Ce n’est pas pour les quelques milliers de francs qu’il serait nécessaire de dépenser pour mettre un toit sur les wagons de troisième classe ou pour mettre des coussins sur les sièges que telle ou telle compagnie a des wagons ouverts avec des bancs de bois. Ce que les compagnies essaient de faire est d’empecher les passagers pouvant se payer un billet de seconde de voyager en troisième. On frappe les pauvres non pas parce qu’on souhaite les frapper, mais pour effrayer les riches. Et c’est le meme raisonnement qui conduit ces mêmes compagnies à être très généreuses sur l’équipement de la première classe. Ayant refusé aux pauvres ce qui était nécessaire, elles offrent aux riches ce qui est superflu.")

Starbucks' gambit is much simpler and more audacious: Offer the cheaper product but make sure that it is available only to those customers who face the uncertainty and embarrassment of having to request it specifically. Fortunately, the tactic is easily circumvented: If you'd like a better coffee for less, just ask.