Here's an example where there would normally be a strict hierarchy in
classic OOP:  Square <: Rectangle <: Shape

But it actually makes much more sense in Julia (why have 2 fields for
Square??):


abstract Shape
> type Rectangle
>     width::Int
>     height::Int
> end
> type Square
>     width::Int
> end
> Base.size(r::Rectangle) = (r.width, r.height)
> Base.size(s::Square) = (s.width, s.width)



Now I completely agree that ensuring a compile-time agreement of interface
is a valuable part of the language (but should ideally be optional).
People do see value in this, and it's an active design discussion.  (search
for "traits")

For composition vs inheritance, I completely agree that sometimes it's nice
to save code/typing when you have structures with a bunch of fields that
are mostly the same.  I'd argue you don't actually care about inheritance,
you just want composition but without the extra layer of structure.  This
might be best implemented with a macro:

type Wheel
>   radius::Int
> end
> type Frame
>   length::Int
> end
> type Seat
>   cushiness::Int
> end
> @compose Unicycle
>   Wheel...
>   Frame...
>   Seat...
> end


Above, a relatively simple macro can replace all the "Type..." with the
fields of the composed types, applying multiple inheritance of the
structures without the baggage required in classic OOP.  Then you can
compose your type from other types, but without having to write
"unicycle.wheel.radius"... you can just write "unicycle.radius".

(also, I'm sure this sort of macro exists somewhere...)



On Mon, Oct 19, 2015 at 11:32 AM, Abe Schneider <[email protected]>
wrote:

> I think I agree with 90% of what you wrote. I also don't know if anyone is
> arguing about single or multiple dispatch. Also, while Java and Borland's
> Object Pascal claimed a strong OO paradigm, C++ does does not (if you read
> Bjarne's design guide, he felt strongly that both OOP and functional were
> important). I'll note too, Java has slowly been moving towards a
> multi-paradigm approach by including Lambdas in the latest version.
>
> Two of the languages you list below, Swift and Scala, also mix OO and
> functional programming. While Scala has a huge push for functional
> programming, it also provides the necessary constructs to talk about
> inheritance of data (while it doesn't provide multi-inheritance, it does
> have mix-ins).
>
> I really like Julia's multi-dispatch approach, and have made great use of
> it in my own libraries. I don't think there should be any reason that
> classes should have to "own" the methods. However, what it currently
> doesn't do, is provide a method to specify the relationship of data within
> types between each other. You stated in the past this is because you want
> to keep dispatch-type separate from representation type. However, I think
> that's actually one of the most important aspects of OOP. Yes, you can
> always write an interface that assumes that each type has variable X, but I
> would claim ultimately that creates less maintainable code (partially
> because of DRY and partially because it turns what should be a compile-time
> error into a run-time error).
>
> On Sunday, October 18, 2015 at 11:28:20 PM UTC-4, Stefan Karpinski wrote:
>>
>> It's a highly debatable claim that single dispatch class-based OO leads
>> to better or more maintainable software designs. I grew up on these kinds
>> of languages – Object Pascal, C++, Ruby, Java. Despite the ongoing rhetoric
>> that this paradigm solves all sorts of program design problems, that's just
>> not what I've seen. I think this style of programming has failed to be the
>> panacea that it was promised to be. If it was really such a success, then
>> we wouldn't be seeing a fresh crop of promising new programming languages –
>> Julia, Rust, Go, Clojure, Scala, Elixir, Elm, Swift, etc. – not a single
>> one of which is a traditional class-based OO language. The message is
>> clear: we need more effective solutions. So far, Julia's multiple dispatch
>> approach seems to me far better at addressing program maintainability and
>> extensibility than classes ever were. Julia does still need a way of
>> talking about interfaces and protocols in the language itself, but that's
>> ongoing design problem, not a fundamental issue.
>>
>> On Mon, Oct 19, 2015 at 8:18 AM, Abe Schneider <[email protected]>
>> wrote:
>>
>>>
>>>
>>> On Sunday, October 18, 2015 at 9:44:21 PM UTC-4, [email protected]
>>> wrote:
>>>>
>>>> Going a bit on a tangent, I claim that object-oriented programming, at
>>>> least as embodied in C++, is not really suitable for scientific computing
>>>> and in fact has led certain codes to go astray.
>>>>
>>>
>>> C++ is purposefully a multi-paradigm language for this reason. C++11
>>> added a lot of features specifically for functional aspects of the language.
>>>
>>>
>>>>
>>>> To give a simple example, suppose you are told to write a 'matrix'
>>>> class in C++ that contains all the usual operations.  You finish writing
>>>> your class, and a week later, you are told to derive 'symmetric matrices'
>>>> as a subclass of 'matrices'.  This is trouble!  Unless you wrote your
>>>> original matrix class in a very particular way, you will have a hard time
>>>> writing a symmetric matrix class that inherits from a matrix base class.
>>>> This is not just a theoretical example; I saw someone try to do this
>>>> (unsuccessfully) in a code he had written.
>>>>
>>>
>>>
>>> Sure, you always have the option to write bad code, but that doesn't
>>> make a particular paradigm good or bad. I think Torch7 has a good example
>>> of using object oriented programming for scientific programming.
>>>
>>>
>>>>
>>>> The problem with object-oriented programming is that you have make
>>>> design decisions when you write the base classes that lock you into a
>>>> certain path.  This path may not be compatible with the flexibility needed
>>>> for scientific software projects.
>>>>
>>>
>>> I think that's true with any language. In Julia you still have to define
>>> an interface to access the variables. Yes, there are fewer mechanisms in
>>> place that restrict access, but that isn't always a good thing. You end up
>>> trading compile-time errors for run-time errors. I much rather deal with
>>> compiler-time errors.
>>>
>>>
>>>>
>>>> I for one am glad that the designers of Julia decided not to make Julia
>>>> an object-oriented language, at least not in the C++ sense of the term.
>>>>
>>>>
>>> I think there is a lot to be gained from a multi-paradigm approach.
>>> Having a language that is scientific-code friendly is important, but so is
>>> integrating it into larger systems.
>>>
>>>
>>>>
>>>>
>>>>
>>>> On Sunday, October 18, 2015 at 8:41:58 AM UTC-4, Sisyphuss wrote:
>>>>>
>>>>> When I'm learning Julia, I am always thinking what is the correct way
>>>>> to do OOP in this language. It seems to me that what I learned in C++ does
>>>>> not apply in Julia.
>>>>>
>>>>> It took me long to realize that the equivalent of Class of C++ in
>>>>> Julia is not Type, but Module. Module is the basic function unit in Julia.
>>>>>
>>>>> Thus, a Class in Julia is like
>>>>> module ClassName         # class Name {
>>>>> using                    #     include<>         // should be outside
>>>>> import                   #     include<>
>>>>> export  function         #     public  function;
>>>>> var = 1                  #     private static var;
>>>>> end                      # }
>>>>> This provides the same structure as C++.
>>>>>
>>>>> However, this design has two issues:
>>>>> 1) The visit control is not as fine-grained as in C++, the
>>>>> encapsulation is not strict;
>>>>> 2) Variables at the top level of a module are global variables.
>>>>>
>>>>> These two points are closely correlated. If we let module have private
>>>>> variables, then they are not too different from local variables, ans thus
>>>>> can be type inferred.
>>>>> I think this is a natural way to do OOP with Julia.
>>>>>
>>>>>
>>>>>
>>>>>
>>

Reply via email to