What "<%" means?

106 views
Skip to first unread message

Andy Sardina

unread,
Aug 11, 2016, 2:48:42 PM8/11/16
to scala-debate

Hi everyone!

 I'm new in Scala programming and there are some stuffs that I don't understand yet. For example, I have seen in some Scala projects, such as https://github.com/vkostyukov/scalacaster, the use of something like this:


def quicksort[A <% Ordered[A]](list: List[A]): List[A]

 

but I can't figure out what "<%" means in that context!! Please, can anyone help me to understand it?! 

Simon Ochsenreither

unread,
Aug 11, 2016, 3:03:37 PM8/11/16
to scala-debate
It's a "view bound". It means that the method requires a function from A => Ordered[A] to be implicitly available.

And now you can forget it again, because view bounds are being deprecated. :-)

Simon Ochsenreither

unread,
Aug 16, 2016, 7:21:48 AM8/16/16
to scala-debate
Thank you so much!!!

I finally understand the code of https://github.com/prnicolas/ScalaMl (at least, some parts!!). I really like Scala, and I'd like to learn how to use it for Machine Learnig. Thank you for answer me, I'm very surprised how quickly I could get an answer, I'll take it into consideration for the future. Finally I would like to ask you, where can I find more information of this kind of themes, and in what Scala's version this feature will be deprecated?.

I think the deprecation is not that official yet, as we want to only emit deprecation warnings when we have the tools to automate the rewrite as much as possible for developers.
If you pass the -Xfuture flag to scalac, you will already see the warning, though. If everything works out, I think it will be officially deprecated in 2.13.

Petr Novak

unread,
Aug 22, 2016, 6:41:19 AM8/22/16
to scala-debate
In Scala you need to understand these magical symbols and terms:
- "type bounds", symbols: [T <: U] and [T >: U]
- "view bounds", symbol: [T <% U]
- "context bounds", symbol: [T : U]

Put bound terms into Google and it gives explanations.

As already said view bounds are deprecated and generalized by context bounds. View bounds (VB) are implicit function or constructor while context bound (CB) is an implicit value. VB says that it is required that a type can be viewed as another type. This "viewing" is implemented as a function which implicitly converts one type to another behind the scenes (done by compiler). Disadvantage is that this conversion is done on every call and has perf impacts. As well the original type identity is lost after conversion.

CB says that a type has required capabilities implemented in a separate instance (value). Pretty much like using a helper class in Java. This instance has to be implicitly available in a scope, either created or by importing and object which provides this instance. This value with implementation of required capabilities is as well called "evidence" as it proves that given type has implementation of required capabilities available. The advantage is that there is no conversion, every call is using the same instance with required capabilities implementation for a given type (there is one implementation and instance (object) for each type used). And type keeps its identity, it is not converted during the process. Hence we can work with Employee domain type without having to switch to RichEmployee type for serialization etc. I like that it is possible to read required capabilities from type signature - def do[T : C1 : C2 : C3]() = ??? where C1, C2, C3 refer to required capabilities which has to be implemented for the type T. It is similar when understanding requirements from input arguments - anyway each context bound is compiled into one input argument for default constructor - good to understand it when trying to do some magic with reflection as default constructor can have different signature than expected after compilation.

Context bound syntax [T : U] and view bound syntax [T <% U] can be replaced with currying with implicit value or function respectively:

Eqv.
def do[T <% U](x: T) = ???
def do[T](x: T)(implicit v: T => U) = ???

Eqv.
def do[T : U](x: T) = ??? // use implicitly[U[T]] to get the value with implementation
def do[T](x: T)(implicit ev: U[T]) = ??? // ev is the value (evidence) with implementation

It can be read as U is type which defines required capability. U[T] is an implementation of capability U for type T.

I hope it helps more that confuses you,
Petr
Reply all
Reply to author
Forward
0 new messages