Detecting integer overflow


#21

NB: value classes mostly avoid boxing, although not reliably. So they’re pretty efficient, but require a little bit of care. I strongly recommend reading the value-classes link that @shawjef3 provided for the full details.

Opaque types (coming in Scala 3, maybe a bit sooner) will have stronger efficiency guarantees, but that’s a little ways off yet.

A non-obvious detail: Scala allows you to use arbitrary Unicode for function names, and infix notation is automatically available for any single-parameter method. So operators look just like ordinary functions, eg:

class MyType {
  def +!(other: MyType): MyType = { ... }
}

val a: MyType = ...
val b: MyType = ...
val c = a +! b  // Means the same thing as a.+!(b)

No imports or anything involved.

(The implicit class stuff allows you to add a function like this to an existing type such as String, which may be needed for your use case, but if you want to add a symbolic operator to a class you own, you don’t need any of that.)


#22

When defining custom operators it’s important to place extra characters after basic operator symbol, not before. See: https://docs.scala-lang.org/tour/operators.html

Precedence
When an expression uses multiple operators, the operators are evaluated based on the priority of the first character


#23

Oh, another useful distinction: it isn’t quite that Java doesn’t do it, it’s that the JVM doesn’t do it. Java is a programming language; the Java Virtual Machine (JVM) is the pseudo-machine on which both Java and Scala (as well as a lot of other languages) run.

So the JVM is effectively the “CPU” for this purpose, sitting between the code and the actual CPU, and its libraries are the available primitives.


#24

@jducoeur, are you suggesting that even if a single quotient/remainder operator is not available in the Java programming language, but were available at the JVM level, the Scala could make this available to the programmer as a single instruction returning a tuple?


#25

Yes, but the compiler would have to support it, it can not be done from library code. The JVM actually supports instructions that Java doesn’t use, but IIRC these were mostly for supporting dynamically typed languages.


#26

More or less. Really, what I’m saying is that the Java language is irrelevant – the JVM is essentially the “machine”, and the libraries you import basically target that machine; which language those libraries are written in mostly doesn’t matter. That’s the intuition I’m trying to get across here: while they’re called the “Java Virtual Machine” and “Java Standard Runtime library”, they’re mostly language-neutral: effectively a pseudo-CPU and pseudo-OS that happen to be somewhat optimized for Java, but which any language can use pretty equally.

But as @crater2150 says, if the JVM provided that operation and the Java Standard Runtime libraries did not expose it, that would be more challenging to use from Scala application code without compiler support – it’s like a CPU operation that isn’t exposed by the language, so it’s hard to use from application code without some sort of “assembly language” glue.

And unfortunately, since Java doesn’t have a native concept of tuples, I don’t think it occurred to anybody to provide this functionality in the first place – while the JVM isn’t limited to Java, it is highly influenced by that language…


#27

Doing integer division and modulo in one step is going to be expensive if it involves an extra object creation or method call. It would be cheaper to just do them separately.

The only way to access this functionality efficiently would be to simply write:

val quotient = a / b

val remainder = a % b

and have a compiler smart enough to understand that the above can be optimized accordingly.

So, you are looking for a compiler feature, not a language feature, and operators lie /% will not help you.