I haven't been following this thread closely, so I have no frame of reference here, I'm like a child who wanders into the middle of a julia-users thread...
A few observations: - functions being called with composite types which have some non-concrete fields suffer no performance penalty, as long as you don't use those non-concrete fields - if using a non-concrete field, you can use kernel functions (aka barrier funciton): http://docs.julialang.org/en/release-0.4/manual/performance-tips/#separate-kernel-functions The kernel fn could be what Tom suggested nvp(myBond) = isdefined(myBond, :nvp_val) ? myBond.nvp_val :_nvp!(myBond, myBond.pricingEngine) _nvp!(bond, pe:PricingEngine1) = ... # writes to nvp_val field and returns it _nvp!(bond, pe:PricingEngine2) = ... On Tue, 2016-02-02 at 00:41, Christopher Alexander <[email protected]> wrote: > I've been trying to think of a way to implement this, but I'm having some > trouble. Perhaps this can be a discussion around organizing objects in > Julia to best exploit the benefits of multiple dispatch. Let's say I have > a Bond type: > > type Bond{P <: PricingEngine} > # some attributes here > pricingEngine::P > end > > > Then the particular PricingEngine object for each instantiation of "Bond" > has its own term structure (perhaps this could be stored with the bond > itself?). Each PricingEngine sub type (in my code PricingEngine is > actually an abstract type itself) has its own calculation method, where > various components of the bond are calculated (e.g. NPV, etc). I suppose > this could be separated out, but I essentially want to provide to the end > user something like npv(myBond). The bond knows whether it's been > calculated or not, and if it hasn't, it does so via its pricing engine. > Otherwise, it returns a cached value of its NPV (already having been > calculated). If I break all of these things out (bond/instrument, term > structure, and pricing engine), I would envision a method like this: > npv(bond, pricing_engine, term_structure) > > Is there a better/more "Julian" way to organize this? Perhaps keeping the > TermStructure separate from everyone and passing it into methods where I > need it? > > > On Monday, February 1, 2016 at 5:05:21 PM UTC-5, Tom Breloff wrote: >> >> Just so you realize... in this example "pricingEngine" has an abstract >> type, and you've possibly lost whatever performance gain you were hoping >> for in your original question. To solve you either need to take the same >> approach in defining and updating the Bond object, or maybe rethink how >> you're doing this. You should consider utilizing multiple dispatch a >> little more keep your PricingEngine and TermStructure separate: >> >> do_something(engine::PricingEngine, term::TermStructure) = ... >> >> >> >> On Mon, Feb 1, 2016 at 2:07 PM, Christopher Alexander <[email protected] >> <javascript:>> wrote: >> >>> This doesn't seem to work if your PricingEngine object is attached to >>> some other object. Like, for example if you have: >>> >>> type Bond >>> pricingEngine::PricingEngine >>> end >>> >>> >>> myPE = PricingEngine(4.5, 5.5, TermStructureA()) >>> >>> >>> myBond = Bond(myPE) >>> >>> >>> myPE = update_ts(myPE, TermStructureB()) >>> >>> >>> At that point, myBond's pricing engine still points to the older myPE >>> with TermStructureA. >>> >>> On Monday, February 1, 2016 at 1:58:54 PM UTC-5, Christopher Alexander >>> wrote: >>>> >>>> So something like: >>>> >>>> function update_ts(pe::PricingEngine, newTS::TermStructure) >>>> newPE = PricingEngine(pe.varA, pe.varB, newTS) >>>> return newPE >>>> end >>>> >>>> >>>> myPE = PricingEngine(4.5, 5.5, TermStructureA()) >>>> >>>> >>>> myPE = update_ts(myPE, TermStructureB()) >>>> >>>> You probably wouldn't be able to update the "myPE" object in place right >>>> (i.e. updating it in the actual update_ts method and then returning >>>> itself)? >>>> >>>> >>>> On Monday, February 1, 2016 at 1:50:41 PM UTC-5, Tom Breloff wrote: >>>>> >>>>> You could just construct a new object with the new TermStructure, >>>>> instead of overwriting the old one. >>>>> >>>>> On Mon, Feb 1, 2016 at 1:27 PM, Christopher Alexander < >>>>> [email protected]> wrote: >>>>> >>>>>> Hello all, I have a question about the usage of parametric types. I >>>>>> know these bring about a performance boost (at least that was my >>>>>> understanding), but I have a situation where I have a parametric type >>>>>> defined as such: >>>>>> >>>>>> type PricingEngine{T <: TermStructure} >>>>>> varA::Float64 >>>>>> varB::Float64 >>>>>> ts::T >>>>>> end >>>>>> >>>>>> >>>>>> But then I need to actually swap the existing term structure with >>>>>> another subtype of TermStructure further down the road. Using parametric >>>>>> types, it complains because I guess it's locked in to using whatever >>>>>> TermStructure sub type is initially there when I instantiate the >>>>>> PricingEngine type. Is there anyway to do such an update while still >>>>>> using >>>>>> a type parameter, or am I stuck just with a definition that uses the >>>>>> broader abstract type? >>>>>> >>>>>> Thanks! >>>>>> >>>>>> Chris >>>>>> >>>>> >>>>> >>
