The best way is probably to introduce a small type hierarchy for your heat 
capacity specification, some of which interpolate and some of which don't. 
For example,

```
abstract HeatCapacity
immutable ConstantHeatCapacity{T} <: HeatCapacity
    C::T
end
heatcapacity(c::ConstantHeatCapacity, x) = c.C # will most likely be inlined

immutable InterpolatedHeatCapacity{T<:Interpolation} <: HeatCapacity
    itp::T
end
heatcapacity(c::InterpolatedHeatCapacity, x) = itp[x] # or however you 
interpolate the heat capacity with your implementation

function SomeFunction(hc::HeatCapacity, otherparams...)
    # do your calculations here
    # whenever you need the heat capacity at x, you can use 
    C = heatcapacity(hc, x)
    # which will be type-stable
end
```

What we've done is to introduce an abstraction barrier between the 
calculation and the representation of the heat capacity, in order to keep 
everything type-stable and performant while letting `SomeFunction` be 
agnostic of how the heat capacity is calculated.

// T

On Friday, May 22, 2015 at 7:39:26 PM UTC+2, Scott T wrote:
>
> Second code block should have 
>
> call(rsf::RunsSomeFunction, x) = rsf.f(x)
>
> instead and, if it's not obvious from the `call` functions, I'm using 0.4 
> - would be happy to hear about what the plans are for making higher-order 
> functions faster so I can pass them around as arguments without worrying so 
> much about speed.
>
>
> On Friday, 22 May 2015 18:34:27 UTC+1, Scott T wrote:
>>
>> I'm aware of the fact that higher-order functions will currently be slow, 
>> and you can get around this by using a package like FastAnonymous or by 
>> using custom types:
>>
>> function SomeFunction(value, par)
>>    # do stuff with value based on parameter
>> end
>>
>> type RunsSomeFunction 
>>     par1
>> end
>>
>> call(rsf::RunsSomeFunction, x) = SomeFunction(x, rsf.par)
>>
>> How should I deal with a situation where I have a function passed from 
>> somewhere else - say, an interpolation routine - and I need to access this 
>> function when using such a type? The function isn't known at compile-time, 
>> so I can't use the above trick. But I also feel like writing out something 
>> similar to the below code
>>
>> type RunsSomeFunction
>>     f::Function
>> end
>>
>> call(rsf::RunsSomeFunction, x) = RunsSomeFunction.f(x)
>>
>> mytype = RunsSomeFunction(make_interpolant_from(file))
>>
>> isn't good, since I'm including a function inside a type (very OO-ish).
>>
>> The context is that I've got some types which represent heat capacities, 
>> varying across temperature and pressure, and these are later included in an 
>> integration routine. Making the heat capacities constant or a simple 
>> function of P/T is easy - they can be included directly in the body of the 
>> code. Interpolating from a file isn't so easy, and slows things down a lot 
>> more than I thought it would. Any ideas? Am I asking too much at the moment?
>>
>> Cheers,
>>
>> Scott
>>
>

Reply via email to