Use nested type as type parameter for generic subclass - swift

Is the following use of Generics "allowed"/unproblematic in swift? I mean, it compiles, but could this cause problems in some cases? It feels strange to use something from within a class while defining that class.
class MyGeneric<A> {}
class MyClass: MyGeneric<MyClass.NestedType> {
enum NestedType {}
}
This question might be kind of stupid and the answer might very well be "it compiles, so yes" but it feels quite strange to write it like this. But it would also be nice if it was fine. Makes the code much more organized and concise.

It's fine.
MyClass.NestedType doesn't get any special attachment to MyClass, MyGeneric or A. It's just a naming thing.
Constrast this with say, Java, where non-static inner classes are parameterized by their containing classes generic type. E.g. Foo<A>.Nested is a different class from Foo<B>.Nested.

Related

Scala trait or concrete class

So I get what we can do with traits but in what cases should we prefer their use to a concrete class ? I was told to use traits everywhere I can and when I need to instanciate something use a regular class.
Edit : I am actually asking about when to use a trait insted of a concrete class not an abstract one
As it's often the case, there is no single rule, but I personally found useful a general suggestion give in Odersky/Spoon/Venners book "Programming in Scala".
It says if the behaviour will not be reused in other unrelated classes, use a concrete class. On the other hand, if you think you'll reuse that behaviour somewhere else in unrelated places, make it a trait.

How to correctly implement a custom number-like class in Scala?

I am currently trying to implement my own UnsignedInt. I would like to implement this correctly so that it fits into the whole Scala type & class system. However, I am really confused by all the classes that fit into Number.
With which class(es) do I need to work: Numeric, Integral or ScalaNumber? Or something completely different? What classes and/or traits should my own class implement?
The short answer is: don't implement your own, use the Spire one :) Otherwise, you should implement Integral (which includes Numeric). Note that your type shouldn't extend it; you need implicit values in the companion object, i.e.
class UnsignedInt { ... }
object UnsignedInt {
implicit val UIntIntegral: Integral[UnsignedInt] = ...
}
You should also consider making your class a value class.

How to determine to use trait to 'with' or class to 'inject'?

I'm puzzled to choose a trait or class when writing scala code.
At first, I have a controller which with several traits:
class MyController extends Controller
with TransactionSupport
with JsonConverterSupport
with LoggerSupport
In these traits, I defined some methods and fields which can be used in MyController directly.
But my friend says: when you extends or with a trait, it should be a that trait.
Look at the MyController, it is a Controller, but it isn't a TransactionSupport, not a JsonConverterSupport, not a LoggerSupport, so it should not with them.
So the code becomes:
class MyController(tranSupport: TransactionSupport,
jsonConverter: JsonConverterSupport,
loggerSupport: LoggerSupport) extends Controller
But I don't feel good about this code, it just seems strange.
I see traits used heavily in scala code, when should I use it or use classes to inject?
I'll refer you to Interfaces should be Adjectives. Though some traits may play the part of a class (and, therefore, be nouns and respect the "is-a" relationship), when used as mixins they'll tend to play the part of interfaces.
As an "adjective", the trait will add a qualifying property to whatever they are extending. For example, they may be Comparable or Serializable.
It can be a bit hard to find an adjective to fit -- what adjective would you use for LoggerSupport? -- so don't feel overly constrained by that. Just be aware that it is completely wrong to thing of traits as necessarily an "is-a" relationship.
I would try to avoid using traits to replace "has-a" relationships, though.
My opinion is that it doesn't have to be it. Mixing-in is a different concept than inheritance. Even though syntactically it is the same, it doesn't mean the same. Typical use case for mixing-in is logging just like you wrote. It doesn't mean that if your service class mixes-in a Logging trait that it is a logger. It's just a yet another way how to compose functionality into working objects.
Odersky proposes that if you are not sure and you can, use traits because they are more flexible. You can change trait to class in the future if you need.
Sometime when I feel that mixing-in trait doesn't look good, I use module pattern like this:
trait JsonConverterModule {
protected def jsonConverter: JsonConverter
protected trait JsonConverter {
def convert(in: Json): Json
}
}
class MyController extends Controller with JsonConverterModule {
private doSmth = jsonConverter.convert(...)
}
MyController in this case looks more like a Controller, and all Json-related stuff is hidden from MyController 'client'
Your first example with traits is the "cake pattern" and your second example is "constructor injection". Both are perfectly valid ways to do dependency injection in Scala. The cake pattern is powerful, you can inject type members, the different traits can easily talk to each other (we don't have to create separate objects and pass them to each other object, often requiring setter injection rather than simple constructor injection), etc. However, the type has to be realized at compile-time, and a separate class must be realized for every combination of traits. Constructor injection lets you build your object at run-time and scales better for a large number of combinations.

How do I force the Scala compiler to tell me when my class is abstract?

Why is the "abstract" keyword for class definition optional in Scala, and how do I force the Scala compiler to tell me when my class is abstract?
Here an example that I wrote in Eclipse:
class Toto[T] {
def get(index: Int): T
}
object Toto {
def create[T]: Toto[T] = new Toto[T]
}
This seems to be a perfectly valid class definition in Scala, although it does NOT define the required get method, and is NOT prefixed with abstract. If you don't need the abstract keyword, then why does it exist? And if you want to be told that your class is actually abstract, how do you get the compiler to tell you?
This is not valid scala code, abstract is required, and instanciation forbidden. From the spec (5.2, p63):
The abstract modifier is used in class
definitions. It is redundant for
traits, and mandatory for all other
classes which have incomplete members.
Ab- stract classes cannot be
instantiated (ยง6.10) with a
constructor invocation unless
followed by mixins and/or a refinement
which override all incomplete members
of the class. Only abstract classes
and traits can have abstract term
members.
The code produces an error in the REPL : error: class Toto needs to be abstract, since method get is not defined
I get the proper behavior with the same message in Eclipse too. You should check whether you get the same error with and without eclipse. Whichever is true, I guess if you have exactly the code you posted without an error (does it run?), a bug repport will be warranted.
To answer my own question: In Eclipse, you can only tell if a class is correct if all other classes compile without errors! In other word, you can't trust anything Eclipse says about a class unless there are no errors in other classes.
So if you have errors in several classes, then there is no way of knowing which ones are the real errors, and neither if a class without errors is correct.
You just have to repeatedly loop on the errors, fixing any one that makes sense, and hoping the others errors that don't make sense are eventually going to just disappear.

Is it appropriate to define a non-trivial Scala case class?

I'm defining a Scala class today, and I think "I need an equals method and a hashCode method; and a copy method would be handy too. I'll turn this into a case class." My class already has a bunch of other code, and is in no way trivial.
So fine, it all works and everything, but when the text books deal with case classes, all of the examples define them for use as value classes or 'data transfer objects'. Is it appropriate to define a non-trivial case class? Is the thought process described above OK, or do I need to think of case classes differently?
A case class provides, equals, hashCode and toString methods based on the main constructor parameters, all of which are turned into val too. In addition, the object companion gets an apply and an unapply methods, again based on the main constructor parameters.
Also, a case class inherits from Serializable and from Product, and should not be extended by other classes.
If all of these things are appropriate for your class, then feel free to declare it as a `case class'.
Feel free, provided it doesn't have descendants. Extending case classes is a bad idea.