Swift Experimentation

Andy Flatiron
6 min readNov 26, 2020

Things are off to a great start learning Swift! I’ve been enjoying the Stanford lectures (CS193P). To better internalize the reading assignment, I’m going to code along here, and review my thought process. Since I’m not in a physical class, this gives me a great opportunity to express myself and internalize my thoughts as I learn the vigorous course material.

The layout for today's blog post will be the following. To the best of my ability, I will read and then summarize a certain section in the Swift Documentation, afterwords I will showcase an example to demonstrate the concept.

Type Safety and Type Inference

Type safety makes sure that you specify the type of code you are working with. For example, if you are going to use a string, such as “hello world,” you can’t just set it to a var. Var hello= “hello world” would not work because the system is not aware that “hello world” is a string. So, in this case, you would need to specify what type the var hello is — a string. So instead, it would look like the following

var hello: String = "Hello World"

By assigning the Var “hello” to a string, you let the system know that this variable will always be a string. If you wanted to set hello to an integer or a boolean in the future, you can’t. Once you set a type param, it locks into its type and cannot be manipulated.

for example, the following code

var hello:String = "Hello, World"
hello = 1
print(str)

will print out an error “cannot assign the value of type ‘Int’ to type ‘String’”

Coming from Javascript, this took a bit of getting used to; however, I’m starting to see some of the benefits. When a language is type-safe, it prevents the code from even compiling two types that are not the same. Also, type safety helps you eliminate time-consuming type errors developed from multiple types interacting with one another.

However, unlike languages such as C or Objective-C, Swift has type inference which during certain declarations allows you to leave out the Type Variables as they will automatically be inferred

So, for demonstration purposes, I didn’t mention this in the original example, but if you set var hello = “Hello World”, swift will infer that “hello world” is a string and automatically set the type

In the following example, we are creating a function to check the type of the argument

func printInfo (value: Any){
let t = type(of: value)
print("\(value) of type \(t)" )
}var hello:String = "Hello, World"
hello = 1
print(str)

You can see if we introduce a number argument without specifying the type and print its information

var number = 5
printInfo(value: number)

We see that the number type is an integer

5 of type Int

Also, I’m not sure if this is exactly related to this topic, but functions require params to be written both when calling the function and in the function itself. This is great, as it allows you to know what you’re argument is doing in the function itself.

So in the case of this function

func printInfo (value: Any){}

In order to pass in a value, you’ll need to specify “value: argument” before sending in the argument

var number = 5
printInfo(value: number)

If you don’t want to specify the parameter type, you can put an underscore before the argument in the function, which will allow you to call

func printInfo (_ value: Any){}
printInfo(number)

Also, Any means that you can input any type into the function. Similar to strong type the parameter needs to have a specified type and return function, but if you use any, it takes in any type and returns any type

For example, if you did this:

func printInfo (value: String)

and tried passing an integer into the function

var number = 5
printInfo(value: number)

The program would error out as it “Cannot convert Int into String”. That’s a bit on type safety and inference in Swift, now I’d like to test out an example.

In Javascript, you could get the following error based on the arguments that you send into the function

const funFunction = (a,b) => {
console.log(a + b.toUpperCase())
}

toUpperCase is a function that could only be called on Strings, but Javascript allows you to send an Int into the function…and if you send in Int as ‘b’ the code will error out. So this can be frustrating of only some arguments are working with your function. In more complex cases, you wouldn’t even be sure where the error is coming from and it could be a long process of debugging.

In Swift, however, you wouldn’t even try to pass in an integer because the function so clearly states we only accept string

func funFunction(_ a: String, _ b:String){
let b = (b.uppercased())
print (a + b)
}
funFunction("hello", 1)

And not to mention the function would error out before even calling the function — saying the following

error: eligible-.playground:14:22: error: cannot convert value of type 'Int' to expected argument type 'String'
funFunction("hello", 1)

That’s it for the safe type and type inference section for today’s reading.

Numeric Type Conversion

Numeric type conversion makes sure that you don’t combine two different number types accidentally. Swift recommends typically using ‘Int’ or ‘Double’ as it will function universally throughout your code, however, if you are looking to do more complex computing, or working upstream into memory efficiency, you may use different types of integers.

Here are the different types of integer formats you may encounter

UInt8 (min: 0, max: 255)

UInt16( min: 0, max: 65535)

UInt32(min: 0, max: 4294967295)

UInt64(min: 0, max: 18446744073709551615)

Note, none of these integer types have the ability to be less than zero. And what if you have an integer in the negatives that you’re looking to compute … how would you go about doing it?

So let’s say we have an Int at “-40”

let negativeForty:Int = -40

And if want to take another variable and subtract it…actually it looks like this can’t be done because there is no way to convert a UInt to an Int — unless you use something called a bit pattern, which I’m not going to digest today…

But nevertheless, let’s explore some of the possibilities of type-conversions. So, if you have a UInt16 it won’t add with a UInt32. But, Swift has built-in extensions that allow the conversions between the two numerical structures.

So for example if we try to add number1 and number2 which are different number formats, it won't compute properly :

let number1: UInt16 = 120
let number2: UInt8 = 4
let outputNum = (number1+number2)
print(outputNum)
=> overloads for '+' exist with these partially matching parameter lists: (UInt16, UInt16)

But we can add a numeric type conversion

UInt16(number2)

Which is an extension within the UInt16 class, which will allow us to add the numbers as follows:

var number1: UInt16 = 120
var number2: UInt8 = 4
//adding number 1 to convert number 2 to 16 bit from 8
var outputNum = (number1+UInt16(number2))
print(outputNum)

=> 124

Tuples

A touple lets you group many different types into one variable. It functions similarly to an array, but is not reccomended to be used in multiple data types. With a tuple, you can also rename multiple variables at once for easier access to your intended data type.

let chance = ("dog", false, 3)
let (animal, good, age) = chance
print(("\(good)"))
=> false
//the value of false is automatically linked up to the value of 'good' in the tupple

The documentation mentions tuples work best with functions that return multiple arguments,so let’s give it a shot — we’ll have a function that returns a recipe, with amount of ingredients (Int) and Main Ingredient (String)

func recipe(ingredientsCt:Int, mainIngredient: String ){
let recipe = (ingredientsCt, mainIngredient)
print("You're going to cook \(recipe.0) portion of \(recipe.1)")
}
recipe(ingredientsCt: 1, mainIngredient: "Rice")

In the above example I set recipe to a tuple and was able to easily access the different argument variables by calling (0 and 1) on the tuple. This seems like a good way to handle function execution.

These are some initial examples that I created to showcase the initial reading and experiementation with the Swift documentation. It’s been great, so far.

Until Next,

Andy

--

--