[Pharo-users] Dynamic graph exploration - seeking input on idiomatic smalltalk [LONG]

phil at highoctane.be phil at highoctane.be
Fri Jul 6 08:23:00 EDT 2012


What's that PharoTabletIDE thing?

I am doing some work with Pharo on iOS. Is it the platform you use?

Phil

2012/7/6 S Krish <krishnamachari.sudhakar at gmail.com>

> You should read as much as you can about Kapital of JPMC. It does more or
> less what you describe for esoteric Prime Interest Derivatives and very
> scalably ..
>
> I doubt if there is much in the public domain, but the fact that Kapital
> is the golden standard in this product line talks highly of why Smalltalk
> is THE platform for this kind of product.
>
> It would be nice to have a Pharo based derivative product that can easily
> beat Ruby/ Java / .Net at this dynamic visualization using standard
> browsers, where Nautilus too can serve your purpose.. or a home grown tree
> based browser.../ Grids..
>
> Once I have completed my run at a PharoTabletIDE/ PharoMorphicView
> framework, I would love to collaborate on your endeavour to see if it can
> be modelled on it and exposed..
>
>
>
> On Fri, Jul 6, 2012 at 4:08 PM, Patrik Sundberg <patrik.sundberg at gmail.com
> > wrote:
>
>> Hi,
>>
>> First of all, sorry for the long email as my first email to the list.
>> Hopefully some people will find it an interesting discussion :)
>>
>> I'm a long time programmer that has been studying smalltalk and pharo over
>> the last year. It's a beautiful language I'm liking the image style of
>> development a whole lot. I've been looking for a good test case to try out
>> in pharo and I've got something in mind. I've used ruby since around 2000
>> and given how much it has been inspired by smalltalk it's not a big leap.
>>
>> My real job is being a commodities trader but I build my own tools and
>> something I'm always working on is improved risk and pricing tools. Lots
>> of
>> that comes down to 2 things:
>> 1. evaluating a "function" (in a general sense) with inputs that are
>> picked
>> depending on time. e.g. I want to price a security and I want to pick up
>> prices for time X as inputs to the pricing model.
>> 2. calculating a derivative of the "function" above with respect to inputs
>>
>> What I tend to do in order to keep things consistent by design, plus add
>> natural caching, is create a calculation graph. I define all the
>> dependencies and create an in-memory graph where each node is unique using
>> an identity map. I then perform a calculation where the calculations
>> trickle
>> down the graph starting from the node I'm interested in down all it's
>> dependencies. To calculate the derivative I then find the node
>> representing
>> the input I want the derivative with respect to and use finite
>> differences,
>> e.g. move it's value, and recalculate the top level node. On the second
>> valuation of the graph only the parts that are affected by me changing
>> that
>> 1 value will need to be evaluated, the rest is cached an unaffected. It
>> makes it very easy to ask questions like "How much will I be affected by X
>> changing by Y?" since I can take the top level node of the graph, search
>> for
>> X, and if found change it by Y and recalculate.
>>
>> How the graph is constructed in memory depends on time (and a few other
>> things). I always store all previous states of the world so that I can
>> recreate any calculation I did in the past. Very useful for diagnosing
>> problem. Hence if I for example change what model I use to model
>> something,
>> that change is recorded in a way such that if I set my "time" to before
>> the
>> change happened the graph will get created as it would have with the old
>> model, and for a time after the change it'll create a different graph
>> reflecting the new model. Hence the graph can only be known at runtime
>> when
>> the "time" etc is known.
>>
>> I currently have a ruby mockup of this. It's a DSL that looks like this:
>>
>> ----------- EXAMPLE
>>
>> class ExampleObject
>>   include GraphEntity # includes a module with functionality for objects
>> participating in the graph, including #property and #calc used below
>>
>>   property :foo do
>>     123 # this is the default value for this property which will be used
>> before a value has been set and saved
>>   end
>>
>>   calc :bar do |arg|
>>     foo.value + arg     # take the value of the arg property and add the
>> argument given to the calculation node
>>   end
>> end
>>
>> o = ExampleObject.new
>> # this will kick of the graph being built in memory and setup the
>> dependency
>> between bar and foo nodes
>> o.bar(1).value  # -> 124
>> # this will be a "cache lookup" since nothing in the graph that bar
>> depends
>> on has changed (i.e. the "expensive" calculation is not performed again
>> o.bar(1).value  # -> 124
>>
>> o.foo.set_value(2)
>> o.bar(1).value  # -> 125, realizes that foo changed and performs a recalc
>> --------------------------------------------------------
>>
>> To accomplish this I use dynamic code generation like the below for
>> #property and similar for other types of nodes:
>>
>>         # NOTE: it's a class level method, hence how I can call it when
>> defining the class in the example
>>
>>         def property(name, time = CdrEnv.instance.time, &block)
>>           clear_property(name)
>>           getter_method_body = <<-EOF
>>             def #{name}
>>               init_block = self.class.property_init_block_for(:#{name})
>>               time_for_property =
>> self.class.property_time_dependency_for(:#{name})
>>               if init_block.nil?
>>                 CdrEnv.instance.get_property_node(self, :#{name},
>> time_for_property)
>>               else
>>                 CdrEnv.instance.get_property_node(self, :#{name},
>> time_for_property, &init_block)
>>               end
>>             end
>>           EOF
>>           setter_method_body = <<-EOF
>>             def #{name.to_s}=(value)
>>               #{name.to_s}.mutate(value)
>>             end
>>           EOF
>>           class_eval getter_method_body
>>           class_eval setter_method_body
>>           register_property_node(name, time, &block)
>>         end
>>
>> Don't worry about the details or all the unfamiliar ruby, the main point
>> is
>> that it creates an instance method that uses the singleton CdrEnv.instance
>> to either get or create the node representing the property from the graph
>> identity cache depending on if it exists or not.
>>
>> From a tooling point of view I think I'd love to work with this kind of
>> thing in pharo. Building my own browsers for inspecting and debugging my
>> dynamic graph should be very good fit. However, I'd appreciate some
>> pointers
>> to idiomatic smalltalk to attack this kind of problem in terms of
>> implementing the graph itself - I obviously want the user (even if it's
>> me)
>> to just have to focus on the domain model and hide as much as possible of
>> the graph bits under the covers the same way I've done with the code
>> generation stuff in my ruby example.
>>
>> Any input into this would be much appreciated,
>> Patrik
>>
>> P.S.
>> Btw, the persistence backend for this is the neo4j graph database, but
>> it's
>> fronted by a service slotting into my own service framework built using
>> ZeroMQ and services exchanging messages in protobuf format. One can use it
>> from any language as long as one can send protobuf messages over zeromq. I
>> see there's a zeromq ffi library available on SS that I'll check out, but
>> I'm not finding a protobuf implementation. It'd be easy enough for me to
>> port a ruby protobuf implementation but I may as well ask if someone has
>> already done any work on protobuf for smalltalk?
>>
>>
>> --
>> View this message in context:
>> http://forum.world.st/Dynamic-graph-exploration-seeking-input-on-idiomatic-smalltalk-LONG-tp4638702.html
>> Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
>>
>>
>


-- 
Philippe Back
Dramatic Performance Improvements
Mob: +32(0) 478 650 140 | Fax: +32 (0) 70 408 027 Mail:
phil at highoctane.be| Web:
http://philippeback.eu | Blog: http://philippeback.be

High Octane SPRL
rue cour Boisacq 101
1301 Bierges
Belgium
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.pharo.org/pipermail/pharo-users_lists.pharo.org/attachments/20120706/064aecec/attachment.html>


More information about the Pharo-users mailing list