To make my example work I think you'd need some kind of horrible dynamic
scoping. So just to be clear, my question is - what should I do instead?
The options I can see are:
* add a function pointer to the population and use that explicitly
* make Population an abstract type so that users can stick the extra state
in there.
I am guessing the second is better...
Andrew
On Friday, 27 December 2013 19:32:55 UTC-3, andrew cooke wrote:
>
>
> How do I write a library so that it can be arbitrarily extended by users?
>
> In particular, I was trying to write a Genetic Algorithm library (I know
> there is one, but I didn't understand it, perhaps for the reasons here).
> And so I created a parameterized "Population" type and then wrote a main
> loop that calls methods like select, breed, mutate, etc.
>
> The idea being that someone who uses the library provides their own
> parameterization of Population and functions that implement the methods for
> that type.
>
> I hope / pray this is the right way to do things, as I try to get into
> this multiple dispatch thing.
>
> BUT then I needed a "score" function. And that needed some extra state
> that isn't available in Population (the score of my individuals depends on
> more than their type - it depends on data specific to this particular run).
> So I created the function inside an outer scope with the data I needed -
> created a closure. But then it no longer worked (see example code).
>
> How do I get around this?
>
> Also, is there a way to avoid declaring the base function when I have no
> useful implementation?
>
> module Experiment2
> export foo, bar
>
> function bar(x)
> foo(x)
> end
>
> function foo(x)
> println("base")
> end
>
> end
>
>
> module Baz
> using Experiment2
>
> function Experiment2.foo(x::Float64)
> println("float")
> end
>
> function test()
> function Experiment2.foo(x::Int)
> println("int")
> end
> bar(1.0) # works (prints "float")
> bar(1) # THIS PRINTS "base" WHEN I WANT "int"
> end
>
> test()
>
> end
>
> Thanks, Andrew
>