var initalization at the time of declaration in scala - scala

I am confused with following initialization
var in = None: Option[FileInputStream]
however what I know is that
var varName : type = _ // default value initialization
var varName : type = someValue // other than default intitalization
but what is
var in = None: Option[FileInputStream]
Please help
Thanks

This is called a type ascription and the resulting expression is called a typed expression. It, well, ascribes a type to an expression:
expr: Type
means "treat expr as if it had Type".
For example:
1
// Int
1: Float
// Float
Obviously, the expression needs to conform to the type that is ascribed to it.
The most widely used example of type ascription is probably the _* pseudo-type, which unpacks a Seq into a series of arguments:
def sumNums(nums: Int*) = nums.sum
sumNums()
//=> 0
sumNums(1)
//=> 1
sumNums(1, 2)
//=> 3
sumNums(Seq(1, 2))
// error: type mismatch;
// found : Seq[Int]
// required: Int
// sumNums(Seq(1, 2))
// ^
sumNums(Seq(1, 2): _*)
//=> 3
In your particular case, I find it questionable to ascribe a type to an expression just to get the type inferencer to infer the correct type, when you could just as well have declared the correct type to begin with:
var in: Option[FileInputStream] = None
With regards to your comments:
however what I know is that
var varName : type = _ // default value initialization
var varName : type = someValue // other than default intitalization
You can also leave out the type:
var varName = someValue
In this case, the type is inferred from the expression someValue.
var varName = _
Obviously, this cannot work: the type is inferred from the expression, but the value of the expression is inferred from the type. Therefore, this is not allowed.
Your example uses the form with inferred type:
var in = someExpression
So, the type of in is inferred from the type of someExpression.
Now, if we said
var in = None
then the type inferred for in would be None.type, i.e. the singleton type of the None object. But that doesn't make sense: why would we have a var, i.e. a variable which we can change, when we then give it a singleton type, i.e. an type which has only a single instance. So, we can re-assign in as often as we want, but we can only assign the same thing to it. That's illogical. (Well, technically, we could also assign null to it.)
And in fact, we want to be able to assign something to it, but also know whether we assigned something to it or not. That's why we use an Option in this case, and initialize it with None. So, re-interpret None as an Option, so that Scala infers the correct type:
var in = None: Option[FileInputStream]

// [name] = [value] : [type]
var in = None : Option[FileInputStream]
// can equivalently be written as:
var in: Option[FileInputStream] = None
This creates a variable of type Option[FileInputStream], with the initial value None.
To learn more about Scala's Option type, see http://www.scala-lang.org/api/current/#scala.Option

Related

Why can't I call Optional methods on an optional-chained type?

Consider the following example where foo is explicitly defined as optional:
let foo: Int? = 10
let bar = foo.map { $0 * 2 }
This compiles and works as expected. Now consider a subsequent example using optional chaining:
let foo: [Int]? = [0, 1, 2]
let bar = foo?.count.map { $0 * 2 }
This fails to compile with the following message:
error: value of type 'Int' has no member 'map'
Why does the compiler see foo?.count as an Int and not an Int?? This defies the Swift Language Book:
To reflect the fact that optional chaining can be called on a nil value, the result of an optional chaining call is always an optional value, even if the property, method, or subscript you are querying returns a non-optional value.
This is an operator precedence issue. You need to add parentheses to change the order:
let bar = (foo?.count).map { $0 * 2 }
Consider the case of a Collection like String rather than an Int:
let foo: String? = "ABC"
let bar = foo?.uppercased().map(\.isLowercase) // [false, false, false]
In this case, it's sensible that the .map applies to the String rather than to the Optional. If the precedence were the other way, then you'd need a ?. at every step (or a lot of parentheses :D)
The type of count unwraps to Int if available. Int does not implement the function map. Optional chaining simply fails when it finds nil. The compiler is trying to tell you if it does not fail the operation map cannot happen. The result is bar which is indeed an optional, because if the operation fails( because something unwraps to nil) the entire chain must return nil.

Is there any particular resource that demonstrates which values can be inferred in Swift?

For instance:
let myConstant = 4
The value of the constant above can be inferred
How do we know if a value can be inferred or not?
Generally, the type of x can be inferred if the type of value that expression will evaluate can be known:
let x = <expression>
In your example, 4, an integer literal, is evaluated to be an Int, so myConstant's type is inferred to be Int.
Another example:
func f() -> String { return "Foo" }
let x = f()
The type of x can be inferred because we know the type that f will return by looking at its declaration, a String.
For more complicated expressions, this still holds true. The compiler will look at the types that each subexpression evaluates to and do an analysis to figure out what type the expression will evaluate to eventually.
However, sometimes this cannot be done:
func f<T>() -> T? { return nil }
let x = f()
f can return any type but you haven't specified any. T is not known so the return type of f is not known, so x's type cannot be inferred.

What is the differnce between both the declarations in scala?

I declared both the variables in two ways. But the output is same as "name". Then what is the difference between both the declarations? Are there any differences in memory allocations?
var x="name"
println(x)
var y:String="name"
println(y)
There is no difference with respect to memory allocations.
In case 1 Scala compiler infers the type for you
var x = "hello"
In case 2 You are explicitly announcing the type to guide the compiler
var x: String = "hello"
Explicit type declaration is important in some cases where Compiler inferred type is not good enough. For example
var a = 1
Compiler will infer the type of a as Int. But if I want a to be AnyVal in this case I have to say var a: AnyVal = 1

What is the difference between Type Safety and Type Inference?

How are they different? I get a bit confused because they seem to be similar concepts.
How does understanding them help with optimizing compilation time?
From Swift's own documentation:
Type Safety
Swift is a type-safe language. A type safe language encourages you to be clear about the types of values your code can work with. If part of your code expects a String, you can’t pass it an Int by mistake.
var welcomeMessage: String
welcomeMessage = 22 // this would create an error because you
//already specified that it's going to be a String
Type Inference
If you don’t specify the type of value you need, Swift uses type inference to work out the appropriate type. Type inference enables a compiler to deduce the type of a particular expression automatically when it compiles your code, simply by examining the values you provide.
var meaningOfLife = 42 // meaningOfLife is inferred to be of type Int
meaningOfLife = 55 // it Works, because 55 is an Int
Type Safety & Type Inference together
var meaningOfLife = 42 // 'Type inference' happened here, we didn't specify that this an Int, the compiler itself found out.
meaningOfLife = 55 // it Works, because 55 is an Int
meaningOfLife = "SomeString" // Because of 'Type Safety' ability you will get an
//error message: 'cannot assign value of type 'String' to type 'Int''
Tricky example for protocols with associated types:
Imagine the following protocol
protocol Identifiable {
associatedtype ID
var id: ID { get set }
}
You would adopt it like this:
struct Person: Identifiable {
typealias ID = String
var id: String
}
However you can also adopt it like this:
struct Website: Identifiable {
var id: URL
}
You can remove the typealias. The compiler will still infer the type.
For more see Generics - Associated Types
Thanks to Swift’s type inference, you don’t actually need to declare a
concrete Item of Int as part of the definition of IntStack. Because
IntStack conforms to all of the requirements of the Container
protocol, Swift can infer the appropriate Item to use, simply by
looking at the type of the append(_:) method’s item parameter and the
return type of the subscript. Indeed, if you delete the typealias Item
= Int line from the code above, everything still works, because it’s clear what type should be used for Item.
Type-safety and Generics
Suppose you have the following code:
struct Helper<T: Numeric> {
func adder(_ num1: T, _ num2: T) -> T {
return num1 + num2
}
var num: T
}
T can be anything that's numeric e.g. Int, Double, Int64, etc.
However as soon as you type let h = Helper(num: 10) the compiler will assume that T is an Int. It won't accept Double, Int64, for its adder func anymore. It will only accept Int.
This is again because of type-inference and type-safety.
type-inference: because it has to infer that that the generic is of type Int.
type-safety: because once the T is set to be of type Int, it will no longer accept Int64, Double...
As you can see in the screenshot the signature is now changed to only accept a parameter of type Int
Pro tip to optimize compiler performance:
The less type inference your code has to do the faster it compiles. Hence it's recommended to avoid collection literals. And the longer a collection gets, the slower its type inference becomes...
not bad
let names = ["John", "Ali", "Jane", " Taika"]
good
let names : [String] = ["John", "Ali", "Jane", " Taika"]
For more see this answer.
Also see Why is Swift compile time so slow?
The solution helped his compilation time go down from 10/15 seconds to a single second.

dynamicType of optional chaining not the same as assignment

Optional chaining returns always an optional value.
To reflect the fact that optional chaining can be called on a nil value, the result of an optional chaining call is always an optional value, even if the property, method, or subscript you are querying returns a nonoptional value.
The Swift Programming Language
Why the heck does in a playground the type not optional?
let stringOptEmpty: String? = ""
stringOptEmpty?.isEmpty // is true
stringOptEmpty?.isEmpty.dynamicType // Bool.Type
But the following code is
let isOk = stringOptEmpty?.isEmpty.dynamicType
isOk.dynamicType // Optional<Bool.Type>.Type
TLDR;
The playground sidebar/column will dynamically resolve expressions in the playground, be it values assigned to variables (mutables/immutables) or just "free-floating" non-assigned values.
Your first example applies dynamicType to a value, which will resolve to the type of that specific value (true.dynamicType: Bool.Type).
Your second example, on the other hand, applies dynamicType to a variable (an immutable, but I'll use variable here to differ from value), which must have a concrete type, and hence will resolve to a type that can hold any kind of wrapped values (true or false) as well as nil (here, nil is, specifically, Optional<Bool.Type>.None), no matter what value the variable actually holds. Hence, the dynamicType will resolve to Optional<Bool.Type>.Type in your second example.
Details
The value displayed in the playground sidebar/column generally follows the following display rules:
For an assignment expression, the value shown in the sidebar is the value assigned, e.g.
var a = 4 // shows '4'
a = 2 // shows '2'
let b: () = (a = 3)
/* shows '()': the _value_ assigned to 'b', which is the _result_
of the assignment 'a = 3', to which a _side effect_ is that 'a'
is assigned the value '3'. */
For an expression that contains no assignment, the value shown in the sidebar is generally the result of the expression, e.g.
true // shows 'true'
1 > 3 // shows 'false'
let c = 3
c // shows '3'
c.dynamicType // shows 'Int.Type'
In your first example (lines 2-3), we have no assignment, and the playground will dynamically resolve the value(/result) of the expression prior to resolving the dynamicType of that value. Since we're dealing with optionals, the value is either simply the value of the wrapped type (in this case, true), or the value is a type specific .None. Even if the playground shows e.g. the result of let a: Int? = nil as just nil in the sidebar, the value shown is in fact not the same .None (nil) as for say let b: String = nil
For let a: Int? = nil, the value of a is in fact Optional<Int.Type>.None,
whereas for let b: String? = nil, the value of b is Optional<String.Type>.None
With this in mind, it's natural that the resolved dynamicType of a non-nil value will be the concrete wrapped type (in your example, Bool.Type is naturally the type of true), whereas the resolved dynamicType of a nil value will include both the general optional and the wrapped type information.
struct Foo {
let bar: Bool = true
}
var foo: Foo? = Foo()
/* .Some<T> case (non-nil) */
foo?.bar // true <-- _expression_ resolves to (results in) the _value_ 'true'
foo?.bar.dynamicType // Bool.Type <-- dynamic type of the _result of expression_
true.dynamicType // Bool.Type <-- compare with this
/* .None case (nil) */
foo = nil
foo?.bar.dynamicType // nil <-- _expression_ resolves to the _value_ 'Optional<Foo.Type>.None'
Optional<Foo.Type>.None.dynamicType
// Optional<Foo.Type>.Type <-- compare with this
Now, if you assign the values to a variable, naturally the variable must have a concrete type. Since the value we assign at runtime can be either .None or .Some<T>, the type of the variable must be one that can hold values of both these cases, hence, Optional<T.Type> (disregarding of whether the variable holds nil or a non-nil value). This is the case which you've shown in your second example: the dynamicType of the variable (here, immutable, but using variable to differ from value) isOk is the type that can hold both .None and .Some<T>, no matter what the actual value of the variable is, and hence dynamicType resolves to this type; Optional<Bool.Type>.Type.
Wrapping expressions in parantheses escapes the runtime introspection of the Swift Playground?
Interestingly, if an expression is wrapped in parantheses prior to applying .dynamicType, then the playground sidebar resolves .dynamicType of the wrapped expression as the type of the expression, as if its actual value was unknown. E.g., (...) in (...).dynamicType is treated as a variable with a concrete type rather than a runtime-resolved value.
/* .Some case (non-nil) */
foo?.bar // true
(foo?.bar).dynamicType /* Optional<Bool>.Type <-- as if (...)
is a _variable_ of unknown value */
/* .None case (nil) */
foo = nil
(foo?.bar).dynamicType /* Optional<Bool>.Type <-- as if (...)
is a _variable_ of unknown value */
We can further note that any lone expression wrapped in parantheses in the playground will not resolve to anything at all (in the sidebar). It's as if we escape the sidebar:s runtime introspection if wrapping expressions in parantheses (which would explain why the dynamicType of expressions wrapped in parantheses will resolve as if the playground cannot make use runtime information of these expressions)
var a = 4 // shows '4'
(a = 2) // shows nothing; can't expand or get details in sidebar
Tbh, I cannot explain why this is, and will categorize it as a peculiarity of the Swift playground.