« Return to Thread: annotations or traits to better scale scala up

Re: annotations or traits to better scale scala up

by Walter Smith :: Rate this Message:

Reply to Author | View in Thread

Marcus Downing wrote:
Walter Smith wrote:
DontAssign: Like HashMap example above, this type is not meant for variables, values, or return types. Just use it for construction.
I see two sides to this. The first is in issuing warnings should somebody use the class manually, for example:

   val map: HashMap
               ^ Cannot use scala.collection.mutable.HashMap as a value type, suggest scala.collection.mutable.Map instead

This could get *really* annoying if used incorrectly. For example, if HashMap implemented a method that Map does not.
True, but I think for bigger systems the possibility to use it correctly outweighs the danger of annoyingly bad design.

Marcus Downing wrote:
Walter Smith wrote:
DontExtend: This class is meant to just be called by client code; avoid the much stronger coupling by implementing a trait or extending a class. This privilege is left to the library itself.
Can't this be achieved with the sealed modifier? That prevents the class being extended except in the same source file.
Yes it can, but there may be just too many extensions to reasonably put into one file!

Marcus Downing wrote:
Walter Smith wrote:
Key: Instances of this class can be used e.g. as a key in a HashMap, i.e. the class overloads == and hashCode.
Are you suggesting that a HashMap would refuse to accept any non-valid keys? This could be accomplished with a trait applied by the compiler, but any class that wasn't compiled with this trait would then be invalid - including String.
I *do* suggest that HashMaps don't accept non-valid keys. But Strings *are* valid keys. An annotation or a common trait would not work at all, but some sort of structural type could; it does not work, yet, as you can't tell the compiler that the structural type has to overload these methods instead of inheriting them from Any; maybe an annotation on the structural type... something like:

type Key = {
  @overriding def equals(that: Any): Boolean
}

class HashMap[K <: Key, V]() { ... }

class Invalid()
class Valid() { def equals(that: Any): Boolean = ... }

new HashMap[Invalid, String] // should not compile
new HashMap[Valid, String] // does compile
new HashMap[String, String] // does compile as well

Maybe allowing the override keyword in a structural type would be an even better option.


Thanks for the feedback and kind regards
Walter

 « Return to Thread: annotations or traits to better scale scala up