JuliaLang / julia

The Julia Programming Language
https://julialang.org/
MIT License
45.43k stars 5.46k forks source link

Allow '?' in variable and function names #22025

Open nsmith5 opened 7 years ago

nsmith5 commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

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

StefanKarpinski commented 7 years ago

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

nsmith5 commented 7 years ago

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 commented 7 years ago

In other words: pleeeeeeeeeease :)

ararslan commented 7 years ago

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.

ExpandingMan commented 7 years ago

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 commented 7 years ago

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

StefanKarpinski commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

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

ararslan commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

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.

tecosaur commented 3 years ago

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:

ararslan commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

Is that correct?

It is not 😄

StefanKarpinski commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

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

tecosaur commented 3 years ago

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

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.

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 commented 2 years ago

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 commented 2 years ago

imo, this is probably not worth it.

tecosaur commented 1 year ago

closed as completed

Did something happen with this?

kapple19 commented 4 months ago

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.