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

remove importall Base.Operators #8113

Closed
vtjnash opened this issue Aug 25, 2014 · 23 comments
Closed

remove importall Base.Operators #8113

vtjnash opened this issue Aug 25, 2014 · 23 comments
Labels
breaking This change will break code needs decision A decision on this change is needed

Comments

@vtjnash
Copy link
Member

vtjnash commented Aug 25, 2014

it's rather annoying that importall Base.Operators is the default. It came up recently on the mailing list, but also came up recently in my own work. The workaround (baremodule), requires a lot of boilerplate (and some like eval is rather mysterious). The need for workarounds also make it difficult to use the redefined function outside of the module (via export).

@vtjnash vtjnash changed the title importall Base.Operators remove importall Base.Operators Aug 25, 2014
@IainNZ
Copy link
Member

IainNZ commented Aug 25, 2014

I'd be OK with this. It feels like "magic", and thats often a bad sign

@rfourquet
Copy link
Member

On my first read of the docs (modules), I was bugged by the explanation: "since one typically wants to extend operators rather than creating entirely new definitions of them". It seems arbitrary, and doesn't help understand what makes them special (e.g. could I want entirely new definitions of length (or isless, convert, ...) more than of < ?). If the behavior doesn't change, the docs should help the beginner understand the rationale.

@tknopp
Copy link
Contributor

tknopp commented Aug 25, 2014

+1. When I read the mailing list post I also did not fine it very obvious.

@toivoh
Copy link
Contributor

toivoh commented Aug 25, 2014

+1

@StefanKarpinski
Copy link
Member

I agree that this doesn't feel great. But I also think that adding methods to imported functions feels odd in general. That was what I was trying to address with part of my interfaces proposal. Since I feel like something is wrong here in general, I'm reluctant to fiddle around with this too much until we have a story around this that just feels right.

@mlubin
Copy link
Member

mlubin commented Aug 27, 2014

I'd agree with @StefanKarpinski, both approaches are unintuitive in some sense. Switching between them without a real solution will cause a lot of churn.

@JeffBezanson
Copy link
Member

I've also always felt that this is a bit arbitrary, but I don't have the answer either. All I can say is that some names really are more canonical than others. Having your own + ought to be possible, but it's very unusual compared to something like Base.run vs. Git.run.
We shouldn't just mindlessly fiddle with this.

@vtjnash
Copy link
Member Author

vtjnash commented Aug 27, 2014

I opened this because I had the sense that it unusual because it is unnecessarily complicated, not that it is actually unusual. I would argue that wanting your own getindex or start method is far more unusual, and yet that doesn't have this hidden special case code.

@JeffBezanson
Copy link
Member

Base.Operators contains every function that has special syntax, which at least makes it somewhat easy to remember what is in there. Anything else really would be too complicated.

@vtjnash
Copy link
Member Author

vtjnash commented Aug 28, 2014

I agree that colon, hcat, vcat, getindex, setindex!, transpose, ctranspose correspond to special syntax. But this why didn't A_mul_Bt make the list then? Or ===? But looking at the list now, this is so completely arbitrary it is ridiculous. I would be content if it only contained operators that resolved to something other than their symbol (e.g. the list I just gave). But the current situation appears to be much worse than the description of "annoying" in my initial post.

julia> module X
       ===(a,b) = false
       end

julia> X.(:(===))(1,1)
false

@StefanKarpinski the following deserve's it's own Julep, but I'll try to outline this here to see if others think it is worthwhile:

I've previously mentioned / asked for with blocks, as the (only) feature from Visual Basic that was useful. But didn't think they would be worth the implementation effort to support. However, I think this would be an excellent usage case, replacing with with let . = x to avoid adding additional syntax. Consider:

module Me
let . = Base
    .+(a::MyType,b::MyType) = 1
    ..+(a::MyType,B::MyType) = 2
    global +(a,b) = .+(a,b)
    global .+(a,b) = ..+(a,b)
end

This requires a change to the parsing rules for ., which would be terribly problematic for a dot-oriented language, but relatively inconsequential for Julia: that of making Main.Base and Main .Base parse different.

Note, that this also makes it much easier to refer to qualified infix operators, because the dot parsing can be defined to be unambiguous.

@JeffBezanson
Copy link
Member

=== cannot have methods added so it doesn't really matter. The A_mul_B
things should be in there. I just don't like them. Are those the only
problems you see?
On Aug 27, 2014 8:08 PM, "Jameson Nash" notifications@github.com wrote:

I agree that colon, hcat, vcat, getindex, setindex!, transpose, ctranspose
correspond to special syntax. But this why didn't A_mul_Bt make the list
then? Or ===? But looking at the list now, this is so completely
arbitrary it is ridiculous. I would be content if it only contained
operators that resolved to something other than their symbol (e.g. the list
I just gave). But the current situation appears to be much worse than the
description of "annoying" in my initial post.

julia> module X
===(a,b) = false
end

julia> X.(:(===))(1,1)
false

@StefanKarpinski https://github.com/StefanKarpinski the following
deserve's it's own Julep, but I'll try to outline this here to see if
others think it is worthwhile:

I've previously mentioned / asked for with blocks, as the (only) feature
from Visual Basic that was useful. But didn't think they would be worth the
implementation effort to support. However, I think this would be an
excellent usage case. Consider:

module Melet . = Base
.+(a::MyType,b::MyType) = 1
..+(a::MyType,B::MyType) = 2end


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

@vtjnash
Copy link
Member Author

vtjnash commented Aug 28, 2014

=== can have methods added to it. const Base.(:(===)) = Base.is cannot (see example above)

also that it is missing any operator defined since v0.2

@JeffBezanson
Copy link
Member

But that's precisely why importing === is not useful. All it would do is
make any method definition of === an error.
Other than the A_mul_B things, I don't believe any operators are missing.
Of course the undefined unicode operators aren't there, since importing
undefined identifiers would just prevent any use of them.

@vtjnash
Copy link
Member Author

vtjnash commented Aug 28, 2014

Of course the undefined unicode operators aren't there, since importing
undefined identifiers would just prevent any use of them.

That sounds like a great argument, except that (a) that's not what julia does if you importall undefined operators (b) we have undefined operators in the list

@mikewl
Copy link
Contributor

mikewl commented Aug 28, 2014

Just as another argument for with:

@wbhart has the flint interpreter and there was an issue relating to his redefinition of +(::Int, ::Int)
I think with could possibly help with this?
Especially if it gets used by users. The with will allow for the redefined + to not affect the rest of the code.

Though I am quite new at using Julia, so there may be a way of only using redefined operators in specific sections of code I have not found yet!

@vtjnash
Copy link
Member Author

vtjnash commented Aug 28, 2014

If this issue is accepted, then it will be easy to redefine an operator within any module

@JeffBezanson
Copy link
Member

All operators are normal identifiers that can also be used as local
variables and argument names.

@JeffBezanson
Copy link
Member

I think we should do this. The compatibility story couldn't be easier: just add importall Base.Operators at the top of a module and it will work on 0.3 and 0.4.

@StefanKarpinski
Copy link
Member

Seems reasonable to me. The current situation means you can't actually define your own operators.

@toivoh
Copy link
Contributor

toivoh commented Jul 16, 2015 via email

@JeffBezanson
Copy link
Member

One possible exception: call. It's the only function you can add methods to without realizing it.

Either that or we need to adopt the proposal in #11452.

@StefanKarpinski
Copy link
Member

I'm still not sure but @vtjnash's proposal has something appealing about it. I have yet to come up with a really convincing argument that makes it a slam dunk for me though.

@JeffBezanson
Copy link
Member

The basic problem is that it extends our data model at a very low level, with an operation moduleof(x) that applies to all values and is used for dispatch. It's like a second typeof.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking This change will break code needs decision A decision on this change is needed
Projects
None yet
Development

No branches or pull requests

9 participants