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

a+b=2 should be an error #2032

Closed
alanedelman opened this issue Jan 13, 2013 · 15 comments
Closed

a+b=2 should be an error #2032

alanedelman opened this issue Jan 13, 2013 · 15 comments

Comments

@alanedelman
Copy link
Contributor

discovered by my 10 year old son:


julia> a
a not defined

julia> a+a=2
syntax error: function argument names not unique

julia> a+b=2 # should be an error

julia> a
a not defined

julia> b
b not defined

@toivoh
Copy link
Contributor

toivoh commented Jan 13, 2013

You just defined the method

+(a,b) = 2

I also think that this behavior can be pretty confusing. I'm not sure how easy it is to get at it, since a+b gets represented as +(a,b) already during parsing. See also #1846.

@alanedelman
Copy link
Contributor Author

now that i understand it , i kind of like it :-)
but i do see the confusion

julia> a+b=5;1+1
5

@PallHaraldsson
Copy link
Contributor

It seems to me this was closed because it was fixed but not fully (I'm using 0.3.1).

julia> a+b=2
"+ (generic function with 126 methods)" # not sure how to not get + treated as a markup..

[message should maybe say you did NOT redefine? not too important..]

julia> 1+2
3

However, the above fix is not consistent with (implemented more fully):

julia> a+b+c=2
Warning: Method definition +(Any,Any,Any) in module Base at operators.jl:82 overwritten in module Main at none:1.

  • (generic function with 126 methods)

[still learning, not sure why +(Any,Any,Any) is treated differently with the fix - I assume since it is because it's another function; not sure why it wasn't fixed - overlooked/not important or likely to be a common mistake?]

julia> 1+2+3
2

julia> 1+2+3+4
10

julia> a+b+c+d=2

  • (generic function with 126 methods)

    +(Any,Any,Any,Any) and so forth is I guess not implemented in standard libray. Not needed, not sure why three-way was (and not four-way) or it's point.. Is it difficult to fix this thing once and for all?]

julia> 1+2+3+4
2

Didn't check all operators, just noting * works but not:

julia> a_b_c=2
Warning: Method definition *(Any,Any,Any) in module Base at operators.jl:82 overwritten in module Main at none:1.

  • (generic function with 127 methods)

julia> 1_2_3
2

[not sure why I get a different error message here, but - is prevented]

julia> a-b-c=2
ERROR: syntax: "-(a,b)" is not a valid function argument name

There are probably endless variations..:

julia> div(a, x)=2
div (generic function with 1 method)

julia> div(10, 2)
2

This one SHOULD work this way? When is a function just a function that you want to be able to redefine?

@StefanKarpinski
Copy link
Sponsor Member

There wasn't any fix – a + b = 2 means defining a very general two-argument method for +.

@PallHaraldsson
Copy link
Contributor

Confused then - strike that seems to be a variant of my first bug..:

julia> a+b=2
"+ (generic function with 127 methods)"

julia> 1+2
3

@JeffBezanson
Copy link
Sponsor Member

Also a+b+c is parsed as a single call to + with 3 arguments. That's just how it's parsed. So you can define methods for that too.

Also all of these syntaxes do not "define functions", they add methods. In every case. With no types specified, the default is Any, the most general possible. So the new + is just less specific than the existing methods for +.

@JeffBezanson
Copy link
Sponsor Member

The following will avoid "inheriting" the standard + and create your own fresh function:

julia> global +
Warning: imported binding for + overwritten in module Main

julia> a+b = 2
+ (generic function with 1 method)

julia> 1+2
2

@PallHaraldsson
Copy link
Contributor

Why is the three-way + inherited without global? See my first comment..

@JeffBezanson
Copy link
Sponsor Member

Because all definitions of a given + are part of the same function object.
The name + refers to one thing. However that can be a different one thing
in different namespaces.

@nalimilan
Copy link
Member

While this definitely makes sense, we may question whether supporting this syntax for defining methods is a good idea in practice. Requiring people to write +(a, b) = ... instead would reduce confusion.

@PallHaraldsson
Copy link
Contributor

What I meant with last comment (note no global +):

julia> a+b+c=2
Warning: Method definition +(Any,Any,Any) in module Base at operators.jl:82 overwritten in module Main at none:1.

  • (generic function with 125 methods)

julia> 1+2+3
2

Doesn't work the same as with (this would require global +):
julia> a+b=2

  • (generic function with 126 methods)

julia> 1+2
3

@quinnj
Copy link
Member

quinnj commented Oct 7, 2014

That's because with a+b+c=2, you're actually redefining a method in Base,
whereas there is no +(::Any,::Any) method in Base to redefine (you're
definition is the first in this case).

On Tue, Oct 7, 2014 at 5:46 AM, Páll Haraldsson notifications@github.com
wrote:

What I meant with last comment (note no global +):

julia> a+b+c=2
Warning: Method definition +(Any,Any,Any) in module Base at
operators.jl:82 overwritten in module Main at none:1.

  • (generic function with 125 methods)

julia> 1+2+3
2

Doesn't work the same as with (this would require global +):
julia> a+b=2

  • (generic function with 126 methods)

julia> 1+2
3


Reply to this email directly or view it on GitHub
#2032 (comment).

@quinnj
Copy link
Member

quinnj commented Oct 7, 2014

In  [15]: method_exists((+),(Any,Any,Any))

Out [15]: true

In  [16]: method_exists((+),(Any,Any))

Out [16]: false

@tkelman
Copy link
Contributor

tkelman commented Oct 7, 2014

@PallHaraldsson the warning is giving you a hint about what's happening. If you look at line 82 of base/operators.jl you'll see +(a,b,c) is defined (via a macro, along with similar 3-argument definitions for *, &, |, $, min, max, and kron) as +(+(a,b),c). There is not normally a predefined 2-argument + operator for inputs of type Any, but there is a predefined 3-argument + operator for inputs of type Any. The 3-argument definition for Any inputs falls back to the 2-argument definition, whether or not it exists.

I agree with @nalimilan that infix-syntax method definition for operators is perhaps more confusing than it is useful.

@garborg
Copy link
Contributor

garborg commented Oct 7, 2014

I didn't understand what is going on at first (infix-syntax method definition). I'm sure I'll remember now, but it doesn't look clear/clean to me quite yet, and it's one more data point, somehow, from someone who's used the language for a while, extended + before, defined other infix operators, etc.

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

9 participants