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

Should there be Infix Macros? #11608

Closed
oxinabox opened this issue Jun 7, 2015 · 22 comments
Closed

Should there be Infix Macros? #11608

oxinabox opened this issue Jun 7, 2015 · 22 comments

Comments

@oxinabox
Copy link
Contributor

oxinabox commented Jun 7, 2015

In #5571 (around here) it was discussed that if |> was defined by a macro, it could be (directly) enhanced by packages,
to give people the varios pipeline styles they desire (and perhaps eventually allow it to be deprecated then removed from core).
Now, pipelining isn't for everyone.

Similarly though, tilde is already an infix macro: see #4882
It may be only actually in use in Dataframes.jl -- defined here.
If you look at that defition, you can see it is a macro taking 2 arguments: lhs and rhs

We allow the redefining of a section of the unicode operator range as Infix functions -- that is functions of two arguements that can be written between the two arguements.

Not having ~ as a special case would be a good thing -- which means either generalising the mechanism, or removing it.

Should we have generally overloadable macro infix operators?


if so, what should the syntax be?

  • One possibly is @+ where the + is anything that is valid as Operator.
  • Another option for symetry would be @+@.
  • or the Haskellish: <backtick>+<backtick> (idk how to write backtic character in markdown, inside a code block)
  • Alternitively, macro operators and functional operators could be indistringuishable, and alway resolve to be Macro first, then if that is not defined/errors to fall back to a function. I think that is kinda gross.

An

@tkelman
Copy link
Contributor

tkelman commented Jun 7, 2015

Interesting question to raise. I agree with the sentiment that it would be good to get rid of the special-casing of ~. If infix macros are a good idea in general isn't so clear-cut, though we have found at least 2 use cases where they might be convenient. The question is whether they can ever be properly extensible the way generic functions can.

Macros don't do dispatch in the same way as functions, and usually with operators the most common usage is extending the base versions with new methods for new package/user types. You don't often see a package introducing and claiming an operator for Any... inputs.

@yuyichao
Copy link
Contributor

yuyichao commented Jun 7, 2015

In some sense another special case is . (i.e. getfield, which is the only one I personally want...)

@tkelman
Copy link
Contributor

tkelman commented Jun 7, 2015

getfield is a separate issue, #1974 - and it has little to do with macros.

@kmsquire
Copy link
Member

kmsquire commented Jun 9, 2015

Not much to add, just a +1 for "let's explore whether this is a good idea".

@oxinabox
Copy link
Contributor Author

Another potential use case:

a=[1,2,3,4]
a[1:end/2]

now throws a deprication warning so that you have to write:

a[1:round(Int,end/2)]

A infix macro overload of / (or what every symbol it is) could perhaps be used to special case the devision where the LHS was literally the keyword end

@yuyichao
Copy link
Contributor

OT. but for this case I would like a easier way to do integer division (if there isn't one now)...

@yuyichao
Copy link
Contributor

And I think div works and is simple enough

@oxinabox
Copy link
Contributor Author

div huh, Thanks.
I think that is better
that a special definition of / just for end/2

@yuyichao
Copy link
Contributor

And even better

julia> ÷
div (generic function with 31 methods)

@oxinabox
Copy link
Contributor Author

oxinabox commented Jun 11, 2015

Thanks.
my code is becoming clearer every moment

@IainNZ
Copy link
Member

IainNZ commented Jun 11, 2015

div is love, indeed.
Back on topic, I'm definitely interested in the idea of infix macros from a DSL perspective, but I'm worried they'll be too weird and magical. Macros can be weird and magical, but its obvious when they are performing their magic. Operators will presumably look like just normal operators. We could require R-style notations, like %>% which I think a lot of people like very much.

@ScottPJones
Copy link
Contributor

@IainNZ Would @>@ be more consistent, in Julia, for denoting an infix macro? Would %>% have any parsing issues?

@IainNZ
Copy link
Member

IainNZ commented Jun 11, 2015

It would be more consistent - I wasn't suggesting %>% for Julia, just that its an example from another language.

@johnmyleswhite
Copy link
Member

As someone who generally wishes you couldn't use macros without putting their arguments in parentheses, I'm pretty negative on the idea of infix macros. I think it would often be hard to read complex expressions involving infix macros. What would the following transform into?

x = 1.0
y = 0.0 @in@ x == 1.0 ? 1 @in@ 2 : 3 @in@ 4

@ScottPJones
Copy link
Contributor

@johnmyleswhite Cases like that are why I always use parenthesis, even with normal operators, even when not necessary in that particular language... (because otherwise, you can confuse yourself or other programmers when the precedence isn't the same... best to always be explicit...)

y = ((0.0 @in@ x) == 1.0) ? (1 @in@ 2) : (3 @in@ 4)

@johnmyleswhite
Copy link
Member

That's a good strategy, but then why not use @in(3, 4) instead of (3 @in@ 4). You'd get the additional benefit that you didn't add more functionality to Julia that people have to implement, maintain, test, learn to use, etc.

@ScottPJones
Copy link
Contributor

I'm not advocating in-fix macros, just that if they go in, I think the syntax should be @op@, that's all.
I also prefer using () for macros...

@kmsquire
Copy link
Member

That's a good strategy, but then why not use @in(3, 4) instead of (3 @in@ 4).

In this case, for the same reason we write x in y instead of (the equally valid) in(x, y): it's easier to parse (for English and most western speakers), because our language works that way. (The same thing generally holds for operators.)

(@johnmyleswhite, I hear your concern about adding things to the language that people have to maintain, etc.. Practically speaking, I'm not sure how well founded that concern is in this case, mainly because of how Julia works: someone interested enough in this would have to spend the time learning how the parser works, and adding the functionality in, and then it would have to go through a comment period, where it's usefulness would have to be clearly demonstrated. I suspect the first step in this is quite a ways off. But if someone were to try it, I'd like to at least see what it looked like.)

@hayd
Copy link
Member

hayd commented Jun 12, 2015

Doesn't the same precedent (I think that's what the complaint is?) argument apply without being macros / with current julia syntax, "what would does the following transform into?":

0.0 in 1 == 1.0 ? 2 in 2 : 3 in 4

@tkelman
Copy link
Contributor

tkelman commented Jun 12, 2015

I think we'd just have to have a precedence table for that, and if there were macro versions of operators then we'd probably have the macro versions follow the same precedence as the standard operators?

I'm more worried about the extensibility of these. Macros operate on untyped expressions. So is there no way for 2 packages to simultaneously have definitions for the same macro-operator that could be used together unambiguously in a single user code base? This is essentially the situation we're in with ~ right now AIUI, where if any other package were to define a @~ macro then it wouldn't be usable at the same time as DataFrames, MixedModels, etc. That's not great.

@jakebolewski
Copy link
Member

This issue is purely speculative and not really actionable. The only way forward here would be to develop an actual implementation. I think you will find that much harder to do in practice than it seems.

@oxinabox
Copy link
Contributor Author

It is actionable in the negative.
by removing the ~ macro.

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