If you make `ts` the last parameter, using an inner constructor you can leave 
that field undefined when you initially create the object, then fill it in 
later. 
You may need to sprinkle some `isdefined(b, :ts)` in various places in your 
code.

Happy New Year!
--Tim

On Friday, January 01, 2016 11:01:02 AM Christopher Alexander wrote:
> I'm actually having a slight problem with this implementation.  Basically,
> in using the parametric approach above, when I initially create an instance
> of the Bond type with the NullTermStructure and then set its term structure
> with the new TermStructure instance that I create (creating the circular
> reference), I get a convert error.  I'm assuming this is because the
> initial instantiation of the Bond wants a TermStructure of type
> NullTermStructure, so then when I try to re-set it with PiecewiseYieldCurve,
> it complains.  Is there any way to avoid setting it with the
> NullTermStructure in the first place?
> 
> Thanks!
> 
> Chris
> 
> On Friday, January 1, 2016 at 1:24:21 PM UTC-5, Christopher Alexander wrote:
> > Thanks Tim, this is very helpful!  Happy New Year!
> > 
> > - Chris
> > 
> > On Thursday, December 31, 2015 at 6:33:29 PM UTC-5, Tim Holy wrote:
> >> See
> >> http://docs.julialang.org/en/stable/manual/faq/#how-do-abstract-or-ambigu
> >> ous-fields-in-types-interact-with-the-compiler and the section
> >> afterwards. You'd be better off with
> >> 
> >> type Bond{T<:TermStructure}
> >> 
> >>     rate::Float64
> >>     ts::T
> >>     mat_dat::Date
> >> 
> >> end
> >> 
> >> --Tim
> >> 
> >> On Thursday, December 31, 2015 02:42:11 PM Christopher Alexander wrote:
> >> > Hello all,
> >> > 
> >> > I have a question about the usage of circular references in types.  In
> >> 
> >> a
> >> 
> >> > project I am working on, I am running into several situations where
> >> 
> >> this
> >> 
> >> > type of design appears to be the best issue.  For example, let's say I
> >> 
> >> have
> >> 
> >> > this (this is a massive simplification but illustrates my point):
> >> > 
> >> > abstract TermStructure
> >> > 
> >> > 
> >> > type Bond
> >> > rate::Float64
> >> > ts::TermStructure
> >> > mat_date::Date
> >> > end
> >> > 
> >> > 
> >> > function Bond(rate::Float64, mat_date::Date)
> >> > 
> >> >    ts = NullTermStructure()
> >> >    return Bond(rate, ts, mat_date)
> >> > 
> >> > end
> >> > 
> >> > 
> >> > type NullTermStructure <: TermStructure end
> >> > 
> >> > 
> >> > type PiecewiseYieldCurve <: TermStructure
> >> > settlement::Date
> >> > bonds::Vector{Bond}
> >> > end
> >> > 
> >> > 
> >> > function PiecewiseYieldCurve(settlement::Date, sched::Schedule, rate::
> >> > Float64)
> >> > 
> >> >   bonds = Vector{Bond}(length(sched))
> >> >   for (i, d) in enumerate(sched)
> >> >   
> >> >      new_bond = Bond(rate, d)
> >> >      bonds[i] = new_bond
> >> >   
> >> >   end
> >> >   
> >> >   pyc = PiecewiseYieldCurve(settlement, bonds)
> >> >   for b in bonds
> >> >   
> >> >     b.ts = pyc
> >> >   
> >> >   end
> >> >   
> >> >   return pyc
> >> > 
> >> > end
> >> > 
> >> > 
> >> > Firstly, I guess, is this the best implementation?  There are
> >> 
> >> situations
> >> 
> >> > where I need the bonds of the PiecewiseYieldCurve to be aware of the
> >> > TermStructure to which they are connected.  Secondly, do I take a
> >> > performance hit from this?  The PiecewiseYieldCurve instance will have
> >> > parts of it updated as I run some of my pricer methods (not shown).
> >> > 
> >> > Thanks!
> >> > 
> >> > Chris

Reply via email to