Inheritance should be understood in terms of properties (and operations on 
properties) of a classes and sub-classes.  In functional programming 
language,
application of functions like *func_1*(x, y, *func_2*(z, p)) is implicitly 
exploiting the idea of inheritance. Making such relationships explicit
in programming languages will lead to much less errors at run time with 
compile time ( definition and declaration ) checks.


On Friday, October 23, 2015 at 7:59:26 AM UTC-7, Brendan Tracey wrote:
>
> On Friday, October 23, 2015 at 7:38:37 AM UTC-6, Abe Schneider wrote:
>>
>> An OO approach is really just specifying an interface in a formal manner. 
>> The second you write any type of interface, you always risk making a choice 
>> that will haunt you down the road. I don't see the difference between
>>
>> class Foo {
>>   float getX() { ... }
>>   float getY() { ... }
>> }
>>
>> and:
>>
>> type Foo { ... }
>> function getX(f::Foo) -> float { ... }
>> function getY(f::Foo) -> float { ... }
>>
>> except that an instance of `foo` is being passed implicitly in the first 
>> case. To that extent, I would say Julia OO (i.e. on the dispatching). Where 
>> it is not OO is in the layout of the data.
>>
>
> In some  languages there is no difference. In Go, a method is exactly a 
> function that can be called with a special syntax. One can do
>
> c := mat64.NewDense(5, 5, nil)
> c.Mul(a, b)
>  
> or one can do
> (*mat64.Dense).Mul(c, a, b)
>
> There aren't many cases where one would actually want to do the latter, 
> but it makes the definition of behavior clear.
>
> I think the difference in Julia would be the interaction with multiple 
> dispatch. In the former case, it seems like getX would live in its own 
> namespace (only accessible through the Foo class), while in the latter case 
> it would add to the many definitions of getX.
>
>
> It is true that with a more OO language, because of its formalism, you run 
>> the risk of declaring variable types in a parent class that might not be 
>> correct in the child classes, so some planning is required. However, what 
>> you gain is better code in the long run. For example, I might have:
>>
>> abstract Baz
>>
>> type Foo <: Baz {
>>   x::Float
>> }
>>
>> type Bar <: Baz {
>>   x::Float
>> }
>>
>> and an interface:
>>
>> getX{T <: Baz}(b::T) -> Float = b.x
>>
>>
>> which works fine, except maybe someone else comes along and writes:
>>
>> type Blob <: Baz {
>>   myX::Float
>> }
>>
>> Now to fix your interface, you have to write a separate `getX` for 
>> `Blob`. This might not seem like a big deal, except you might not catch 
>> this issue until run time (I don't think there is a way a static-checker 
>> could identify the problem). Imagine a large library or base of code, with 
>> many people working on the code, and you suddenly are exposed to a large 
>> number of issues.
>>
>
> This seems more like an issue of compiler vs. no compiler issue than one 
> with OO vs. multiple dispatch.
>  
> You can do OO without inheritance (or OO like things if your definition of 
> OO includes inheritance). In Go, one would define 
>
> type GetXer interface {
>      GetX() float64
> }
>
> I could then write a function
> func SquareX(g GetXer) float64 {
>      v := g.GetX()
>      return v * v
> }
>
> Now, any type that has a GetX method can be passed to SquareX. There is no 
> inheritance necessary to make this happen.
>
>

Reply via email to