the getters/setters issue will be fixed by https://github.com/JuliaLang/julia/issues/4935 which i think makes 1 a nice solution in many cases.
unfortunately interest in that issue seemed to die when (i think?) there was no consensus on the details. andrew On Wednesday, 26 February 2014 14:03:27 UTC-3, Robert Feldt wrote: > > Hi Kevin, > > Thanks for your input. You are right, I did forget about your "method 1" > which I've also used at times. It does feel a bit annoying but I can't > describe why; maybe it's an (unfounded) concern that performance is > hampered but I guess there will be almost zero effect of that in practice > given Julia's backend and optimizations in LLVM. Maybe we can address the > getters and setters issue with a simple macro? Hmm... > > There seems to be discussions about the possibility to override the dot > operator / field access which allow for a lot of flexibility if added: > https://github.com/JuliaLang/julia/issues/1974 > > Cheers, > > /Robert > > Den onsdagen den 26:e februari 2014 kl. 17:47:32 UTC+1 skrev Kevin Squire: >> >> Hello Robert, >> >> Thanks for posting this question. This is something I've struggled with >> and attempted to address in a couple of different ways. I'm not totally >> happy with either of the solutions, but I'll share them in the hope that >> they're useful. >> >> 1. One method you did not mention was to implement everything against an >> abstract base class, but override individual functions for different >> concrete classes. To avoid depending on the actual type implementation, >> additional functions are defined on the concrete types which give access to >> the data. >> >> A couple of variations on this include the GraphicsDevice interface in >> Julia ( >> https://github.com/JuliaLang/julia/blob/master/base/graphics.jl#L177-L192), >> and Graphs.jl ( >> http://julialang.org/Graphs.jl/interface.html#interface-declaration-and-verification >> ). >> >> This is a pretty good solution, although how well it works is problem >> dependent. I've sometimes found it challenging/annoying to design >> "getters" and "setters" just to make sure that the functions and types are >> only loosely coupled. >> >> 2. I used your third design pattern when implementing OrderedDicts ( >> https://github.com/JuliaLang/DataStructures.jl/blob/master/src/ordereddict.jl), >> >> and used John Miles White's @delegate macro to simplify the code ( >> https://github.com/JuliaLang/DataStructures.jl/blob/master/src/delegate.jl). >> >> >> The @delegate macro makes the code less cluttered, but has the downside >> in that you don't have access to other/new methods for the wrapped type >> unless you specify them. >> >> Hope this is useful. Cheers! >> >> Kevin >> >> >> On Tue, Feb 25, 2014 at 10:44 PM, Robert Feldt <robert...@gmail.com>wrote: >> >>> I really like Julia's dispatch mechanisms, type system and so on. I have >>> found a number of different ways I use it to design libraries and programs. >>> But it would be great with some patterns/ideas/feedback from more seasoned >>> Julia programmers. What are your Julia Design Patterns? >>> >>> A concrete situation that I have struggled somewhat with is how to best >>> design in Julia for the situation where I have one main/default >>> algorithms/set-of-behaviors+data but then with a multitude of small >>> variations. Typically there is a large set of data and methods/functions >>> that are the same for the whole class of things and there are only 1-4 >>> functions/methods that need to change for each variation. An example from >>> BlackBoxOptim ( https://github.com/robertfeldt/BlackBoxOptim.jl ) is >>> where there is one type for DifferentialEvolution and then multiple >>> different variants of DE where only 1-2 functions differ from the "base" DE >>> one. >>> >>> I have found a few different "design patterns" for this situation but >>> not sure what is the long-term best: >>> >>> 1. Have a few Function fields in the "base" (composite) type which are >>> set up at construction time and that implements the variant-specific >>> behaviors. This is simple and direct but feels a bit "un-Julia" since it >>> does not really use the dispatch system. One also has to predict the >>> variation points (here: function) upfront which might not be flexible >>> enough. Also performance might suffer since the types of the function not >>> known. >>> >>> 2. Have one XBase type which includes a field of an abstract XStrategy >>> type where specific sub-types to XStrategy implements each variant by >>> implementing variant-specific functionality. This seems fairly efficient, >>> but again one has to predict more or less where the variations should >>> happen since the functions on the XBase type need to call to the XStrategy >>> functions. >>> >>> 3. Have one XBase type which is then included as a field in specific >>> variants. This seems efficient and flexible but the code is somewhat >>> cluttered in that one has to have one extra indirection when accessing >>> common data/fields (this is a similar problem in 2 above though). >>> >>> 4. "Copy" the common data/fields of XBase into each specific variant. >>> This is the most flexible and should have high performance but there seem >>> to be a risk that bugs have to be changed in multile source code locations >>> since it is a kind of "copy-paste reuse". >>> >>> Would be great to hear your advice/feedback on how you design in/with >>> the Julia type and dispatch system. >>> >>> Thanks, >>> >>> Robert Feldt >>> >> >>