Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider using := instead of = for method definitions #1846

Closed
toivoh opened this issue Dec 29, 2012 · 5 comments
Closed

Consider using := instead of = for method definitions #1846

toivoh opened this issue Dec 29, 2012 · 5 comments

Comments

@toivoh
Copy link
Contributor

toivoh commented Dec 29, 2012

My feeling is that assignment

x = 1

and (method) definition

f(x) = 1

are really two different things, and the fact that the operator = has been overloaded to do both is creating unnecessary confusion and complications. Consider e.g. #1717. If the method definition syntax were changed to

f(x) := 1

instead (which feels like a sensible alternative), remnants of matlab indexing such as x(i) = 1 would be able to give much more sensible error messages.

This is of course a breaking change of epic proportions, but do I think that it would be worth it in the long run. The two syntaxes for method definition could coexist for a long time to ease the transition.

I think that the main benefits with this change would be increased clarity and syntactic elbow room, and better error messages. A few thoughts about possible benefits:

  • Currently, assignment syntax = serves multiple purposes in julia, depending on the type of the left hand side in the AST:

    • Symbol ==> variable assignment
    • :. expression ==> field assignment (setfield)
    • :ref expression ==> indexed assignment (assign)
    • :call expression ==> method definition

    The last one clearly stands out. It is not always easy to see what constitutes a method call, e.g. the fact that x+y=z is a method definition might catch many by surprise. x+y:=z would leave no doubt that this is a method definition.

  • Method definitions that mirror usage could be made to work consistently. E.g.

    x::MyType + y::MyType    :=  MyType(x.data + y.data)  # +
    (x::MyType)[i::Int]      :=  x.data[i]                # ref
    (x::MyType)[i::Int] = y  :=  x.data[i] = y            # assign
    [x::MyType, y::MyType]   :=  MyType([x.data, y.data]) # vcat
    

    I don't know if this would be a preferred style, but it does have the beauty to make explicit in the method definition what kind of operation is being overloaded. Neither the writer nor the reader would have to know that ref corresponds to indexing.

  • Generalized assignment, as discussed here could be implemented, if desired.

The way that I see it, the only real downside is that all existing code will have to be updated to accommodate the change. Others will have to weigh that against the benefits.

@JeffBezanson
Copy link
Sponsor Member

I appreciate these arguments.
First, I do not think we will fully change the syntax. While method definition is different from other assignments, it is not easy to explain how, and it is not clear how := expresses this difference. Using := would appear "randomly different".

If we ever start using :=, for example for in-place assignments of some kind, it might make sense to allow it for method definition as well. However, using x[i] := y for ref method definition gives up potential array-related syntax.

We might be able to allow more readable ref definitions with the function keyword:

function (x::Foo)[i::Int]
  ...
end

@toivoh
Copy link
Contributor Author

toivoh commented Dec 29, 2012

Ok, I see that you might have other plans for the := operator. Claiming a perfectly good operator should obviously have been on the cons list. I also agree that the issue of usage-like definitions for e.g. ref is somewhat orthogonal. I still argue that the difference is not random at all, but profound:

Though method definition is indeed superficially similar to assignment, I do think that there are some very clear differences. Method definition, unlike assignment, defers evaluation of the right hand side. But, to my mind, the main difference is that

  • Assignment is meant to be done many times, and can be precompiled.
  • Method definition is only meant to be done once. In fact, at least until
    automatic recompilation of dependent functions #265 is resolved, there's no guarantee that a method redefinition will be
    visible everywhere. Even when it is, it is a very bad idea to use method
    redefinition such as f() = value as a substitute for variable updates x = value.
    They are in no way interchangeable.

Also, assignment can be precompiled, which I am not sure that method definition always can. Indeed, method definitions will influence the compilation of other parts of the code! This distinction might become more important with static compilation. In that sense, := (and function) would serve as a warning sign, somewhat like @.

@sth4nth
Copy link

sth4nth commented Dec 31, 2012

We do need a in place operator. For any iterative algorithm, there must be some variables need to be reused
like
while !converged
myMatrix = foo()
end

The storage of myMatrix should be reused instead of allocating new ones and deallocating myMatrix. I am thinking of .= for this.

@JeffBezanson
Copy link
Sponsor Member

We decided not to use := for method definitions.

@toivoh
Copy link
Contributor Author

toivoh commented Jan 14, 2013

Fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants