I wrote a guide about Object Orientation and Polymorphism in Julia. opinions wanted!

While I agree with you, note that the OOP crowd also makes this kind argument (“people think in objects”) etc, so perhaps appeals to “natural” choices are not the best way to decide this things. Programmers are adaptive, and consider unnatural things natural after a bit of usage — consider, eg, Perl :wink:

I am afraid that these categories are pretty vacuous. What people consider 4th generation languages are all niche applications, and the 2nd generation is assembly. So yes, most general programming languages used are 3rd generation languages, and this information says very little about a language.

I agree. I’m not the one who brought up 3rd-generation languages.

1 Like

Actually, size(X, 1) is the preferred way both in Matlab and Julia.

I think so, yes. Julia benefits from several decades of progress in language design.

I’ll try to think of some ways to integrate multiple dispatch into the guide. I may just add it to the end of the section on polymorphism, ad-hoc. (pun strongly intended)

1 Like

Yeah, maybe not the best example – but that syntax can be convenient some times, and Matlab doesn’t have it, which forces you to write two statments where Julia needs only one. My main point is that writing Matlab has become difficult (I might even say painful) for me since I started using Julia.

4 Likes

can be written

Opt{T} = Union{T,Nothing}

This definitely works on 1.1, does it work on 1.0 too? I’m asking because, for some reason, I’m also always using const to do that.

1 Like

You need the const for both statements if you want performance. I think @c42f’s point was that you didn’t need the where T, not that you didn’t need the const.

1 Like

Actually, I tested it, and Opt{T} = Union{T,Nothing} does create a constant without const.

I frankly feel like Julia is a little too eager to incorporate syntactic sugar for trivial stuff like this. It’s not this or any other specific example. It’s just, you know, a thousand paper cuts. I don’t want us to end up in a situation like Perl where every valid UTF-8 string is also valid Julia code. Less is more, where syntax is concerned.

3 Likes

Whoops, my mistake! I should have tested that myself.

1 Like

Wow! I learned a lot from this conversation. I made my first comment pretty flippantly. My formal education has all been in psychology and biology, so my comment was more of a thought experiment. I appreciate everyone’s open and friendly discussion on these more technical points.

3 Likes

You are correct, my comments were not addressed to the tutorial. My motivation was to correct, IMHO, some of the points you raised in the comments. I saw comments like “OO and FP are orthogonal…”. And also comments like Functional programming is about being side effect free. Frankly, these hits a pet peeve of mine!

​FWIW… ​The point I was trying to make is that comparing OO and FP is like comparing apples and oranges. When someone does the comparison, it tells me they don’t see the relationships properly.

To state my point differently, FP can be compared to Imperative programming. It goes back to two fundamental approaches to computation namely Lambda Calculus and Turing machine. In one case you are viewing computation as a series of steps of modifying memory in another you are seeing computation as essentially abstractions, application, and values.

In an imperative style, OO defines encapsulation as a way to implement Ad Hoc polymorphism. OO is a tactical solution to a problem, not an end to itself. So it would make sense to compare say Haskell’s implementation of ad-hoc polymorphism to OO. But not to compare OO with FP.

The other point is about FP and side effect. Simon Peyton Jones, one of the architects of Haskell, once said that if a program doesn’t cause side effect, it is a heather. That is the wrong way to think about FP. In this context, FP is about referential transparency. You can easily define a state full computation as a function. Challenge is how to do it while being referential transparent as is required by FP.

​Hope that explains it.

Thanks

Daryoush​

Unfortunately, I’m more confused than before!

The latter statement sound exactly as if you’re saying FP and OO are orthogonal: i.e. they address completely different concerns.

I said FP was about putting constraints on side effects, not being free from them. I didn’t didn’t mention the kinds of constraints explicitly, but what I had in mind was forcing side effects to be representing as values of types with referential transparency. (e.g. monads)

I guess you have a point that I was more focused on the practical implications of referential transparency (controlling side effects) than the referential transparency itself.

The impression I got from your post was that your pet peeve was the term “object oriented”, since we appear to essentially have the same ideas about FP: everything (including but not limited to side effects) must be representative of a value, and OO and FP have entirely different concerns, which is to say, they are orthogonal.

I also wonder why your initial post was mostly about your perception that object orientation is useless if your aim was to correct my understanding of functional programming. I cannot see the relationship between these topics.

1 Like

I see orthogonal as a relationship between two vectors of the same dimensions. So if one thinks of ideas as forming some sort of tree structure, two things make sense to be compared if they are peers. That is what I assumed you meant, and what I objected. In that, I tried to lay out the hierarchy as I see it and tried to place ideas on the right places

As I said, I see OO, Dynamic Dispatch, and Haskell’s class (see https://people.csail.mit.edu/dnj/teaching/6898/papers/wadler88.pdf) as orthogonal approaches to implementing AdHoc polymorphism. They can be compared, but FP and OO are not peers, but FP and Imperative programming are peers.

What I mean is that OO and FP solve different problems, and the patterns of each can be used together because one is concerned with the description of data and the other with the description of processes. This is what I mean when I say they are orthogonal.

I agree that declarative and imperative programming are concerned with the same thing: both describe processes, but one does it by describing changes in state, and the other through symbolic expressions.

This I 100% disagree with.

OO is not about describing data, it is about Encapsulation as a solution to AdHoc polymorphism. Once you propose Encapsulation then you have to have a strategy to define data. Haskell, as for an example of FP, has its own solution to ad-hoc polymorphism that works and has none of the issues one encounters in OO. You don’t spend time thinking about if Jam spreads over bread, or bread spreads the jam, or there is a spread manager that spreads jam over bread. https://www.e-education.psu.edu/geog485/node/110

IHMO, Mixing FP, and OO is the worst decision one can make. Scala is based on similar thinking and I think it is an absolute disaster. There are many designs in Haskell that models data perfectly and consistently with FP, I challenge you to show me one that can be improved by using OO.

To give you an analogy in car design. Pickup trucks with different size cabins make sense on their own, cars in different sizes make sense on their own but mixing them is a disaster that is neither a car nor a truck. Example of what I think is El Camino cars: https://bringatrailer.com/listing/1970-chevrolet-el-camino-3/

We may just have to agree to disagree.

thanks

Daryoush

I think what we disagree about is what OO means—a recurring theme in this thread. It seems the people who like it think of it as set of strategies for creating interfaces to complex data, while those who dislike it think of it as language-level rules for controlling the organization of data.

The way I think about the term, Haskell’s type system supports a better set of tools for OO (i.e. strategies for abstracting complex, composite types)—which, like Julia’s, doesn’t rely on classes because it provides superior approaches to polymorphism.

As mentioned elsewhere, OO is a helpful tool and a bad religion. Of course the same can be said for FP and any other paradigm. One should attempt to discern and use them on problems where they are helpful and discard them when they are a hindrance.

2 Likes

Exactly. That was my motivation for the conversation from the start.

At Minimum to have OO you have to have encapsulation and object identity. You don’t need interfaces or inheritance to have OO. Encapsulation is not data modeling, it is how you organize your computation. Therefore you can’t think of OO as data organization. But if you define encapsulation as a way to implement computation you need to define a way to define data. That is secondary, not primary.

It is not about religion, its about understanding and the discipline. When I look at Haskell or Julia I get a pleasant sense that its designers have a clear view of concepts and discipline which helps them steer clear of making their language a kitchen sink of ideas with their contradiction.

I think we have made our points clear, and thanks for the conversation.

Daryoush

Continuing the discussion from I wrote a guide about Object Orientation and Polymorphism in Julia. opinions wanted!:

Thanks for writing this. This kind of content is missing in the Julia community. Or maybe I’m just unable to find it.

4 Likes

Thanks for this guide. It will help people like me who come from a more OO driven background to get a feeling of the Julian way of structuring programs. A similar article about Post-OO, which helped me, actually starts from MD.

2 Likes

My guide also covers multiple dispatch by this definition. By the stickler’s definition, it’s only single dispatch if you choose different dispatches on the basis of one type. Some people were complaining about this in my guide.

You need something like this for it to really be multiple dispatch:

collide_with(x::Asteroid, y::Asteroid) = ...
collide_with(x::Asteroid, y::Spaceship) = ...
collide_with(x::Spaceship, y::Asteroid) = ...
collide_with(x::Spaceship, y::Spaceship) = ...

I’m still trying to think of ways to address OO patterns with this kind multiple dispatch in my guide, but I’m having trouble thinking of how it relates to the topics I already cover, but maybe it could go right at the end of the section on composition and encapsulation?

I’m also thinking about another guide on FP techniques in Julia, and I was thinking of covering it there instead because it results in a lot of patterns similar to pattern matching with ADTs and things (not that that stuff is actually related to FP in the purest sense, but it’s a thing which comes up in many functional languages). Probably there is room to talk about multiple dispatch in both contexts.

I should definitely add a link to Chris’ article in my guide, though! Thanks for the reminder!

1 Like