I don't have enough background in genetic algorithms to understand what you 
are trying to accomplish, but I think that to answer the question of how to 
write code so that it can be generally extended by users, the first thing 
to ask is what the interface to the code that you want to write really is 
(in abstract terms). Then, one can start to model it with types, generic 
functions, inheritance, etc.

Also, to create a generic function without actually providing any 
implementations, I've lately been using things like

f(::None) = nothing

which seems to work fine.

On Saturday, 28 December 2013 00:01:24 UTC+1, andrew cooke wrote:
>
> 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
>>
>

Reply via email to