How to initialize empty variables from your own type in Scala? - scala

My problem is understanding is the syntax of Scala. I come from a Java background. I am trying to make a variable of the same type as the class it is in. Example:
class Exp {
var exp1: Exp;
}
I am getting this error:
Driver.scala:4: error: class Exp needs to be abstract, since variable exp1 is not defined
(Note that variables need to be initialized to be defined)
class Exp {
Can someone explain why I cannot do this? I am new to the language. Any explanation would help in understanding it better.

Because you need to initialize it. Otherwise the compiler thinks you want only the variable's interface: the getter and setter methods. It's very similar to how a method without a body is abstract. The following will initialize it to null and give you a valid concrete class with a concrete variable.
class Exp {
var exp1: Exp = _;
}
This use of _ means "default value" where the default is null for reference types and 0, false, or something similar for non-reference types.

Wildcard Initializer
in Scala 2:
var x: A = _
in Scala 3:
var x: A = scala.compiletime.uninitialized

Related

swift - Generic classes with inheritance

When I try to execute the code below, I get the following error
error: cannot convert value of type 'X' to specified type
'X'
Doesn't swift support inheritance with generics? Is there a workaround for this?
class Parent{ }
class Child:Parent{ }
class X<T>{
var name: String?
}
var test:X<Parent> = X<Child>() //Compiler Error
In Swift, generics are invariant, e.g. any X<A> will never be assignable to X<B>, regardless of the inheritence relationship between A and B.
Nevertheless, there are some exceptions to this rule, regarding Arrays and Optionals (and mabye some other types):
var array2:[Parent] = [Child]()
// same as:
var array1:Array<Parent> = Array<Child>()
var opt1:Parent? = Child()
// same as:
var opt2:Optional<Parent> = Optional<Child>(Child())
These will compile (since Swift 3) - but these a special cases treated by some hard-coded rules of the the compiler.

Where do I need to give Swift generics placeholder's type? And where it's not necessary? [duplicate]

Let's say I have a generic class:
class SomeClass<Element> {
// What is the difference between this:
var array: [SomeClass]!
// and this declaration:
var array2: [SomeClass<Element>]!
}
What is the difference between those declarations?
A generic type cannot exist without its generic argument, therefore omitting the generic type means that you want the compiler to infer the type.
In this case the logical type to be inferred is Element.
Note that this works only because you have used SomeClass inside SomeClass declaration. It wouldn't work for a different generic class.
A similar inferring of generic arguments can be used in variable declarations:
let instance: SomeClass = SomeClass<Int>()
let array: Array = [1] // Array<Int>

How do I get the instance from a Generic?

I just cannot understand why this causes errors (errors shown as comments in code):
class SomeClass {
var id = 123
}
class AnotherClass {
func myFunc<T>(object: T) {
T.id = 555 // Error: Type 'T' has no member 'id'
object.id = 555 // Error: Value of type 'T' has no member 'id'
}
}
let someClass = SomeClass()
let anotherClass = AnotherClass()
anotherClass.myFunc(someClass)
How do you get the instance of someClass after passing it into the generic function?
Also, I can't do any named downcasting inside AnotherClass (as you would expect with a generic).
You have to look up a little bit more about generics. T has no member called id - that is correct! Just because you pass in some T that has a member (SomeClass) that does not matter for the compiler since at some other point you can insert something else like a Int or [Double] or anything.
Consider adding the following line to your code
anotherClass.myFunc(1)
What should happen? What should .id do??? It would fail because 1 does not have a member called id.
Your T has no generic constraint telling the compiler anything, therefore it assumes you can just pass in anything. And then you can only use all those properties the possible inputs share.
What you might want to use is for example
func myFunc<T : SomeClass>(object: T) {
object.id = 555
}
That tells the compiler that you are only allowed to pass in objects of type SomeClass or classes that extend SomeClass. Following the logic from above the compiler can look at the code, all possible inputs and allows you to perform the operations that are valid on all possible inputs. Therefore the compiler knows that the id property exists since SomeClass has it and all classes extending SomeClass do as well, since that is how extending works.
Once again the apple docs on generics are a really good place to learn a lot about generics from the basics to the quite complex use-cases.

In Swift, can Types (not instances) conform to protocols?

I have a ViewController that uses a class (call it A) from a framework outside of my control. A provides a class function I need (call it f). I want to make A easy to mock out in tests.
So my idea was to create a protocol P that has the same signature as A, extend A to implement P, and then create a mock class M that also implements P and has a dummy implementation of f. Then in my tests, I could just do viewController.dependency = M and everything should be dandy.
This is easier said than done, for reasons I'm hoping you'll help me understand.
Inside my viewController, it's easy to declare a variable that contains a protocol-conforming instance and then reassign the variable to another Protocol-conforming instance:
// works
var dependency: P = A()
dependency.f()
dependency = M()
dependency.f()
But it doesn't work to do the same thing with just the types:
// doesn't work
var dependency = A.self
dependency = M.self // cannot assign value of M.Type to a value of type A.Type
// also doesn't work
var dependency: P = A.self // type A.Type does not conform to protocol P
Is there a way to make this work? I thought maybe I could use a generic type for dependency but I can't figure out a syntax to declare a generic type for a variable assignment.
If you really want to store the type itself, you can use P.Type. The following works in Swift 2:
protocol P {
static func foo()
}
class A: P {
static func foo() { print("A foo") }
}
class M: P {
static func foo() { print("M foo") }
}
var dependency: P.Type = A.self
dependency = M.self
dependency.foo()
It doesn't work because when you say var dependency = A.self, the compiler infers, from the right-hand side, that dependency's type is A. That means that if dependency ever gets reassigned, it can be assigned only to some other instance of an A class type. When you created protocol P with the same signature as A, then a a class M that implements P, you still haven't (and can't, since it's out of your control) made A implement protocol P. The way the Swift and Objective-C runtimes work is that each object contains a pointer to its type class. This type is inspected when assigning, and if the right-hand value is being assigned to a left-hand declaration, then the right-hand value has to have the left-hand's type somewhere in its inheritance hierarchy.
Some languages (e.g. Ruby) feature so-called duck typing, where if an object or class walks like a duck, then it is a duck, even if it's not really an instance of a duck. That's what you're looking for here, but Swift (and Objective-C) don't work that way. Duck typing is a type of pseudo-polymorphism. It's not really polymorphic.

Scala generics - why I can't create parametrised object inside generic class?

I'm currently learning scala.
Why this code doesn't work:
class GenClass[T](var d : T) {
var elems: List[T] = Nil
def dosom(x: T) = {
var y = new T()
y
}
}
I get:
error: class type required but T found
in place of var y - new T()
Is it because type erasing from java? Is there any way to solve this - create variable of type T inside generic function?
have a look at this question, there's an example of a factory:
How to instantiate an instance of type represented by type parameter in Scala
Because you can not be sure there always is a public, parameterless constructor.