# Comparing different types doesn't raise an error?!?!?

**URL:** <https://discourse.julialang.org/t/comparing-different-types-doesnt-raise-an-error/26868>\
**Category:** General Usage\
**Created:** [July 27, 2019, 2:07am UTC](https://discourse.julialang.org/t/comparing-different-types-doesnt-raise-an-error/26868 "2019-07-27T02:07:29Z")\
**Posts on this page:** 7\
**Page:** 2

<div class="post-metadata">

**Author:** ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)\
**Post date:** [July 27, 2019, 3:26pm UTC](https://discourse.julialang.org/t/comparing-different-types-doesnt-raise-an-error/26868/21 "2019-07-27T15:26:18Z")

</div>

> [@yuyichao](#):
>
> Calling method is not an assignment. I mean, where **is** the assignment ( `=` ) when you call a function?

Hows this?

```julia
function bar(a::Int16)
end

function foo()
    local b::Int16 = 35

    bar(35)
end

foo()

```

My (naive) view is that in the case of `local b::Int16 = 35` the compiler is interpreting my constant 35 as an Int16 value. However for `bar(35)` the compiler is saying NO the constant 35 is a Int64. Yes at their base these are two different operations, assignment vs method call. However how the constant 35 is interpreted in these two operations is different…which changes based on operation…

My naive again guess would be this happens because there **may** at some time in the future be another function bar which takes a numeric, in which case it wouldn’t know which one to use. Or maybe it’s just that it **could** happen so the compiler refuses to make guesses, even though at this point and time, there is no other option.

> [@yuyichao](#):
>
> you’ll always have a conversion and what you wanted is simply putting that on the function call, which makes absolutely no difference in this case.

You are correct, however by forcing me to make the conversion (or at least looking at the function definition) I can realize that the value will be used as an Int32. Which means the calling function should operate on an Int32…which trickles up the call stack.

Know (or at least being reminded) of the size of a primitive value at the bottom of the call stack can be useful when you are at the top of the call stack and can simplify (or complicate) your input validation, especially when taking the value from a user…but you can be reasonably confident the value won’t be rejected at the end of it’s journey.

I’m not sure if the CPU pipeline handle math operations on Int32 more efficiently than int64, but the CPU cache can handle more Int32s than it can Int64s. So if the value is going to be save or used as an Int16 or an Int32 why would I manipulate it an int64? Granted I probably shouldn’t be worrying about cpu cache size, but I’d prefer my code to be closer to right than wrong from a performance standpoint. So if the value can be treated as the same primitive type in it’s whole journey that would be the most efficient path, correct?

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [July 27, 2019, 3:43pm UTC](https://discourse.julialang.org/t/comparing-different-types-doesnt-raise-an-error/26868/22 "2019-07-27T15:43:56Z")

</div>

> [@pixel27](#):
>
> interpreting my constant 35 as an Int16 value

\*Converting.

> [@pixel27](#):
>
> However how the constant 35 is interpreted in these two operations is different

No. The operations done on the 35 are different. 35 is always interpreated as 35, an `Int`, in both cases. Only that one of them has an implicitly inserted conversion, as do all assignments and **only** on assignments.

> [@pixel27](#):
>
> You are correct, however by forcing me to make the conversion (or at least looking at the function definition) I can realize that the value will be used as an Int32. Which means the calling function should operate on an Int32…which trickles up the call stack.

Yes? By requiring the argument to be `Int32` it is by all mean forcing you to make the conversion. I still don’t see what you are complaining about. As I said, if this is the reason you choose to use `::Int32` on the argument then by all mean do it. You’ll be forced to do the conversion when you call the function exactly as you wished.

> [@pixel27](#):
>
> can simplify (or complicate) your input validation, especially when taking the value from a user…but you can be reasonably confident the value won’t be rejected at the end of it’s journey.

Err, so are you using the type information in your validation or not? If you are, then you are assuming the type already, if you aren’t then it’s not making any difference.

> [@pixel27](#):
>
> but the CPU cache can handle more Int32s than it can Int64s

Well, if you are talking **that** low level, then no, passing `Int32`/`Int64` around does not go through the memory/cache and that doesn’t make any difference.

Anyway, as I said, wanting to do operation on a known type is fine and the current behavior give you exact that. I’ll be slightly more concrete with an example. From your discription it seems that you have

```julia
struct A x::Int32 end
high_level(x, ...) = ... low_level(x) ...
low_level(a::A, x, ...) = ... a.x = x ...

```

Now, if you just want

> Know (or at least being reminded) of the size of a primitive value at the bottom of the call stack

then it’s there already, in the declaration of `A`. You don’t need anything else. You’ll also get the

> be reasonably confident the value won’t be rejected at the end of it’s journey.

that you wanted.

If you want to

> forcing me to make the conversion

when you call `low_level`. Then put `::Int32` on the `x` on `low_level`. You’ll be forced to do that since you’ll get an error otherwise. (Similarly, if you want to be forced for `high_level`, put the assersion there instead). By all mean, you cannot expect no value being reject in this case since that’s the whole point of “forcing you to”. If by forcing you to do something you don’t mean an error if you don’t then please advice what you mean by forcing.

If you don’t want a conversion anywhere for performance reasons, then put `Int32` on both functions and also make sure the input to `high_level` is correctly typed since this is the only way you can know for sure that no conversion on it is done within the code I show and this can propagate upward nicely as well so you can be confident that a good caller can arrange for no conversion if it’s possible. You’ll also be assured that whatever value accepted by your `high_level` won’t be rejected anywhere lower since it’s already of the right type.

Edit: And just to be more clear. I have no problem with the `as` syntax for automatic argument conversion. However, there’s no inconsistency in the current state and the usecase/concerns you’ve presented so far fits the current feature set perfectly well.

You also don’t need to explain why `Int32` is more efficient than `Int64`, it’s not really in basically all the cases above and it does matter when you store it in a field/array in which case you explicitly state the field type you want and you get an automatic conversion.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [July 27, 2019, 3:45pm UTC](https://discourse.julialang.org/t/comparing-different-types-doesnt-raise-an-error/26868/23 "2019-07-27T15:45:10Z")

</div>

> [@pixel27](#):
>
> My naive again guess would be this happens because there **may** at some time in the future be another function bar which takes a numeric, in which case it wouldn’t know which one to use. Or maybe it’s just that it **could** happen so the compiler refuses to make guesses, even though at this point and time, there is no other option.

And sort of yes for this. In any case, taking a guess is the best way to break any consistency you’ll ever hope to have. Since you want consistency, I assume you don’t want that.

---

<div class="post-metadata">

**Author:** ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)\
**Post date:** [July 27, 2019, 3:52pm UTC](https://discourse.julialang.org/t/comparing-different-types-doesnt-raise-an-error/26868/24 "2019-07-27T15:52:30Z")

</div>

> [@yuyichao](#):
>
> Consistency in exactness between comparison and conversion

Having dug more into this (because of this thread), I’ll have to agree.

> [@yuyichao](#):
>
> Comparing string to number.

I’ll probably just grumble about this to myself. I see the point, but I also feel that it helps hide issues. As @jonathanBieler mentioned === helps alleviate some of that, but it still (for me) _hides_ the bug. From a scripting language point of view it’s reasonable and there are times Julia feels more like scripting than programming, which I’m assuming is by design.

> [@yuyichao](#):
>
> Method calls requiring exact type matching

This I like, I also tend to like the “as” syntax for conversion, but that’s probably just from familiarity. My biggest grumble is that constants i.e. 0 doesn’t get converted to the correct type and for some reason I pass 0 around alot.

> [@yuyichao](#):
>
> Inefficiency from convertion.

This is really just causing me to declare all the parameter types on methods which is to be expected. If at the end of the day a value is going to be of type X, then I prefer that all operations on it during the day be with it as type X.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [July 27, 2019, 4:00pm UTC](https://discourse.julialang.org/t/comparing-different-types-doesnt-raise-an-error/26868/25 "2019-07-27T16:00:15Z")

</div>

> [@pixel27](#):
>
> Having dug more into this (because of this thread), I’ll have to agree.

Good =)

> [@pixel27](#):
>
> From a scripting language point of view it’s reasonable and there are times Julia feels more like scripting than programming, which I’m assuming is by design.

Yes. I won’t claim this is the only solution or the best one. It’s a good enough trade off so far.

> [@pixel27](#):
>
> This I like, I also tend to like the “as” syntax for conversion, but that’s probably just from familiarity. My biggest grumble is that constants i.e. 0 doesn’t get converted to the correct type and for some reason I pass 0 around alot.

An easier syntax for conversion could help (edit:) although in most cases just explicitly call the constructor will do. I’ve also hit my fair share of problem (although more on `Float32`) of constant having the wrong types. There are packages (macro) to change the type of constants in a block of code and if you compare to c++ I’d say the main thing we don’t do by default is typed varable (but we do allow it). The automatic conversion in C++ has just got me an ambiguity error at compile time yesterday and I’ve also got quite a few performance issues/compiler warnings when using the wrong literal types within an expression before assigning it to “fix the type” (actually I got one of this yesterday as well… make me wonder what did I do wrong yesterday…).

Edit: In any case, this (type of literal and maybe by extension, type of operation return value) is a deeper and more subtle topic that is much more complicated than what the title of this thread would suggest and is very context dependent so it is more likely solved via a varity of solutions. Find a coding style and using the package mentioned above are both valid (partial) solutions.

Edit2: Ah, finally find the package… [GitHub - JuliaMath/ChangePrecision.jl: macro to change the default floating-point precision in Julia code](https://github.com/stevengj/ChangePrecision.jl) …

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [July 27, 2019, 4:11pm UTC](https://discourse.julialang.org/t/comparing-different-types-doesnt-raise-an-error/26868/26 "2019-07-27T16:11:06Z")

</div>

Also, for giving literals a different behavior than normal values, see [Confusing difference: ^literal vs ^variable](https://discourse.julialang.org/t/confusing-difference-literal-vs-variable/13515) and all the linked discussions…

IMHO, it’s possible to implement. It could be useful sometimes. It breaks the insignificance of assignment to untyped variables in a benign looking case so I really don’t like it. Because of this properties, it has lead to quite a bit of confusions.

---

<div class="post-metadata">

**Author:** ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)\
**Post date:** [July 27, 2019, 4:13pm UTC](https://discourse.julialang.org/t/comparing-different-types-doesnt-raise-an-error/26868/27 "2019-07-27T16:13:21Z")

</div>

I do hope nobody took this personally. I do like Julia, and have been enjoying programming in it.

The number compared to a string issue was a coding on my part, that took me by surprise. It was in hard to reach code from a Juno standpoint: A Task in a chain of Tasks started by a GTK callback. So figuring out what was happening was tricky and I ended up having to put together a whole slew of code to setup the chain and push in dummy data so I could step through it.

[Previous page](https://discourse.julialang.org/t/comparing-different-types-doesnt-raise-an-error/26868.md?page=1)
