Proposal: broadcast operator for primitive types

Hi!

I was coding something today, and I have a variable `V` which can be of many types (`Int`, `Float32`, `Float64`, and so on). However, I need to limit the value of this variable. What I did was:

``````V > +10 && (V = eltype(V)(+10))
V < -10 && (V = eltype(V)(-10))
``````

However I found this strange… So, I would like to propose the indrocution of broadcast operator for such primitive types, so that we can do:

``````V .= 10
``````

and V will not change type. Of course, if conversion is not possible, then an error will be thrown.

What do you think?

EDIT: I know we have the `sign` function that would do what I need, but I still think this will be nice to have.

I am confused, where does broadcasting happen here? `V` looks like a scalar.

Also, why the `eltype`? `V = oftype(V, 10)` would be simpler.

It is not “broadcast”, I do not know how to call it… but an operator that will keep the type of the variable on the left side if it is a scalar. Doesn’t make sense?

Yes, that will be much better than my previous approach.

I can see a use case for this (enforcing type stability in certain situations), but would not conflate it with broadcasting.

Possibly a macro that expands

``````@keeptype v = rhs
``````

to

``````v = oftype(v, rhs)
``````

could be useful. OTOH `oftype` is shorter and already exists.

1 Like

The problem IMHO is for bigger expressions, like:

``````v = oftype(v, theta + omega + alpha/2 + gamma - beta - 180)
``````

but a macro will be ok too

The suggestion of `.=` was to give the meaning that we are “modifying” the value of a variable but keeping the type.

Can’t you do this?

``````V::T = 10
``````

where `T` is the type you want.

This is a little pedantic, but Julia’s identifiers aren’t really “variables.” They’re just names. So the only way to “modify” the name is to completely re-purpose the same name to identify something different.

Using `.=` and thinking about “modifying” a variable leads your mental model down a path that points towards more confusion, I think.

What you can do is declare that this name will always identify something with a certain type with the `V::T = ...` syntax. You could do this as a macro, too, with a `@typeconst V = rhs` expanding to `V::typeof(rhs) = rhs`.

But to your actual original example: just use `clamp`

``````julia> V = 8.0
8.0

julia> clamp(V, -10, 10)
8.0

julia> V = 22.5
22.5

julia> clamp(V, -10, 10)
10.0
``````
9 Likes

I would need to compute `T`, which in that case I did not have. So there would be a `T = eltype(V)` somewhere.

Fair enough!

I really liked this idea I will try to put in a package.

Indeed! @mcabbott told me about this function in Slack. I did not know how I missed that. You have no idea how many times I needed to do such a thing living and learning!

Great function and I love the choice of verb…Very easy to remember!

1 Like