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

Allow '?' in variable and function names #22025

Open
nsmith5 opened this issue May 22, 2017 · 35 comments
Open

Allow '?' in variable and function names #22025

nsmith5 opened this issue May 22, 2017 · 35 comments
Labels
design Design of APIs or of the language itself kind:speculative Whether the change will be implemented is speculative parser Language parsing and surface syntax

Comments

@nsmith5
Copy link
Contributor

nsmith5 commented May 22, 2017

Currently Julia does not support question marks inside of variable names. This was discussed a while ago , with support, but never pursued (#1539). The major implication of allowing this is that you can write predicate functions with a question mark. (eg. integer?(x) instead of isinteger(x)).

A little more discussion can be found on discourse. I wish I could accompany this with an RFC-like pull request, but I got quite lost in the parser in my attempt.

If this is pursued I really think trailing question marks should be pursued as the convention for predicates. They indicate very clearly that the function asks a question and, as previously discussed, the is- predicates can be awkward, leading to inconsistent usage (eg. contains).

@StefanKarpinski
Copy link
Sponsor Member

I would also really prefer writing predicates as property? but at this point this would be a very nasty deprecation since it would require putting spaces in all uses of the ternary operator.

@ExpandingMan
Copy link
Contributor

ExpandingMan commented May 22, 2017

Perhaps I'm extrapolating too much, but wouldn't the use of ? in a ternary operator without spaces be extremely rare? It seems like bad practice to do this as it is rather difficult to read, and it would certainly seem reasonable to disallow it.

@nsmith5
Copy link
Contributor Author

nsmith5 commented May 22, 2017

Yeah, its unfortunate this wasn't tackled earlier, but if it doesn't happen pre-1.0 will it ever? I think the change is warranted. If someone changes the parser, I'd be happy to hunt through Base finding the offending statements. Obviously the deprecation issues for package managers is there, but as @ExpandingMan suggested, I wonder how often the space-less ternary operator was really used in the wild.

@quinnj
Copy link
Member

quinnj commented May 22, 2017

I'd be in favor of requiring spaces around ?; I agree it only leads to more readable code and would definitely be something enforced in a juliafmt tool eventually.

@StefanKarpinski
Copy link
Sponsor Member

There's a surprisingly large number of instances of ternary operators without space after the ? in Base Julia, so this would certainly not be undisruptive.

@nsmith5
Copy link
Contributor Author

nsmith5 commented May 22, 2017

I suppose the larger, and much more serious deprecation would be renaming of the predicates in the standard library should it be decided that following the property? convention is worth pursuing...

@ExpandingMan
Copy link
Contributor

One observation is that ternary ?, : constructs without spaces seems like a fundamentally different thing than, for instance + and - without spaces due to the presence of the :. Because of the role of : in Julia, leaving no spaces for it seems bonkers (and would, I hope, result in syntax errors). Therefore it seems a bit inconsistent to allow ? without spaces.

@StefanKarpinski
Copy link
Sponsor Member

StefanKarpinski commented May 22, 2017

Right, that's the other thing about this – it's a multistep deprecation:

  1. Version N+1: deprecate ? : without spaces.
  2. Version N+2: make ? : without spaces an error.
  3. Version N+2: deprecate isfoo in favor of foo?.
  4. Version N+3: profit.

I'm not sure that much underpants collecting is worth it.

@ExpandingMan
Copy link
Contributor

Ugh, when you put it that way, it sounds pretty painful...

@StefanKarpinski
Copy link
Sponsor Member

I know... not breaking people's code is a total drag 😬

@nsmith5
Copy link
Contributor Author

nsmith5 commented May 22, 2017

Ok, so the question is: is it worth it? I still think that it is and as mentioned by @quinnj the deprecation of ? : seems justified on readability grounds if not for a change in predicate convention.

@nsmith5
Copy link
Contributor Author

nsmith5 commented May 22, 2017

In other words: pleeeeeeeeeease :)

@ararslan
Copy link
Member

Ok, so the question is: is it worth it?

Probably not.

FWIW I actually like that we use is for predicate functions, as it jives with the fact that nearly all function names are full words (or combinations thereof).

Regarding ?, the stats/data devs have our eyes set on postfix ? for T? == Union{T, Null}. But still, the massive code churn almost makes it a non-starter.

@ararslan ararslan added design Design of APIs or of the language itself kind:speculative Whether the change will be implemented is speculative labels May 23, 2017
@ExpandingMan
Copy link
Contributor

It sounds like movement should be made toward deprecating ternary operators without spaces, regardless of whether ? winds up being used for predicates, postfix, or whatever else.

@ararslan
Copy link
Member

I'd tend to think that should be something that a linter/formatter should catch rather than the language itself.

@StefanKarpinski
Copy link
Sponsor Member

True, if we get widespread adoption of a standard formatting tool then this kind of change becomes much smoother since we can just tell people to run the formatter on their code before upgrading. I think I agree that deprecating ternary without spaces is a good idea regardless, but if we don't end up claiming that syntax, then disallowing it for no reason is just a bit weird.

@ZacLN
Copy link
Contributor

ZacLN commented May 23, 2017

This is already implemented for the julia-vscode plugin (on master) using CSTParser.jl, the auto formatting adds whitespace on ternary (and other appropriate) operators

@andyferris
Copy link
Member

Stefan - we've combined steps 2 and 3 in the past, no? That would be v0.7 (step 1) and v1.0 (steps 2+3).

But yes, this needs to compete with nullables (prefix unary ?T might be a mutually compatible option for nullables). Predicate f? looks nice in the femtolisp code... hard to say what is best, but definitely "last chance" territory.

@StefanKarpinski
Copy link
Sponsor Member

Yes, that's why they're in the same version (N+2).

@ararslan
Copy link
Member

I think at this point it doesn't make sense to introduce ? for predicates. The current style of using is* and other prose is well-established, so introducing another competing style is just asking for inconsistency and confusion.

@StefanKarpinski
Copy link
Sponsor Member

StefanKarpinski commented May 23, 2017

We could deprecate identifiers followed by ? without an intervening space in 0.7 and then make it an error in 1.0 (which will follow 0.7 immediately). That would allow us to use the syntax for something in the future without being too long a process now. We would possibly also want to deprecate and then disallow not surrounding the : in a ternary operator with spaces, although that's really an orthogonal issue.

@mkborregaard
Copy link
Contributor

I also would like to raise the point that ? parses intuitively as an operator, to my eyes and possibly other's. It would be the only operator allowed in names, and there is already an easy, succinct and intuitive syntax for this (is...). Finally, there would be an unintuitive pattern where postpending ? means a question, but postpending ! (which I have learned to like) does not mean answer - it means something completely different, that the function modifies at least one of its arguments.

@JeffBezanson JeffBezanson added kind:breaking This change will break code parser Language parsing and surface syntax labels May 31, 2017
@tecosaur
Copy link
Contributor

tecosaur commented Jun 22, 2021

This issue seems in limbo, but just to chime in with my 2c: I think allowing ? to be used in identifiers would be a significant improvement — it allows for much more intelligible naming. Leaving the matter of overhauling core isX functions to use X?, I think it's really nice if this were just possible to be used in peoples' own code. While it may be common in other languages, relegating the character ? to solely be a ternary operator feels like a waste to me.

To summarise, I think allowing ? in identifiers is good because it's:

  • helpful for succinctly conveying information about the nature of a function/variable (better than isX IMO)
  • consistent with allowing !
  • more grammatically flexible than isX et. al.

@ararslan
Copy link
Member

ararslan commented Jun 22, 2021

Tbh I've come around on this a bit. It is worth noting that omitting spaces in ternaries has been deprecated required (quite a while ago, actually—IIRC I did the deprecation during the JuliaCon 2017 hackathon) and that the ecosystem has been getting by thus far without a ? shorthand for Unions, be it a union with Missing or with Nothing, both of which have been pined after. Changing this would still be a massive churn, since presumably we'd want to do more predicates than just those currently prefixed with is, e.g. startswith. Would have to be a 2.0 deprecation and 3.0 hard change, IIUC.

¯\_(ツ)_/¯

@tecosaur
Copy link
Contributor

Given that space in ternaries is now required (I see a syntax error with true? 1 : 2), and I'm not aware of any other current uses of ? (do let me know if I've missed something), would anything break today if suddenly one could use ? in identifiers?

@andyferris
Copy link
Member

andyferris commented Jun 22, 2021

Would have to be a 2.0 deprecation and 3.0 hard change, IIUC.

Is that correct?

IIUC allowing ? in identifiers could be a 1.x change. Code written for Julia 1.8 code does not have to work in Julia 1.7, for example, just the other way around. With the mandatory space for the ternary it's non-breaking.

Adding aliases for predicates like const equal? = isequal could similarly happen in 1.x. I saw it claimed (please let me know if I'm mistaken) that deprecations are no longer a major end-user or performance concern, so the old versions like isequal could then be deprecated in 1.y. And safely removed in 2.0 (as we can have the nice property code that works in 1.y without depwarns is still working in 2.0. We needn't require that all code that works in 1.y, particularly code evoking deprecation warnings, also works in 2.0).

@ararslan
Copy link
Member

Is that correct?

It is not 😄

@ararslan ararslan removed the kind:breaking This change will break code label Jun 24, 2021
@StefanKarpinski
Copy link
Sponsor Member

The plan for ? was to allow T? as a syntax for Union{T, Missing} and f? as a syntax for lifting f to propagate missings. Not sure if we're still going to do that, but that was the intention in reserving this.

@tecosaur
Copy link
Contributor

If a shorthand for Union{T, Missing} is still wanted, are there any alternatives that may be acceptable? e.g. ?T, T:?, T.?. For the above reasons, it would be very nice if ? could be used in identifiers, and a shorthand syntax also worked out (later?).

@StefanKarpinski
Copy link
Sponsor Member

Allowing it in identifiers feels a bit wasteful to me. We already have the isblah convention which works well.

@tecosaur
Copy link
Contributor

tecosaur commented Jun 24, 2021

As I understand it, there are two competing desires here:

  • it would be cool to be able to use ? in identifiers
  • it would be cool to be able to Union{T, Missing} types more efficiently, with T?

The alternatives which I suggested above were ... clunky. With the exception of ?T which would interfere with the help mode.
A thought has just occurred to me though, which I think may work quite nicely:

How about ~T? With the logic being that a not-value is a missing value (which I see as pretty consistent with the current meaning). This works in Julia as-is without consuming any additional identifiers or conflicting with existing usage (AFAICT)

julia> ~(T::Type) = Union{T, Missing};

julia> ~String
Union{Missing, String}

Perhaps this isn't quite as nice as T?, but it's an efficient syntax that makes some sense.

Regarding allowing ? in identifiers being wasteful, I must strongly disagree — I think they provide a lot of value.

We already have the isblah convention which works well.

It works, I'm not so sure about well.

  • At a glance it's less obvious that isblah is a predicate compared to blah?.
    • ? works really well at getting me in that predicate mood 😛
    • it's even more obvious if you do isblah?
  • What about the predicates that don't start with is? E.g. occursin, I know I'd rather occursin? to isoccursin. Also see all, any, startswith, endswith, and contains for some other examples of non-is/has prefixed predicates.
  • I consider ? superior for clarity of intent when trying to indicate which kind of function one is working with
  • Using ? can also work better grammatically: as blah? can serve as doesblah, hasblah, and isblah. Meanwhile, writing doesblah or hasblah as isblah for predicate consistency is grammatically clunky. As an English speaker (and I imagine the same would apply to many other languages) good?(...) feels much more sensible than isgood(...). isgood(...) is a question without the question mark ... it just doesn't read as well. The same applies with compound forms like !isnothing which I read as "not is nothing", I find !nothing? (read as: "not nothing?") similarly preferable. A small difference that adds up in a lot of places.
  • An example from a vote counting package I recently started working on:
    • Some current predicate functions: ismonotonic, hascondorcetwinner (arguably should be satisfiescondorcetwinner), iscondorcet, hasmajority (really should be doesmajoritywin or ismajoritythewinner), etc.
    • using ?-style: monotonic?, condorcetwinner?, condorcet?, majoritywin?, etc.
    • I think this is a pretty major improvement

Even if there's little interest in changing the base functions, I'd think it would be worth at least allowing a Julia user to write identifiers with ? in their own code when they feel like it's appropriate.

@tecosaur
Copy link
Contributor

I imagine that any changes with this won't be happening soon, but @StefanKarpinski @ararslan might you have any thoughts on my comments above?

@oscardssmith
Copy link
Member

imo, this is probably not worth it.

@nsmith5 nsmith5 closed this as completed Sep 20, 2022
@tecosaur
Copy link
Contributor

closed as completed

Did something happen with this?

@KristofferC KristofferC reopened this Sep 20, 2022
@kapple19
Copy link

kapple19 commented Apr 26, 2024

My experience for any language in avoiding double-naming things (apparently among the hardest things in programming?) also points toward wanting x? in function names that return a Bool, and leaving x for storing the Bool value.

And the consistency with y! notation just makes so much sense to me.

And as a silly sidenote, when reading a function named e.g. sorted? my mental voice naturally inflects upward and has a sense of questioning - that "predicate mood" that @tecosaur mentions haha. After which, reading a variable named e.g. issorted naturally prompts a downward inflection and has a sense of resolution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
design Design of APIs or of the language itself kind:speculative Whether the change will be implemented is speculative parser Language parsing and surface syntax
Projects
None yet
Development

No branches or pull requests