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 :slight_smile:

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 :slight_smile:

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 :slight_smile: 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 :smile: living and learning!

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

1 Like