Swift vs Kotlin

Apple on top of Android's head
Dropbox wrote a candid and insightful post titled The (not so) hidden cost of sharing code between iOS and Android. It's a common dream to have "one codebase to rule them all" but reality intruded, not only for DropBox, but on projects I have worked on as well.

Dropbox needed to support both Android and iOS devices, so instead of writing for each platform in Java and Objective C respectively, they labored to produce a layer of C++ code that worked for both.  But success was hard to come by, and in their own words:

By writing code in a non-standard fashion, we took on overhead that we would have not had to worry about had we stayed with the widely used platform defaults. This overhead ended up being more expensive than just writing the code twice.

I would add, from my own experience, that a "generic code layer" targets the lowest common denominator, and fails to take full advantage of native device features.  Add that Apple and Google are continuously improving their tool chain -- Xcode and Swift, Android Studio and Kotlin -- and you miss out on those developments as well.

Xcode and Android Studio are both robust environments, complete with a text editor, hooks to version control, and connections to emulators.  Interestingly, the GUI editor in Xcode is referred to as a storyboard, a common term in the movie and animation business. In Android Studio, it's called a layout editor and the blue theme and markings are reminiscent of an architect's blueprints.  Indeed, Apple is known for its artistic side while Google is known for its technical side.

A more significant difference is how iOS and Android interpret device rotation. Under iOS, the app loads the horizontal storyboard and continues where it left off from portrait mode.  Under Android, however, the app loads its horizontal layout and is restarted.  The memory of the app is reset, and you need to save and restore your instance state if you want the illusion of continuity.  In addition, the GUI elements need to be refreshed to properly reflect the state you choose.

Regarding the native languages, Swift has a light C/C++ feel whereas Kotlin is described to me as a concise and safe derivative of Java (not an expert in Java, my opinion doesn't count). Here's what I learned from writing LuldCalc:

if statement

Swift: does not need parens around the condition.
if condition {}

if (condition) {}


enum operation
    case none
    case add, subtract, multiply, divide
    case equal

Kotlin: as a matter of style, Kotlin insists that enumerations begin with a capital letter.
enum class Operation
    Add, Subtract, Multiply, Divide,


Swift: unlike C, Swift does not need a break statement between cases.

switch opKey {
    refPrice = savedRefPrice + refPrice
    refPrice = savedRefPrice - refPrice
    refPrice = savedRefPrice * refPrice
    refPrice = savedRefPrice / refPrice
case .none:
    print ("opKey is none")
case .equal:
    print ("opKey is equal")

Kotlin: uses "when" with a similar benefit of not requiring a break statement.
when(opKey) {
    Operation.Add -> refPrice = savedRefPrice + refPrice
    Operation.Subtract -> refPrice = savedRefPrice - refPrice
    Operation.Multiply -> refPrice = savedRefPrice * refPrice
    Operation.Divide -> refPrice = savedRefPrice / refPrice
    Operation.None -> print("opKey is None")
    Operation.Equal -> print("opKey is Equal")

Function returning multiple values

Swift: Functions are declared starting with "func" and the return values are identified at the end, following the ->.

func getDelta (refPrice: Double, tier: Int, multiplier: Int)->(delta:Double, percent:Double)
    var percent: Double = 0.0
    var delta: Double = 0.0

    . . .

    return (delta, percent)

The code to call getDelta() and obtain the return values looks like this:

    let price = getDelta (refPrice: refPrice, tier: tier, multiplier: bandMultiplier)
    print ("Delta is \(price.delta)")
    print ("Percent is \(price.percent)")

Kotlin: You need to first define a data class that will hold the return values, then append the data class to the end of the function declaration.

data class Delta(var delta: Double, var percent: Double)
fun getDelta (refPrice: Double, tier: Int, multiplier: Int): Delta
    var percent = 0.0
    var delta = 0.0
    . . .
    return Delta (delta, percent)

The code to call getDelta() and obtain the return values looks like this:
var (delta, percent) = getDelta(refPrice, tier, bandMultiplier)
print ("delta is $delta")
print ("precent is $percent")
Swift has the cleaner implementation, not just compared to Kotlin, but to C/C++ as well.

Nan and Infinity

Both Swift and Kotlin handle Nan (not a number) and Infinity in the same way. Swift:
if price.isNaN || price.isInfinite { // ERROR }
Kotlin: if (price.isNaN() || price.isInfinite()) { // ERROR }

Int to Double

Swift: uses a cast like C
Kotlin: uses a function multiplier.toDouble()
Cool difference in for loop

Swift: This will loop from 1 to n, without a need for a counter. Swift beats C.
for _ in 1...n { roundFactor *= 10 }
Kotlin: repeat will do the same, but more concisely. Kotlin beats Swift.
repeat(n) { roundFactor *= 10}
Ternary Operation

Swift: behaves like C.
    refPrice = (Double)(refPriceStr) ?? 0.0
Kotlin: will crash on .toDouble() if refPriceStr is non-numeric. refPrice = if (refPriceStr.isNotEmpty()) refPriceStr.toDouble() else 0.0 Therefore, exception handling is needed. try { refPrice = refPriceStr.toDouble() } catch (e: NumberFormatException) { refPrice = 0.0 }
This last example makes it easy for me to declare Swift as the prettier and more approachable language.

Newton's Apple, Eve's Apple, and Steve's AppleThe photo on top was inspired by this image on the right: "Three Apples that changed the world."  Knowing my fondness for Apple, a friend sent this to me with a helpful translation: "Newton's Apple, Eve's Apple, and Steve's Apple." 


Popular posts from this blog

Bookshelf: UNIX A History and a Memoir

Bookshelf Classic: The C Programming Language