State Machines and bOP
State machines part five
At the September meeting of frameworks-boulder Tom Vilot, an artist and a geek, presented bOP. Rob Nagler, President of bivio also showed up. Tom's personal website has interesting artwork. (I feel obliged to mention that there's some nudity -- exercise caution if you or anyone with a view of your screen is likely to be offended.) Tom's also got an interesting business that you might check out. I enjoyed his presentation of bOP.
The conversation with Rob afterwards was interesting enough that I ended up missing BJUG. Tom had explained that "bOP is written in very lispish perl". Rob added that it makes heavy use of closures which is part of what makes it lispish. I also saw some use of anonymous subroutines (lambdas in lisp) in the task configuration[1]. While talking about lisp and perl Rob asked if I'd read On Lisp? I've been reading it slowly for the past few months. Interesting timing. Most relevant for this conversation, a bOP application centers around a task configuration which happens to be a state transition table.
My intuition is ringing pretty loudly about this framework. I haven't worked with it at all, but while I've been looking more closely, everything I've seen aligns with all of this state machinery. Here's part of the example bOP Pet Store task configuration.
sub get_delegate_info { my($proto) = @_; return $proto->merge_task_info($proto->SUPER::get_delegate_info, [ ... [qw( PRODUCTS 500 GENERAL ANYBODY Model.ProductList->execute_load_all_with_query View.products )], [qw( ITEM_SEARCH 501 GENERAL ANYBODY Model.ItemSearchList->execute_load_page Model.ItemSearchListForm View.search next=CART )], [qw( ITEMS 502 GENERAL ANYBODY Model.ItemList->execute_load_all_with_query Model.ItemListForm View.items next=CART )], [qw( ITEM_DETAIL 503 GENERAL ANYBODY Model.Item->execute_load_parent Model.Inventory->execute_load_parent Model.ItemForm View.item next=CART )], [qw( CART 504 GENERAL ANYBODY Model.CartItemList->execute_load_all Model.CartItemListForm View.cart next=CART want_query=0 )], [qw( CHECKOUT 505 GENERAL ANYBODY Model.CartItemList->execute_load_all View.checkout )],
I don't know the mechanics behind it, but I'm really interested in the lines that declare a relationship between Model and View and a given state. It looks related to parts of the Ace Application Usage Specification. Both appear to be declaring relationships between the state machine and the Model, though Ace is quite a bit more verbose. Also, Ace is speculative research whereas bOP has been in production since 1999.
When I read Bob Martin's chapter on the state pattern, I immediately started imagining how that could be connected to a web app framework so I could get back to thinking about web apps like I used to with Tango. By all initial inspection, it's already implemented in bOP, and bivio's taken further steps to make the model and security connections also declarative. In fact, while explaining why you should consider bOP bivio uses language similar to what I was saying about Tango:
bOP's primary advantage is as an alternative model for web development. Application servers promote a page-centric model. bOP's task-centric model allows you to think in terms of operations, not output (results).
[1] anonymous subs are how you do closures in perl so these are probably the same thing.
Tom Vilot commented
Thanks for writing this review!
And I would like to encourage anyone reading here to contact me at either tom@vilot.com or tom@paintedsnapshot.com (no spam filter there) if they have any questions.