Golang-like member functions

Hi, I recently found out about the notation for callables:

function (obj::MyType)(x::Int)
    return obj.mymember*x
end

I realized this syntax is extremely similar to the golang and rust-notation for member functions. So we don’t we just make the following possible:

function (obj::MyType) myMemberFunction(x::Int)
   return obj.mymember*x
end
myObject::MyType=getObjFromSomewhere()
y=myObject.myMemberFunction(6) # y==myObject.myMenber*6

I think this would fit extremely well in the language design and enable much more advances packages since it would be possible to add some OOP-patterns which may make sense at some point.
What do you think about it?

1 Like

What is the proposed syntax meant to do? (I don’t speak golang).

2 Likes

I’m sorry I messed the post up a bit, now it should be clearer. The syntax is intended to define a member function on the Type MyObject. There is another discussion on how to do this today (you add an anonymous function to the struct in the constructor, looks quite messy), but I think this is a very nice to achieve this functionality.

Welcome! Please refer to these two recent previous discussions on this topic:

And

Also, please be aware that julia is not at “that” stage of development anymore. This change would be breaking and thus would only be considered for 2.0 at best (which is unlikely, given that this syntax already means something different and the perceived benefit from this change is not generally seen as enough of a positive change (if positive at all)).

13 Likes

Thanks! I see a lot of intelligent people have thought about this for a long time.
The reason why I suggested this is that I do not see why this proposal should break anything, or what should it collide with?

A major reason why I think it would be a good idea is (still upcoming) IDE-support as well as type stability: if you have an object and you want to know what you can “do” with that object, its easy to find out in OOP-languages: you type “myObject.” and let the IDE suggest the member functions of the object. In a purely functional approach, it’s not that easy to filter for functions you can call on that object.
I also realized we are sometimes forced to “abuse” operator overloading to achieve things which should actually be done with member functions: for example Makie uses the “” syntax to get the value of observables, which of course is very compact, but “myObs.val()” is much clearer. I mean there is a reason why we have method names.

I think there’s no extra benefits in terms of IDE support or type stability if you mean syntax changes only. Because having different syntax with the same semantics is no different for compiler or tooling.
Besides that there’s differences in tooling and IDEs for dynamic and static languages, maybe you are looking for some static languages feature thinking that this feature is OOP feature?

And we are not forced to “abuse” operator overloading, you always can define val(myObs) :slight_smile:

2 Likes

Well, once you have written it down, there’s no difference, but your IDE (or julia itself) has more information for suggesting methods to you which can be called on an object: it knows you want to do something with exactly that object. For instance if I type “myServer.” and then press strg+space, any OOP-language-IDE will suggest the methods of a server. If I have a server object in julia and want to do something with it, I have to guess the name of the method using it and see if it really exists. Maybe I even get an error because the method looks like it could accept the “myServer” object, but does not.
There is already in issue on GitHub for addressing this issue:

However I am not sure how well this would work compared to the “old” OOP pattern.

But this would only cover an extremely tiny fraction of applicable functions, maybe one or two, the vast majority (sometimes hundreds) of which are external.

Having functions/methods that are external to the types is one of the core patterns and key strengths of Julia. Switching to making methods belong to types would basically destroy the language, i fear. It would at least change it beyond recognition, and since class-based oop is an inferior paradigm, I see no significant upside.

4 Likes

But where the additional information comes from? It’s equivalent to ?(myServer, arts)[tab] completion under Julia semantics. Because myServer.method(args) would be no different from method(myServer, args), it’s a purely syntax changes and in both cases IDE knows you want to do something with exactly that object.

myServer.method(args) already has a meaning in Julia, namely getproperty(myServer, :method)(args) so your proposal would be hugely breaking.

6 Likes

I’m not proposing this change, actually I’m arguing that this change would not bring any benefits for discoverability not to mention other problems this proposal would raise

2 Likes

Well I think it’s not breaking in the sense that, as long as the old meaning you described keeps working, all code will keep working since the old code would not use the new syntax. However you convinced me that it’s probably a bad idea to implement my proposal since there would need to be a way to decide whether the “existing” or “proposed” syntax is meant when you write “obj.myFunction()”, which should be possible but adds unnecessary complexity and confusion.

This sounds pretty close to the definition of “breaking”

2 Likes