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

1.*[0] returns an Array{Int64,1}, not Array{Float64,1} #5246

Closed
dlfivefifty opened this issue Dec 28, 2013 · 25 comments
Closed

1.*[0] returns an Array{Int64,1}, not Array{Float64,1} #5246

dlfivefifty opened this issue Dec 28, 2013 · 25 comments

Comments

@dlfivefifty
Copy link
Contributor

For an array a, I'm using 1.*a to ensure that it is a Float64 or Complex{Float64}. This doesn't work with

a=[0]

I'm assuming this is a bug? Or is 1.*a bad form for converting?

@johnmyleswhite
Copy link
Member

Why would this be a bug? All of the values you've listed are Int's, not Float's.

@gitfoxi
Copy link
Contributor

gitfoxi commented Dec 28, 2013

I totally get this. 1. is 1.0 sometimes. but in this case, you're
saying 1 .* [0]. Got burned by this one today. Anyway, you can say
1.0*[0] or 1*[0.] or whatever.

On Fri, Dec 27, 2013 at 7:16 PM, John Myles White
notifications@git.luolix.topwrote:

Why would this be a bug? All of the values you've listed are Int's, not
Float's.


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

Michael

@dlfivefifty
Copy link
Contributor Author

Yes that’s right,

(1.)*[0]

also works. Thanks!

On 28 Dec 2013, at 2:19 pm, Michael Fox notifications@github.com wrote:

I totally get this. 1. is 1.0 sometimes. but in this case, you're
saying 1 .* [0]. Got burned by this one today. Anyway, you can say
1.0*[0] or 1*[0.] or whatever.

On Fri, Dec 27, 2013 at 7:16 PM, John Myles White
notifications@git.luolix.topwrote:

Why would this be a bug? All of the values you've listed are Int's, not
Float's.


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

  • Michael

    Reply to this email directly or view it on GitHub.

@vtjnash vtjnash closed this as completed Dec 28, 2013
@StefanKarpinski
Copy link
Sponsor Member

Did we already change the way 1.*x parses or did we just agree that it was a good idea. We either already changed it and this is just a case where the new way is also annoying or we didn't and this is further evidence that we should.

@vtjnash
Copy link
Sponsor Member

vtjnash commented Dec 28, 2013

I don't think we changed it, although I don't recall why, I thought it seemed more logical to make the switch. (Also, I think last time the discussion was about 1.^-1)

@StefanKarpinski
Copy link
Sponsor Member

Yeah, I think the general sentiment stands though, which is that switching would be better.

@dlfivefifty
Copy link
Contributor Author

I think switching is less confusing:

(1.)*a

is more common usage than

(1).*a

which I reckon most users would write as 1*a

On 28 Dec 2013, at 4:53 pm, Stefan Karpinski notifications@github.com wrote:

Yeah, I think the general sentiment stands though, which is that switching would be better.


Reply to this email directly or view it on GitHub.

@StefanKarpinski
Copy link
Sponsor Member

Yes, I agree with this.

@JeffBezanson
Copy link
Sponsor Member

I don't think one is obviously better than the other. The last time this
came up iirc, the confusion was that 2.*x unexpectedly introduced floating
point instead of multiplying by the integer 2, and we switched to what we
do now. "2." is marginal syntax for a number, and even more so without
spaces. I'd prefer not to keep flip-flopping on these small issues.
On Dec 28, 2013 1:22 AM, "dlfivefifty" notifications@github.com wrote:

I think switching is less confusing:

(1.)*a

is more common usage than

(1).*a

which I reckon most users would write as 1*a

On 28 Dec 2013, at 4:53 pm, Stefan Karpinski notifications@github.com
wrote:

Yeah, I think the general sentiment stands though, which is that
switching would be better.


Reply to this email directly or view it on GitHub.


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

@JeffBezanson
Copy link
Sponsor Member

Also things look different if you consider 2.<x. There the dot operator
is likely preferred.
On Dec 28, 2013 1:44 AM, "Jeff Bezanson" jeff.bezanson@gmail.com wrote:

I don't think one is obviously better than the other. The last time this
came up iirc, the confusion was that 2.*x unexpectedly introduced floating
point instead of multiplying by the integer 2, and we switched to what we
do now. "2." is marginal syntax for a number, and even more so without
spaces. I'd prefer not to keep flip-flopping on these small issues.
On Dec 28, 2013 1:22 AM, "dlfivefifty" notifications@github.com wrote:

I think switching is less confusing:

(1.)*a

is more common usage than

(1).*a

which I reckon most users would write as 1*a

On 28 Dec 2013, at 4:53 pm, Stefan Karpinski notifications@github.com
wrote:

Yeah, I think the general sentiment stands though, which is that
switching would be better.


Reply to this email directly or view it on GitHub.


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

@StefanKarpinski
Copy link
Sponsor Member

I couldn't remember if we'd switched or not. If we've already switched, then clearly we shouldn't change anything again.

@ivarne
Copy link
Sponsor Member

ivarne commented Dec 28, 2013

An ambiguity warning might be the right choice as we definitely have users who will be confused by both behaviors.

Something like this issued by the parser, but where we keep the current behaviour?

> 1.*[0]
Warning: Ambiguous .* operator. Add spacing to disambiguate "1. *" and "1 .*".
1-element Array{Int64,1}:
 0

@gitfoxi
Copy link
Contributor

gitfoxi commented Dec 28, 2013

Okay. Here's a fun one:

julia> type T
       (*)
       end

julia> t=T(1)
T(1)

julia> t.*
       ^C

julia> t.(*)
ERROR: type: getfield: expected Symbol, got Function

julia> dump(t)
T
  *: Int64 1

julia> getfield(t, *)
ERROR: type: getfield: expected Symbol, got Function

julia> getfield(t, :*)
1

julia> t.:*
ERROR: type: getfield: expected Symbol, got QuoteNode

julia> t.(:*)
1

Point being, there's too-few wingnuts on the keyboard.

You could ditch the 1. shorthand in favor of something else. But careful what that something else is. For example, it's as easy as saying f=1.0. Now you have 1f shorthand and there's no confusion about what 1f*[0] means.

It reminds me of this C++ library I occasionally have to deal with. Somewhere it defines every physical unit like #define mV *1e-3. Seems convenient. Now you can say voltage = 1mV;. But if you forget that hundreds of short 1, 2 and 3-character sequences have been used up this way then you'll try a loop like for(s=1;s<10;s++) and get a very strange error from the compiler which sees this as for(*1e0=1;*1e0<10;*1e0++).

@StefanKarpinski
Copy link
Sponsor Member

I wouldn't be so against requiring that . not be at the end of a numeric literal. We could deprecate it for a while first. If you just define mV = 1e-3 in Julia, then 1mV will work but 1 mV won't.

@dlfivefifty
Copy link
Contributor Author

I think 1. is very common across languages (Mathematica, Matlab, C, …) so I would argue against deprecating it to fix one confusing use case.

On 29 Dec 2013, at 4:22 am, Stefan Karpinski notifications@github.com wrote:

I wouldn't be so against requiring that . not be at the end of a numeric literal. We could deprecate it for a while first. If you just define mV = 1e-3 in Julia, then 1mV will work but 1 mV won't.


Reply to this email directly or view it on GitHub.

@ivarne
Copy link
Sponsor Member

ivarne commented Dec 29, 2013

A compromise would be to require that the character after . in a numeric literal must be whitespace or a number. Similarly the character before . in a broadcasting operator must be whitespace. Removing 1. syntax will not remove the ambiguity when users expect it to work.

@StefanKarpinski
Copy link
Sponsor Member

I'm pretty sure that 1. is not a valid numeric literal in Ruby at least.

@StefanKarpinski
Copy link
Sponsor Member

@ivarne – I like it. You're quit good at coming up with these subtle solutions.

@vtjnash
Copy link
Sponsor Member

vtjnash commented Dec 29, 2013

ivarne's solution sounds good to me also. However, I don't think the character before the . in broadcasting needs any special limitations. (1., 2.,), f(1.) and a[1.] are also unambiguous -- i think it would do better to use a blacklist of invalid combinations (!<number>.<operator>), rather than a whitelist of requirements (<number>.<number or whitespace or delimiter or ...>)

@wlbksy
Copy link
Contributor

wlbksy commented Dec 29, 2013

I like @ivarne 's idea. It's also a good practice to write 1.0 instead of 1. though we accept 1. as valid number

@ViralBShah
Copy link
Member

I was going to make the same suggestion, but this happened before I wrote up. :-)

I have never been a fan of writing 1. instead of 1.0.

@ivarne
Copy link
Sponsor Member

ivarne commented Dec 29, 2013

@vtjnash Good catches! I still think a whitelist is better than a blacklist, because it is easy to add entries to a whitelist, but it will break code in if you add entries to a blacklist.

My suggestion would be that a Float64 literal must have one of the following after the .: [:whitespace:] 0-9, ,, ], ).

As @gitfoxi says, there is problems with the . being both a separator and part of a set of operators. If we later add . as a operator that can be defined on any type (PyCall really wants this!), the confusion will be complete. Therefore it seems reasonable to require whitespace before the broadcasting operators.

Edit: Removed [ and ( from the suggested whitelist. They does not seem nececary, and @toivoh s comment suggests that they might be ambiguous with other functionality.

@toivoh
Copy link
Contributor

toivoh commented Dec 29, 2013

I once suggested to add a broadcasting index operator .. It's hard to be sure of
all things that would be allowed in a whitelist. (Not that a blacklist
makes it easier :) I think that a whitelist should be pretty conservative -
it can probably still cover most cases used in practice.

@ivarne
Copy link
Sponsor Member

ivarne commented Dec 29, 2013

The question is if all charactes allowable in a variable should be allowed. I do not think we should allow 1.pi to be shorthand for 1.0pi, but that is a stylistic opinion.

@dlfivefifty
Copy link
Contributor Author

I think it should be supported:

1.x + 2.x^2 + 3.x^3 + 4.x^4

looks a lot cleaner and easier to read to me than

1.0x + 2.0x^2 + 3.0x^3 + 4.0x^4

On 30 Dec 2013, at 8:05 am, Ivar Nesje notifications@github.com wrote:

The question is if all charactes allowable in a variable should be allowed. I do not think we should allow 1.pi to be shorthand for 1.0pi, but that is a stylistic opinion.


Reply to this email directly or view it on GitHub.

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

10 participants