New version of maroon

Posted: May 22, 2013 in DCI
Tags: , ,

Just a few seconds ago I pressed enter after writing

gem push maroon-0.7.1.gem

and I’m pretty satisfied with this version of maroon. The major chnaes are that you now define methods with regular method definition syntax I.e.

def methodname(arg1,...,argn)
end

The other change I made is in how the abstract syntax tree is treated. Maroon has 3 stages

  1. Reading the source
  2. Creating the AST for each method. The AST is represented as a context with the productions playing the roles and productions are in the form of S-expressions
  3. Traversal of the AST and performing the source transformation. In this stage there’s a transformation context where the individual ASTs for each method in turn play a role

One of the reasons why I changed the stages was the AST build as a seperate step, so that other work could be build on top of that. E.g. one of the requirements I wrote of in a previous post. Namely creating a visual representation of the network of interconnected objects that make up a system. That is visually show how the roles in a context connect to each other in various interactions and role methods.

I also feel that Maroon now itself is a pretty good example on how to use maroon and also on how to do DCI. As always the source can be found at at github

Bootstrapping maroon

Posted: April 9, 2013 in DCI, Thoughts on development
Tags: , ,

At #wrocloverb in the begining of March I started to bootstrap Maroon and have now released a fully bootstrapped version. It took longer than I had anticipated based on the time it took me to write maroon in the first place. The main reason for this was that part of the process lead me to find bugs needing fixing or features required to implement maroon that maroon didn’t support(1). Both tasks some what mind boggling. How do you fix a bug in the tool you use to fix said bug? a lot of the time I ended up having two mental models of the same concept and to be honest that’s one more than my mind can handle.
One model was of what the current version was capable of and another was what it was supposed to do. All this was part of the motivation for bootstrapping in the first place and often the reason why a lot of compilers are bootstrapped too. The current state of the code is a mess. I knew it would be. I’m often asked questions like “Is the code then in fact a lot cleaner when using DCI?” and my answer is that it for me depends on how I design the system. If I design as I presented at wroc_love.rb 2013 (top-down) then yes the code is a lot cleaner, however if I design as I often do when not using DCI (bottom-up) then I often find that the code becomes more messy when I try to rewrite it using DCI and maroon was designed bottom-up.
I’ve done some cleaning up but postponed a large part of the cleaning up till the bootstrapping was actually complete so that I had a foundation to test my refactorings against. So the now live version of maroon is a fully bootstrapped version making maroon the most complete example of how to use maroon. The goal of the version thereafter is to clean the code up and make maroon a good DCI example as well. An example I hope to have both James and Trygve review if their time schedules permit. What bugs did I find?

  • Indexers on self didn’t work in role methods, so if an array played a  role you couldn’t do self[1] to get the second element
  • You couldn’t name a class method the same as an instance method. This wasn’t really a big deal because you couldn’t define class methods in the first place but since that’s one of the features added it did become an issue

What features were added?

  • You can define initialize for context classes
  • You can define role methods and interactions with the same name as methods defined for objects of the Context class. E.g. you can define a role method called ‘define’
  • You can define class methods (The syntax for that is still messy but you can do it)
  • You can use splat arguments in role methods or interactions. In general arguments for role methods are discouraged which I heavily violate in the current version of maroon
  • You can use block arguments (&b). The syntax for this is even worse than the syntax for class methods
  • You can choose whether to build the classes in memory or to output a classname.rb file for each generated class. That’s the way the bootstrapping works. I use the current stable version to generate the files of the next version. I then use those generated files to generate an additional set of generated files and the last set of files, which are generated using the upcoming version are then packaged as a gem and pushed.

What features would I still like to add?

  • Default values for arguments to role and interaction methods
  • Make it possible to use all valid method names for role and interaction methods E.g. field_name=, which are currently not possible
  • Cleaner syntax for both block arguments and for defining class methods. I have an idea for this but it won’t be until after I’m done with the cleaning up. It’s going to be an interesting task since it’s probably not going to be backwards compatible. The changes will be small and make the syntax intuitive to ruby programmers (which the current is not for the features in question) but since I’m bootstrapping I’m breaking my own build before I’m done.
  • a strict flag that would enforce a strict adherence to DCI guidelines and a warn flag that would warn if any of those guidelines were violated
  • Add a third option, that instead of creating classes in memory or class files will visualize the network of interconnected roles for each interaction.

(1) Yes it’s a bit strange to talk about bootstrapping. You think/say stuff like “ features required to implement maroon that maroon didn’t support” that sounds kind of nonsensical a lot. The most mind boggling part of that is when debugging…

Thou shalt not lie

Posted: March 5, 2013 in Uncategorized

Let is be said that I’m not pro piracy and I’m very much against skewing facts to suit your own cause.

The title is the ninth commandment and though not a strong believer my self I do believe in fact that we need certain rules for society to function. The ability to detect when people are cheating is actually by nature viewed as extremely important, important enough that our logic genetically is shaped for this.

Even since the dawn of Napster we’ve had stories about music and movies and how that has impacted the earnings of the Music and Movie production industries. How markeds are affected or not affected by external changes, in this case the emergence of new technology is pretty hard to prove and often is just speculated. However once in a while the empirical evidence points strongly in one direction but when that direction is counter-intuitive it becomes easier to disregard it.

The evidence that supports the musicians did not suffer dues to piracy is abundant. Take the research article “The Swedish Music Industry in Graphs, Economic Development Report 2000 – 2008″  which concludes that in that period earnings of the musicians grew 35%. As a whole the industry earnings stayed at the same level in that period, with the record companies as the only users. The copyrights organisations send more money to the rights owners not less. But the record companies suffered a massive set back from 1700 mio SEK to 800 mio SEK and just who has wage wars against file sharing? well some musicians but mainly the production companies. The study is not on the global marked but only the swedish marked but when talking about piracy a notable marked since the most know torrent tracker the pirate bay origins from Sweden.

What happened in those 8 years? IFPI has an idea of what made have changed the marked (from the 2004 report):

“2003 was the year we proved that consumers would pay for digital music - it is absolutely clear there is a market. This has injected a huge confidence-booster to labels, to investors and everyone who is looking at it as a business to get into.”

Not only is it interesting that IFPI acknowledges that there’s a huge marked potential but it’s also interesting that the year is 2003. The first major online digital music stored opened April 28, 2003. Not only does IFPI acknowledge the potential, the success of the iTunes music store (later renamed to iTunes store) is obvious

iTunes sales graph

iTunes quarterly sales report

within the time frame of the report iTunes store had sold more than 8000 songs according to IFPIs own statistics at Q4 in 2003 only 275,000 tracks were available (which was an increase from 210,000 the quarter before that). It is in the same report noted that

“An IFPI survey conducted in Australia, Germany, UK, USA and Canada showed that total music consumption (legitimate physical formats plus all digital downloads) actually increased by 30% between 1997 and 2002. Total online consumption of music – the vast bulk of it unlicensed – amounted to approximately eight billion tracks” or the same number of tracks sold by iTunes alone from 2007-2009. and finally the report also notes that the number of simultaneous files on FastTrack system dropped 33% from April 2003 to January 2004 and postulates that this was due to RIAA targeting the users of this network”

Interestingly enough April 2003 was when iTunes was launched.

Skipping a few years a head to 2008 where the first beta of spotify was released it was soon realized that was a serious competitor to pirated music and a study by Swedish Music industry supported this and in  2009 it was found that the number of people who pirate music has dropped by 25 percent and the sharp decrease coincides with a the interest for the music streaming service Spotify.

Could it be that the recording industries slow adaptation to change is the real culprint? At least that wouldn’t be the first time. The same industry proclaimed that radio would kill music but three years ago tried to make FM receivers in cell phone manadatory. The radio didn’t kill the music on the contrary radio has been one of the best places to advertise music. Record labels rutinely supply and will even pay to have music played at the right time, some contradictory to what the industry proclaimed radio revitalized the recording industry when the industry adapted to the change. The above cited study that found that music pirates buy ten fold as much as there non-pirate counterparts also found that the two of the main reasons the sales have gone down are that with digital downloads you no longer buy bulks of music aka albums but cherry pick the numbers you want and simple apathy. Spotify and Netflix and the like have shown how the industry can adapt to the change and the latest numbers show that people follow. Just as the availability of digital downloads (iTunes and others) had an impact on piracy so does the increased availability that spotify brought to the marked in 2008. In general supporting that the key factor is not the price. It’s not that it’s free that’s the reason why so many have turned to piracy but the availability of the desired products (E.g. hit single vs. Albums with hit single).

Do I think piracy might have played a part, it’s intuitive that it has and sounds reasonable yes but on the other hand it’s also counterintuitive that you can make money by giving away your products but the history of open source software proves otherwise and it’s just as intuitive that  no one would accept to buy 14 liters of yoghurt to get the one flavor you really liked and 13 you kinda liked but never really got to consume. Anyone in that situation would go to where you could just by the 1 liter you desired. Would that be visible on the yearly revenue of the diary industry? of course it  would!

As I started out by saying do I support piracy, no I don’t it’s illegal. Do I to some extend think the law that defines copying information as flawed, yes I do. Do I think it’s the main reason to the problems the recording industry have had? Not really, I think it’s the availability (or lack thereof) that’s the real reason. A statement that’s supported by Mike Lang, CEO at Miramax: “The music business is suffering because it allowed too few players to flog content, presumably fearful of their content being stolen. Encouraging Apple’s iTunes at the expense of others is effectively strangling the industry” and with spotify and others it would seem that the recording industry it self are starting to pay attention to that.

No one knows what the revenue statistics would have been if the recording industry instead of spending billions on fighting the tide of changed had spent those money on adopting to change, listening to the demands of their customers? But with the latest numbers that shows an industry in progress largely due to services such as Spotify and Netflix history repeats it self. Radio didn’t kill the music and neither will the internet. Who’s knows perhaps sometime in the future music might die and history tells us the most likely cause will be the industries lack of will to adapt to change.

 

Using maroon to do Injectionless DCI part II

Posted: February 25, 2013 in DCI
Tags: , , ,

In the first part of this series we looked at how to install Moby maroon and how to write a simple context with roles. In this post we are going to look at two simple aspects of maroon. The first one is if you wish to have a base class for your context. In the below example the Account class is used as the base class for the context. This will seldom be needed when doing pure DCI but it is possible to do it when the need arises

class Account
   attr_accessor :account_id
end

context :Account_context Account do
   #implement the context
end

The second aspect is how to define a default interaction. In the example from the previous post in this series. There’s just one interaction and it might be worth your while to be able to use the context where you would otherwise have used a callable construct

context :Greeter :greet do
  role :who do
    say do
      self
    end
  end
  role :greeting do end
  greet do
    p "#{greeting} #{who.say}!"
  end
end

You can now use this context in two different ways where a callable construct is needed. Though you can’t transform this to a proc it still servers as a continuation where you can invoke call. The two options are

Greeter.call person1, person2
Greeter.new(person1,person2).call

In the first version whatever arguments you pass will be passed to new of your context class (in this case to Greeter.new) and the default interaction will be invoked on the newly instantiated context object. If you pass more arguments than new expects then the remaining arguments will be passed to the interaction. In the second version where the context object is explicitly constructed any argument passed to call will be forwarded to the default interaction. It’s worth mentioning that you can pass both a base class and a default interaction in which case you would pass the base class as the second argument and the default interaction as the third. In that case you can either pass the Class object as in the previous example or pass a symbol/string representing the name of the class and the name of the interaction.

context :Account :Owned :balance do

and

context :Account Owned :balance do

Have the same result. A context class called Account is defined. It derives from Owned and the default interaction is called balance. As a final remark all the examples in this post has used context rather than Context::define. to use context you’d need to require ‘maroon/kernel’ which adds a method to Kernel called context. context simply delegate to Context::define so the result is the same either way

The artist formerly known as Moby

Posted: February 20, 2013 in DCI, Subtle bugs
Tags: ,

Moby, which was short for Marvin On ruBY had an unfortunate nameclash with the gem moby and was named against recommendations with a capital M. Thanks to Jim Gay and Ted Milkner for pointing this out. I’ve as a result renamed Moby to maroon.

It can be installed using

gem install maroon

What’s in a role

Posted: February 20, 2013 in DCI, Thoughts on development
Tags: ,

On a recent blog post I received a question “Is there hope for sharing roles between contexts?” and my answer to that might at first be discouraging. In short it’s “no”

I thought it worth while to explain this a bit more since it’s a question that keeps coming back. It has surfaced on object-composition several times, often though not always it’s been due to a misconception of what a role is.

How people perceive a role is to some extend influenced by their platform of choice. In Java, where  no one has yet found a way to do pure DCI, people often take a wrapper approach and this wrapper is then what is referred to as “the role” 1. In Ruby on the other hand people often confuse roles with modules because using extend to do injection based DCI is how you would implement the role logic (at least prior to maroon).

However the concept of a role is agnostic to implementation details. It’s first and foremost an identifier. At run time the role is what identifies the current role player. It also identifies the role specific behavior for that role player. or to use Trygve Reenskaugs words “A role is an abstraction that highlights an object’s identity and external properties while it ignores the object’s internal construction.”

Usually when people talk about sharing roles between contexts they talk about sharing behavior between contexts and not sharing roles. The latter is frivolous, it’s like asking if we can share the role of Claudius the uncle of Prince Hamlet in the play by Shakespeare and Claudius in the TV-series ”I, Claudius“.

What then if we rephrase the question to “Can we share implementation of behavior between contexts?”  then the answer is “yes but…”. One important goal of architecture and design is to segregate based on the rate of change and based on reasons to change. Often it will be found that two roles do not share reasons for change, and that they in fact share behavior is incidental. Sharing implementation of behavior between roles in two contexts would in that case lead to accidental complexity.

In the Canonical DCI example there’s two account objects playing each their part in a transfer context and among other capabilities they both have a balance attribute.

Let’s say that in a different context in the bank, we need to calculate the balance of a given set of accounts. Upfront it would seem that a simplistic model of an Account might suffice.  We store the balance as a decimal number and add and subtract to this number as we withdraw and deposit. And initially this would indeed suffice.
However there’s different reasons to change at play. In the second context it’s the accounting department at play and when doing analyses for their Solcency II modelling, they realize that they need the ability to exclude certain kinds of events, before using them for machine based modelling and they need to get the balance at certain days in the past as well as projected into the future. Neither of which can be handled by the original model. Between these to views of an account there are several commonalities

The account context in the above example captures some of these commonalities. It’s a context that based on a collection of ledger entries can calculate the balance. It can be used in the case where you simply need the balance of the account, it can be used if you need the balance based on only a subset of the entries. They can be filtered based on e.g. date or type. The only aspect that it can’t handle is the projection but that is usually based on the account it self and therefor the account can play a role in a ProjectedAccount context. In this respect behavior is shared between different role players in different enactment of the same context and the behavior that’s not common, is placed in a different context, where a context is playing one of the roles.
I’ve seen numerous examples of where someone would want to share roles between contexts but all examples I’ve seen so far have fallen a part when analyzing rate of change for each or reasons for change to happen. There are plenty examples of “reimplementing” behavior because though at first it seems to be the same it’s not. Just take any mathematical operator. Conceptually there’s no difference between 1/3 and 1.0/3.0.
In a mathematical perspective they are semantically identical. In most programming languages they represent different behavior. Similar is often true for addition. E.g in C# 1+x and 1l+x (where the first is 32 bit integer addition and the latter is 64-bit addition) are semantically different. For the division of integers and floating point numbers there’s different reasons for change E.g. we could get a requirement for triple precision floating point or an arbitrary precision floating point (in C# that’s decimal) integers are them self with absolute precision but the operations have limited precision in their results, so a requirement to keep the precision in the result could arise and would require changing the type of the result to something different than the operands. (This of course would violate the semantics we’ve grown accustomed to).
If such simple behavior with very strict definitions can be semantically different and have different reasons to change, odds are that more complex business logic with loose definitions share the risk of ending up being different beast even though they at first seems to be not just similar but exactly the same thing. Be mindful of the importance of not to make two similar but different concepts into the same. Share behavior where the behavior is the same, “reimplement”  where it’s not. The dijkstra examples in Ruby are a good example of this, where several roles have the same implementation of role methods, eventhough it’s technically possible to share the implementation

1) This is the self schizophrenia showing it’s ugly head an perturbating the mental model of the developers, so that when they communicate they are use the same words as the users but a referring to slightly different aspects of the application

How Moby works

Posted: February 18, 2013 in DCI, Thoughts on development
Tags: , ,

As I wrote in my previous post I would write on how Moby maroon works internally. This is definitely not a post explaining DCI. As a matter of fact it might confuse you and potentially impair your understanding of DCI so tread carefully if you are new to DCI. The target audience is Rubyists that want to know how Moby maroon is capable of getting performance on par with regular method invocation and/or those that might want to contribute to Moby maroon and thereby indirectly to Marvin and DCI as well,

The context defined in the previous post is rewritten to an ordinary ruby class the source code of this class is returned as one of two objects from the define method. The first object being returned is the newly created class it self. The second object is the actual source of this class. In the case of the hello world example the source looks like this

class Greeter
   def greet
       p("#{greeting} #{self_who_say}!")
   end

   @who
   @greeting

   private
   def who;@who end
   def greeting;@greeting end
   def self_who_say 
     who
   end
end

As you can see there’s really nothing magically going on. So what did actually happen? Well firstly each role is rewritten to a definition of an instance variable and a getter. So for the who role there’s an instance variable ‘@who’ and a method ‘who’ and similar for the ‘greeting’ role. But there’s no role methods any more, where did the role method go? The last method in the source
def self_who_say
who
end

is where the role method went. The name might hint at this. Role methods are rewritten into instance methods of the context. And this is where you might be confused if you are new to DCI, so it’s worth stressing that this rewrite violates the mental model of DCI. Paradoxically DCI is very much about expressing the mental models and not violating them. A role method should be seen as a part of the role player and never be considered a part of the context.

it would have been safe to rewrite this to

def self_who_say
@who
end

So why isn’t it done? The reason to this is that there’s two rewriting phases in Moby maroon. The first rewrites the use of self to the corresponding role getter and the second rewriting phase depends on the role getter. When a role getter is encoutered the rewriter  will check to see it’s the instance expression of a role method invocation. If it is it will rewrite that invocation. E.g if we changed the who role to

role :who do
    say do
      self
    end
    talk do
      self.say
    end
  end

Then the first phase would rewrite talk to

talk do
who.say
end

And the second phase would the see this as a role method invocation and rewrite it to

def self_who_talk 
  self_who_say  
end

Recollecting from the previous post that if you call a method directly on the instance variable (in this case ‘@who’) it will always be an instance method and never a role method it should be obvious why the first phase rewrites to the role player getter and not the instance variable. Rewriting self to the instance variable would result in the second phase being unable to identify role method invocations.

Having seen how role method invocations are translated into invocations of instance method on the context obejct it should also be clear that there can be no performance difference between calling a role method or calling a regular instance method after all seen from the view of the interpreter role methods are instance methods.

In the next post we will look at how to bind block variables to roles followed by another post on how the rewriting handles this.