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

exploiting colon for custom infix operators #6946

Closed
stevengj opened this issue May 23, 2014 · 17 comments
Closed

exploiting colon for custom infix operators #6946

stevengj opened this issue May 23, 2014 · 17 comments
Labels
julep Julia Enhancement Proposal

Comments

@stevengj
Copy link
Member

Glen O made a very interesting proposal on the mailing list: if we simply add definitions

colon{T<:Real}(x::T,y::Function,z::T)=y(x,z)
colon{A<:Real,C<:Real}(x::A,y::Function,z::C)=y(x,z)
colon(x,y::Function,z)=y(x,z)

then any function can be used as an infix operator simply by surrounding it with colons. e.g. 17 :mod: 5 works (and gives 2).

Possibly modulo some minor cleanups (:+: and :-: appear to be parsed specially, and it's not clear if we want to keep this behavior which is apparently(?) undocumented), this would give a very clean way to define arbitrary infix operators (see also #4498, #2703, and #552), similar in spirit to Haskell's 17 mod 5 but without any parser changes.

cc: @StefanKarpinski, @JeffBezanson

@mbauman
Copy link
Member

mbauman commented May 23, 2014

I think this is very clever. I'd really like to have this ability, too, but the fact that it defines a fourth meaning for : gives me pause

@catawbasam
Copy link
Contributor

@stevengj
Copy link
Member Author

I don't think there is likely to be confusion with the use of colon for ranges x:s:y (or for types :: or conditionals ... ? ... : ..., as the three usages look quite different. Probably most people will put spaces in the operator usage (i.e. x :F: y).

I don't see much potential for conflict: it is not really reasonable to have an x:F:y range where F is a function. (You could try to make the step size some arbitrary function of coordinate, I suppose, but then you couldn't have AbstractArray-like random access, so it couldn't really behave like a Range.)

@JeffBezanson
Copy link
Member

I don't think this is such a good idea. Something as primitive as a
function call should not have to go through another particular function. It
becomes subject to inlining heuristics, depends on the scope of the colon
operator, and is limited by our unresolved issues with higher order
functions. |> has the same problems of course, but at least is less
abusive than this.

The Datetime package actually makes use of colons with a function argument
to construct certain date ranges.

@JeffBezanson
Copy link
Member

Another way to look at this is that given an expression a:b:c, you can't
say what it means. If one day b is a function, you get some random
behavior instead of an error. a |> b doesn't have this problem as much,
since a function can be seen as something you can send a value to.
On May 23, 2014 11:53 PM, "Jeff Bezanson" jeff.bezanson@gmail.com wrote:

I don't think this is such a good idea. Something as primitive as a
function call should not have to go through another particular function. It
becomes subject to inlining heuristics, depends on the scope of the colon
operator, and is limited by our unresolved issues with higher order
functions. |> has the same problems of course, but at least is less
abusive than this.

The Datetime package actually makes use of colons with a function argument
to construct certain date ranges.

@toivoh
Copy link
Contributor

toivoh commented May 24, 2014

Having once myself suggested [x op y] for this kind of thing I also think
that x :op: y would be too overloaded. My favorite out of these kinds of
suggestions is still (x op y), but I'm not sure if it's a good idea.

@Keno
Copy link
Member

Keno commented May 24, 2014

Maybe a unicode character could fill in for colon there?
E.g.:

a ‖b‖ c

if we make it \| in the repl and all editors with the fancy new unicode substitution support I think it could work quite well.

@toivoh
Copy link
Contributor

toivoh commented May 24, 2014

Yes, that could be a possibility. But I'm not sure about

‖, it looks to me like we are taking the norm of the operator b.

On Sat, May 24, 2014 at 10:38 AM, Keno Fischer notifications@github.comwrote:

Maybe a unicode character could fill in for colon there?
E.g.:

a ‖b‖ c

if we make it | in the repl and all editors with the fancy new unicode
substitution support I think it could work quite well.


Reply to this email directly or view it on GitHubhttps://github.com//issues/6946#issuecomment-44081472
.

@Keno
Copy link
Member

Keno commented May 24, 2014

Yeah, I noticed that too, but another character.

@stevengj
Copy link
Member Author

Inlining etc. could be fixed by eventually implementing special handling for colon. The overloading issue is a matter of taste, but I can see why some might not like it.

@Keno
Copy link
Member

Keno commented May 24, 2014

Maybe a ⋮b⋮ c. Looks almost like :.

@nalimilan
Copy link
Member

Any character other than : would be better to avoid confusion (FWIW, R uses %). The fact that colon can easily be used for infix operators doesn't mean it's a good idea. I guess the parser could be changed to support another character if this feature is really needed.

@shashi
Copy link
Contributor

shashi commented May 24, 2014

My two cents FWIW. |> Makes a lot of sense when there is automatic currying. Haskell and Elm people love it as it lets them do things like circle 10 |> move 0 0 |> animate "scale" "ease" instead of the clearly less readable (animate "scale" "ease" (move 0 0 (circle 10))), This may not be of so much value for the confusion/complexity it entails in Julia. It would only be useful on functions of arity 1 if I'm not mistaken.

If at all infixed functions are a go, I'd like to recommend back ticks.

a `plus` b
a `above` b
a `and` b

: is ambiguous with Range construction, 0:0.001:1, and I'd be shocked to find out I can put a function in place of 0.001. Back ticks is also the convention in Haskell.

Edit: Oh, I missed the part about doing this without parser changes.

@stevengj
Copy link
Member Author

It's not so much that parser changes are particularly hard as that they are potentially very disruptive. The fact that colon-based infixing can be done with 3 lines of user-level code is an indication that the change will have little impact on the rest of Julia.

(You might eventually want parser changes even for colon infixing for the reasons Jeff mentioned, but these will mainly be optimizations.)

@shashi
Copy link
Contributor

shashi commented May 24, 2014

As for colon, I think it's better to let this remain possible, as it is, than to make a documented base feature out of it just because it is possible.

@StefanKarpinski
Copy link
Member

Clever as it is, syntax punning with the colon/range construction is a bad idea. We've very carefully kept the meanings of each generic function quite consistent so far. Let's not squander that.

@stevengj
Copy link
Member Author

Okay, it seems like the consensus is against this; good to air the discussion, though.

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

No branches or pull requests

9 participants