Julia: syntax ambiguity with floating point constants and variable names

Created on 20 Jan 2019  路  17Comments  路  Source: JuliaLang/julia

Recently I came across the following piece of code:

    fm = ( f1 + 4f2 + f3) / 4

From the application context it was clear, that the meaning should be

    fm = (f1 + 4*f2 + f3) / 4

but the compiler understood (lexically correct)

    fm = (f1 + Float32(400) + f3) / 4

which led to a not easy-to-find numerical bug. I would like to propose to issue a compiler warning to make the ambiguity more visible to the user.
Alternatives:

  1. when a real constant of the form r".+[ef][[:digit:]]+" is found (recommend +/- after [ef])
  2. when a variable name of the form r"[ef][[:digit:]+" comes into scope
  3. when a constant of the form in 1. is defined while a variable name of form 2. is in scope

Most helpful comment

That's exactly what's useless about it. The warning give you no choice. You have to give up using the syntax if you get the warning and it kicks in even when the syntax is used correctly, penalizing correct usage. That's why if it's just a warning it must be opt in and in which case it doesn't need to be in the language and can be in lint instead.

All 17 comments

Unless we are going to deprecate any of the syntax involved here the warning is only going to be annoy. There's no practical way to make the warning go away without avoiding using one of the features so if we have the feature it essentially deprecate the feature it's warning about.

FWIW, I think this is the job of the editor (it should highlight numerical literals differently) and this kind of warning for perfectly valid syntax should also generally go to Lint.jl.

Unless we are going to deprecate any of the syntax involved here the warning is only going to be annoy...

In this case I propose, not to issue a warning, but a deprecation or error in one of the alternatives.

For me, I've been working around this problem by just not using juxtapose multiplication syntax. I have no issue deprecating this syntax since it doesn't really save a lot of typing (less than the fp literals). However, it cannot be done before 2.0 and I doubt everyone else is fine with that...

it doesn't really save a lot of typing (less than the fp literals).

I think, it just looks better!

julia> 1/2蟺
0.15915494309189535
julia> 1/(2*蟺)
0.15915494309189535
julia> 1/2/蟺
0.15915494309189535

It's just personal taste and it has caused confusion due to its difference from normal multiplication.

I've been working around this problem by just not using juxtapose multiplication syntax.

The proposal is not to ban either feature, but to give a bump to the user in case of ambiguity,

That's exactly what's useless about it. The warning give you no choice. You have to give up using the syntax if you get the warning and it kicks in even when the syntax is used correctly, penalizing correct usage. That's why if it's just a warning it must be opt in and in which case it doesn't need to be in the language and can be in lint instead.

I don't understand the argument. It would have avoided the unwanted interpretation of 4f2, if there had been an error message like

ERROR:syntax variable name f2 is illegal because it can collide with Float32 constants"

Sure, in your case it's fine, but it'll also happen if the user geneully want the fp literal. Basically in the best case the user may not be able to write many fp literals if he has variables like f2 and e4.

He would not be able to define variable names like f2or e4; he would be forced to switch to other names, if alternative 2 would be implemented.

Well, sure. And that's exactly what I mean by,

penalizing correct usage.

In general, this kind of sensitivity to variable names are just bad.

More over it's impossible to determine if variables are in scope at parse time. Even for local variables, this is only known at lowering time and by then the code has already been through macro expansion.

But it would be a lexer rule like: "A variable name starts with a letter or a underscore character, followed by a sequence of letters, digits, or underscore characters. If the starting character is "e" or "f", it must not be followed by a sequence of digits alone."
It would not be necessary to know, when a variable is in scope, and the meaning of the code would not depend on the existence of variables like "e4" or "f23", such variable names were simple impossible.

  1. I covered that already:

    In general, this kind of sensitivity to variable names are just bad.

  2. It's still just penalizing valid use. I've been trying to not say this but since it doesn't seem very clear I'll,

    Please note that there are many other users of the language, don't assume what you don't need isn't necessary. E.g. don't assume everyone wants 2f2 to mean 2 * f2 and don't assume that variable names like e4 are not needed (you use f1, f2, f3 as variable names, after all). I'm only suggesting removing juxtapose syntax since objectively it's the reason we have this sensitivity to variable names and people liking the 1/2pi syntax is exactly why I said I doubt this would be popular.

    Again, I acknowledge the problem, I've thought about it myself a long time ago which is why I can immediately give you these options (edit:) along with my personal resolution of it. However, without removing the reason of the ambiguity (juxtapose syntax (edit: or fp and hex literals FWIW, but I don't think that's an option)) adding a warning or error is just going to favor one usage versus the other and I don't think you can claim your usecase is the single most important one. If anything, there are more alternatives to the juxtapose syntax than fp literals so if there is going to be a trade off it should be favoring the fp literals, which is exactly how the syntax is currently parsed as.

So that means, you think the juxtaposing multiplication syntax is bad in general and should be removed.
That is not my opinion, I welcomed it as an improvement of readability.
I just wanted to point to the ambiguity issue, which should be mitigated by some means, which is not as radical as abandoning or ignoring the juxtaposing mult feature.

you think the juxtaposing multiplication syntax is bad in general and should be removed

No. I think it's the reason for the ambiguity and removing it is one way to fix this.

I just wanted to point to the ambiguity issue, which should be mitigated by some means, which is not as radical as abandoning or ignoring the juxtaposing mult feature.

This ambiguity is well known and I have absolutely no objection to help users with it. However, adding more variable name sensitivity or ambiguity warnings without easy fix in all cases isn't acceptable by default. Like I've said many times now, any of the checks you propose can go to Lint.jl, just not here.

Ok, you convinced me to stop the argument here.

Realistically, we are not going to disallow variable names like f2 or e4. Doing so would violate 1.0 compatibility promises and is just not a good idea. The only real option is to consider removing juxtaposition in 2.0 entirely.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

StefanKarpinski picture StefanKarpinski  路  3Comments

wilburtownsend picture wilburtownsend  路  3Comments

m-j-w picture m-j-w  路  3Comments

TotalVerb picture TotalVerb  路  3Comments

i-apellaniz picture i-apellaniz  路  3Comments