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.
>
>