1

QUESTION:

Why would Swift use something like optionals when I could just check if the value is nil or not ? Essentially, I am wondering what's the use of such a language feature, I am learning Swift atm and from my beginner perspective it seems redundant/useless.

P.S.: I am coming from Javascript.


CODE:

It seems absurd to me to do something like :

if let normalImage = imageFromFaceBook {
  print(normalImage) // normalImage is a constant
} else {
  print("There is no image")
}

when I could just do :

if (imageFromFacebook != nil) {
    print(imageFromFacebook) // normalImage is a constant
} else {
    print("There is no image")
}

like I normally do in Javascript :

if (imageFromFacebook != null) {
    print(imageFromFacebook) // normalImage is a constant
} else {
    print("There is no image")
}
TheProgrammer
  • 1,409
  • 4
  • 24
  • 53
  • Why the downvote ? – TheProgrammer Feb 14 '18 at 16:22
  • 5
    You cannot say `someVar != nil` unless `someVar` _is_ an Optional. So the question makes no sense. – matt Feb 14 '18 at 16:22
  • I'm not familiar with Swift optionals, but optionals indicate on the type level that something may be nil, which allows for the compiler to do safety checks for you. You can also map optionals, which completely negates the need for explicit checking at all. – Carcigenicate Feb 14 '18 at 16:22
  • 1
    Remotely related: [When should I compare an optional value to nil?](https://stackoverflow.com/questions/29717210/when-should-i-compare-an-optional-value-to-nil). – Martin R Feb 14 '18 at 16:24
  • 2
    What you are perhaps thinking of are C pointers or Objective-C instance pointers which can be checked for being nil/NULL. Swift optionals are a far more general concept and can be used with any type, not just pointers. – Martin R Feb 14 '18 at 16:26
  • @matt I should have made my question more detailed: what I really meant is: why would Swift use something like optionals when I could just check if the value is nill or not ? Essentially, I am wondering what's the use of such a language feature, I am learning Swift atm and from my beginner perspective it seems redundant/useless. – TheProgrammer Feb 14 '18 at 16:29
  • 1
    `nil` means it _is_ an Optional. Only an Optional can ever be `nil`. So the question still makes no sense. The notion "I could just check if the value is nil" presupposes that there are Optionals. So that's why there are Optionals: so you _can_ check if the value is nil. – matt Feb 14 '18 at 16:30
  • Okay but that's about `if let`. That's not what you asked. That's just a convenient notation. If you don't like it, don't use it. – matt Feb 14 '18 at 16:33
  • 1
    @Matt So optionals are just a convenient notation ? And btw, that was what I wanted to ask although I admit my question could have been clearer. – TheProgrammer Feb 14 '18 at 16:35
  • 2
    Please read https://stackoverflow.com/questions/24003642/what-is-an-optional-value-in-swift. Read all the answers. – matt Feb 14 '18 at 16:35
  • No. Optionals are not a convenient notation. Optionals just exist. `if let` is a convenient notation for testing an Optional and unwrapping it all in one move, i.e. instead of `if ... != nil` plus unwrapping the Optional. – matt Feb 14 '18 at 16:36
  • It is perfectly possible to deal satisfactorily with Optionals without ever saying `if let`. If you want to do that, go ahead. That would be foolish, but you could do it. – matt Feb 14 '18 at 16:37
  • @matt Again, let me try to explain: I understand how optionals work, I just don't understand why they exist in the first place in Swift. "if ... != nil plus unwrapping the Optional. " That's my point, what's the use of optionals ? – TheProgrammer Feb 14 '18 at 16:37
  • @matt "It is perfectly possible to deal satisfactorily with Optionals without ever saying if let. If you want to do that, go ahead. That would be foolish, but you could do it" That's not what I am talking about. – TheProgrammer Feb 14 '18 at 16:37
  • @TheProgrammer: Think of other data types as well, such as integers, enums, custom structs, ... – Martin R Feb 14 '18 at 16:39
  • @MartinR I am sorry, I don't understand what you are suggesting with this comment. Could you please enlighten me ? – TheProgrammer Feb 14 '18 at 16:40
  • 2
    @TheProgrammer When using javascript, have you ever encountered `TypeError` when trying to access something within a null reference? Ever wondered if there was some static, guaranteed way that a compiler can double check that you haven't forgotten to check for null? That's what Optional is. – Alexander Feb 14 '18 at 16:40
  • 2
    Note to the non-OPs: Holy hell guys, calm it down a bit. It's a really clear question. Most programming languages (maybe by count, by definitely by use) allow any reference to be null, like in Java, JS, Ruby, Python, C, C#, C++, ObjC, SmallTalk. Asking what the point of an optional is in Swift is a completely reasonable question, if you're coming frmo a world where anything can be null. – Alexander Feb 14 '18 at 16:41
  • @Alexander Now I get it. Thank you: that was the answer I was looking for :) – TheProgrammer Feb 14 '18 at 16:41
  • @TheProgrammer The difference is that a value that can be `nil` (`T?` a.k.a. `Optional`) *is a different type* than a value that can't (`T`). So you can't pass a `T?` where a `T` is expected. You *must* unwrap that `T?` to produce a `T`, and only then can you pass it where a `T` is expected. – Alexander Feb 14 '18 at 16:43
  • Most of this comment discussion involves that link @matt made - https://stackoverflow.com/questions/24003642/what-is-an-optional-value-in-swift - and (at least) from my viewpoint this *discussion* between two obviously good programmers should have been taken to another place a good while back. –  Feb 14 '18 at 16:43
  • Contrast this with other languages, which usually allow *any* reference of type `T` to be null. There's no distinction in the type system between "this is definitely not null" and "this can be null". The mismatch (assuming you have something not-null when it actually is null) is what leads to constant null reference errors. – Alexander Feb 14 '18 at 16:44
  • Furthermore, most languages don't have the same level of support of value types as you do in Swift. You can't have an `int` be `null` in Java without using `Integer`. Of course, this has absolutely crippling performance characteristics in many circumstances (large List are rip), and usually leads people to do crazy shit like "What's the first integer in an empty list? `-1`, obviously!" – Alexander Feb 14 '18 at 16:47
  • @Alexander But this is exactly what my answer said. Yet the OP rejected that. – matt Feb 14 '18 at 16:47
  • *"Holy hell guys, calm it down a bit. It's a really clear question. Most programming languages (maybe by count, by definitely by use) allow any reference to be null, like in Java, JS, Ruby, Python, C, C#, C++, ObjC, SmallTalk. Asking what the point of an optional is in Swift is a completely reasonable question...."* Actually no. It isn't. At least in this site's Q&A. It's opinionated, displays nothing about what the specific issue is, and, well, isn't a good fit for this site. So, "holy hell", I'm downvoting now. (BTW, hell isn't holy - it's the antithesis of that.) –  Feb 14 '18 at 16:47
  • 1
    @dfd The purpose of Optional is no more opinionated than the purpose of any other language feature. What's the purpose of higher level languages if we can just write x86 machine code everywhere? "Well it's easier and helps you write safe code." "Well that's just your opinion." Yes, yes it is. – Alexander Feb 14 '18 at 16:49
  • @matt Your answer was factually correct in explaining what Optionals are. I wanted to know why they exist in the first place. You provided the "what", when I was looking for the "why" :) Hope it helps make things clearer. What do optionals offer to justify their existence ? Answer : "Ever wondered if there was some static, guaranteed way that a compiler can double check that you haven't forgotten to check for null? That's what Optional is" – TheProgrammer Feb 14 '18 at 16:52
  • @Alexander, the purpose of optional isn't opinionated - on that we agree. But the OP? I venture to say at best it's vague and at worst *is* opinionated. Somewhere in between is "argumentative", which a few of the OP's comments clearly are. Optionals *are*. Optionals *exist*. Optionals are part of what makes Swift... well, Swift. What's to argue about? Look at the split in the votes - 3 up, 4 down. That's not because it's asking *what* is an Optional (and it's value in app development), it's because it's *how* the OP is asking - or arguing their point... and that doesn't belong here. –  Feb 14 '18 at 19:15
  • @dfd I just wanted to understand. No opinion there. Have a nice day. – TheProgrammer Feb 15 '18 at 14:59

2 Answers2

8

I think the key distinction is that Optionals allow the type system to express when something might be nil or definitely will not. In Javascript, you have no way of expressing "var x will never be undefined, so no need to add that check everywhere" and similarly, in Javascript, you may have a var that you expect to have a value, and forget to check the possibility that it is undefined in some cases.

Optionals promote this distinction into an actual type in the type system, so the compiler can detect (and warn you) when you are assuming non-nil in contexts where nil is a possibility that must be considered. And similarly, non-optional types can be enforced by the compiler to never be set to a nil value (which would violate assumptions of dependent code expecting a non-nil value).

Put differently, without Optionals, only runtime checks can determine if a value even might be nil (there is no way of knowing). In Swift, with Optionals, the type itself can specify whether nil must be considered or not, and so the compiler can verify safety at build-time, or even as you type.

Daniel Hall
  • 13,457
  • 4
  • 41
  • 37
  • 1
    This was exactly what I was looking for ! Thank you for a clear and concise answer :) – TheProgrammer Feb 14 '18 at 16:47
  • 1
    It's also worth noting that `Optional` extends beyond just references, in that it allows value types (structs, enums, tuples) to be nullable as well, without needing to be boxed, moved to the heap and accessed by a nullable reference – Alexander Feb 14 '18 at 16:51
0

In some languages, such as Objective-C, any object reference can be nil.

Swift is much clearer and safer. In Swift, only an Optional can be nil. Thus, in order for you to be able to check whether something can be nil, that thing must be an Optional first.

You cannot, for example, say:

let s : String = "howdy"
if s == nil {

That won't even compile, because s can never be nil; it's a String, not an Optional. Only an Optional can be nil. That's what an Optional is: it is a thing that can be nil.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • I know. I understand how optionals works in Swift. I just don't understand what they offer compared to simply checking for nil – TheProgrammer Feb 14 '18 at 16:34