Allow syntax like Int32(1:10)?

Depends on what you want to achieve. In most cases, I think you’d want to promote to Int64 if your literals don’t fit in 32 bits. LLVM would make it work even if the hardware only supports 32 bits.

Ideally, you’d also want to apply this recursively to any function that gets called. I’ve been meaning to implement that using CodeTransformation.jl, but I haven’t gotten around to it yet. Yes. I think GPU interfaces are already doing something similar.

My point is explicitly for broadcasting. The following are uncontroversial:

  1. If you don’t know the types of the inputs, don’t assume the output of broadcast is mutable
  2. If you know the inputs are immutable and don’t know the function, don’t assume the output output of broadcast is mutable

So the only case where this will actually arise is if a user knows both the function and the input, so literally types something like:

x = UInt32.(1:10)
x[1] = 1

So my point is that this is really bad style, and would propose the following rule:
3. Even if you know the function and the type, but the type is immutable, do not assume the output of broadcast is mutable in future versions of Julia

So in the minuscule chance that there is extant code out there, the user should really change it to

x = convert(Vector, UInt32.(1:10))
x[1] = 1

Instead of making major changes to the broadcast mechanism, could the user just state what they want explicitly? eg

UnitRange{Int32}(1, 10)
UnitRange{Int32}(1:10)
1 Like

It’s actually a very minor change, see https://github.com/JuliaLang/julia/blob/34d2b87b65b1643b1055b10aa5ea7d2bdbcf6cd2/base/broadcast.jl#L1028
That is, just add the following should do it:

broadcasted(::DefaultArrayStyle{1}, ::typeof(UInt32), r::UnitRange) = UInt32(first(r)):UInt32(last(r))

Now where is that documented? You can theoretically add that to the document, sure and that’s a breaking change which allows you to do this kind of changes in the future but unless it’s there already you can’t just throw in new ways you can break things after the fact to justify new breaking changes.

In practice, this rule just make broadcast useless since type plays a central rule in julia and you are just saying don’t assume anything you can observe about type from broadcast. (The last time (or one of the previous times) this come up, in comprehension, it causes a lot of breakage.)

No, that’s not the point. You are breaking user’s code, so it’s breaking. Also, this is the worst kind of (fixable) breaking change. It changes the output on the use site without throwing an error but the return value is generally more restricted than the input. In practice, this change will cause error to be raised at completely different places, potentially even in a different package from where the syntax is used, and the error message will offer absolutely zero help in tracking it down.

You are changing the definition of “minor” here. For all the cases I (and others) have talked about major/minor in this thread wrt the change, minor has nothing to do with the length of the code required. You can add a - to the output of rand() and I don’t think you’ll have a very easy time arguing it’s a minor change even though it’s a single line change with 1/102 number of characters. (Of course in this case the output range of rand() is hopefully documented so that’ll break the document, but I don’t think you can argue it’s a minor change even if the output range is left out of the document, and if anything it’ll not be because of the size of the change)

1 Like

Whether or not it counts as “breaking” you should still follow rule 3 in anticipation of Julia v2.0+

Oh, sure. Even more than that. Anything can break from 1.0 to 2.0 (but not from 2.0 to 2.1). If there’s a good reason I have no fundamental objection (and at least not from the breakingness) for broadcast of mutable array to return an immutable one, or change the syntax/meaning of the broadcast/dot-syntax altogether on 2.0.

I’ll repeat that I have no objection to making the change itself. But it’s a breaking change and should not be done before 2.0.

2 Likes

And if this is really so burdensome, one can always just do

julia> const RInt32 = UnitRange{Int32}
UnitRange{Int32}

julia> RInt32(1:10)
1:10

julia> typeof(ans)
UnitRange{Int32}
1 Like

Here’s the breadcrumb for where to do it, even:

Having big.(1:10) return a range but not BigInt.(1:10) is simply an oversight. Special care may be needed to ensure that we don’t change the values of the range (due to, e.g., overflow or floating point precision or some such). Starting with just support integer → integer conversions may be easiest.

1 Like

didn’t know this, this looks perfectly fine to me

For the most part, T(x) for some type T is equivalent to convert(T, x) i.e. it tries to convert x to be of type T.