Hi, I'm a newbie at clojure and functional programming and I'm toying with the idea of switching a project of mine to clojure. Sorry for a long first post, and it may also be a bit abstract - but you never know before trying :)
In my previous OO prototype the domain is modelled via 2 basic principles: 1. an implicit DAG (directed acyclic graph) is created at runtime as some calculations are performed. i.e. calc 1 depends on values X and Y, so build that graph. then X depends on A and B, etc. 2. the nodes in the graph are unique, e.g. handled via an identity map. i.e. if calculation 1 depends on the leaf 1 and then calculation 2 also depends on leaf 1 they point to the same leaf 1. unique in this case means either via some unique ID. The graph fulfils 2 main functions and 1 minor: 1. allows me to start from a given node X and find any nodes below that are of type Y (or has name Z or any other node based predicate) 2. do something to value of node X and see how that propagates through the graph 3. (minor) only the nodes needing refreshing gets recalculated (as a result of 2). i.e. graph works as an implicit and automatic cache. a nice to have but performance not my main goal. My existing prototype is done in jruby via a lot of meta programming and voodoo. It still doesn't quite flow perfectly naturally since I can't bend the syntax far enough (i.e. the user has to be aware of the existence of nodes and distinguish between a node and it's value when I'd like to keep all the graph/node stuff under wraps as far as the user is concerned). I can see how doing it in clojure I could get all the way to the kind of user API I'm looking for (plus performance and java interop would probably be better). The actual problem domain is modelling financial instruments if that makes it any more concrete. I.e. the price of security 1 depends on the price of security 2 to 1000, out of which half depends (in different ways) on the price of security 1001, which depends on paramter X the input Y of type A. Find any dependencies of type A starting at price of security 1, move paramter X of any such dependency by epsilon and check the effect of price of security 1, only recalculating the parts needed (i.e. security 1001, half of the 2-1000 secs, and security 1). My initial instinct is a design involving 1 graph per thread to start with (i.e. using a Var for graph and identity cache), the graph consisting of nodes and edges that can be represented as either records or maps, and functions attached to nodes for refreshing their values when a child has changed (using the values of child nodes). The graph get's created implicitly on first evaluation (and extended as one evaluates more nodes, and parts could end up rebuilding themselves if one changes some parameters etc). I can kind of see how I'd do it. A few things bothers me or are unclear: 1. There's quite a lot of state, which feels a bit unclojurey. 2. Implementing the "same" function for different types is not quite clear what best way to go is. Looks like multimethods perhaps. i.e. i'd like to just call (price secA) and (price secB) and the right thing happens even though completely different functions/parts of the graph get evaluated depending on the "type" of secA and secB. I don't think I need/want a record per type of security so protocols not looking like the way to go. I'm asking myself though if there's a more functional design for accomplishing the same goals? My main goals are to do things consistently so that changing a value X propagates properly, and being able to find dependencies of a given value. A DAG+identity map is my first take, but there may be something more natural for FP I'm completely missing. Thanks, Patrik -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en