Thanks for the links!

My main complaint with declaring the variables rather than defining the 
interface. I was never a fan of Java interfaces, which I think is 
essentially what the current Julia design already mimics (if not in a 
slightly less formal design). Having to redeclare variables for larger 
projects can become difficult for the programmer who might have to visit 
each of the interfaces defined to see which variables are expected to be 
exported. If you only allow for a single interface to be defined, you are 
saved some work, but at the expense of design (I can think of many 
instances where multiple instances are desirable).

I think allowing abstract types to declare variables solves most of this 
problem. I can appreciate people's reserve on implementing 
multiple-inheritance. As another data point, most modern languages seem to 
using Mixins instead (e.g.: Java 8, Scala, Ruby, Swift). Java 8 is 
especially interesting as they started off with the same interface design.

In Scala (if my memory serves me correctly), Mixins are enabled by having a 
separate structure-type called traits. What distinguishes classes from 
traits is that classes are allowed constructors whereas traits are not. 
This eliminates most of the problems people have with implementing multiple 
inheritance.

Obviously, it's possible to design the NNModules with the current feature 
set of Julia. However, at least to me, it won't feel like a good design if 
I have to repeat the same fields for all children of NNModules (there is 
more than just output). It also makes me worry as to how well Julia will 
scale for larger projects, though the answer may be that is not it's main 
use.


On Friday, June 20, 2014 2:30:04 AM UTC-4, Tobias Knopp wrote:
>
> Hi Abe,
>
> There has been various discussions about this in the following threads:
>
> https://github.com/JuliaLang/julia/issues/4935
> https://github.com/JuliaLang/julia/issues/1974
>
> You might see that there is not yet a consus if one of these features will 
> be implemented or not.
>
> I have been myself trying to figure out how to resolve the issue of 
> duplicating code until Jeff and Tim showed me the solution Jameson has 
> outlined above.
> I don't really see why solution is too verbose. You only have to define 
> the getter function for public types where it is encouraged anyway to 
> define functions for data encapsulation. Fields are in the current view 
> private. 
>
> You might be also interested in 
> https://github.com/JuliaLang/julia/issues/6975 where we discuss how to 
> define interfaces more formally as it is done now.
>
> Cheers,
>
> Tobi
>
> Am Freitag, 20. Juni 2014 04:15:21 UTC+2 schrieb Abe Schneider:
>>
>> Okay, so that matches the Java interface style, where you would then make 
>> one function per variable you want to officially sanction as required.
>>
>> One thing I didn't except from doing this is that if you do:
>> type OtherModule <: NNModule end
>>
>> mod = OtherModule
>> getoutput(mod)
>>
>> I was expecting an error within the method that 'output' doesn't exist 
>> for 'mod'. Instead I get:
>> ERROR: no method getoutput(Type{OtherModule})
>>
>> which is a much nicer complaint.
>>
>>
>> The downside of the design is that now I have to duplicate the variable 
>> for every type, but also make sure there's a function defined at top. 
>> However, of the choices to make, it's probably the cleanest (though a macro 
>> might save a little on typing).
>>
>> Thanks for the help!
>>
>>
>>
>> On Thursday, June 19, 2014 9:14:34 AM UTC-4, Jameson wrote:
>>>
>>> here is my recommended solution:
>>>
>>>
>>> abstract NNModule
>>> getoutput(nnm::NNModule) = nnm.output # <<-- add this line
>>>
>>> type LinearModule <: NNModule
>>>   weight::Array{Float64}
>>>   output::Array{Float64}
>>> end
>>>
>>> type SigmoidModule <: NNModule
>>>   output::Array{Float64}
>>> end
>>>
>>>
>>> On Thu, Jun 19, 2014 at 8:18 AM, Abe Schneider <abe.sc...@gmail.com> 
>>> wrote:
>>>
>>>> I'm trying to figure out the best way to factor code that consists of 
>>>> repeated modules which all share some common attributes.
>>>>
>>>> Specifically, if I have (very abbreviated from actual code):
>>>>
>>>> abstract NNModule
>>>>
>>>> type LinearModule <: NNModule
>>>>   weight::Array{Float64}
>>>>   output::Array{Float64}
>>>> end
>>>>
>>>> type SigmoidModule <: NNModule
>>>>   output::Array{Float64}
>>>> end
>>>>
>>>> For both modules I need an 'output' variable. I know the idea of 
>>>> putting variables in an abstract type has come up before. However, while 
>>>> it 
>>>> would solve this problem, it is also not yet resolved (and may or may not 
>>>> actually happy).
>>>>
>>>> Given that, two alternatives occur to me:
>>>> 1. Keep the current design and be okay with repeated code (difficult)
>>>> 2. Use a macro to create the repeated code for me
>>>>
>>>> Option (1) is certainly the easiest, and probably the one I'll stick 
>>>> with for now. However, it seems error prone and (IMHO) produces ugly code.
>>>>
>>>> Option (2) has the problem that it can make what's actually happening 
>>>> opaque and could potentially produce bugs that are difficult to track down.
>>>>
>>>> So my questions are: 
>>>> (1) Have other people come across design issues like this before, and 
>>>> how did they deal with it?
>>>> (2) Is there a macro out there already to accomplish this? After a 
>>>> quick search, I found '@delegate' proposed as a solution for something 
>>>> like 
>>>> this, but it was never officially merged. If not, any suggestions on how 
>>>> such a macro should act/look?
>>>>
>>>>
>>>> As a side note, it would be great if Julia added properties to abstract 
>>>> types. The current design gives something equivalent to Java's interfaces, 
>>>> where most languages opt for mixins instead.
>>>>
>>>> Thanks!
>>>>
>>>
>>>

Reply via email to