Why NOT use optionals in Swift? - swift

I was reading up on how to program in Swift, and the concept of optionals bugged me a little bit. Not really in terms of why to use optionals, that makes sense, but more so as to in what case would you not want to use optionals. From what I understand, an optional just allows an object to be set to nil, so why would you not want that feature? Isn't setting an object to nil the way you tell ARC to release an object? And don't most of the functions in Foundation and Cocoa return optionals? So outside of having to type an extra character each time to refer to an object, is there any good reason NOT to use an optional in place of a regular type?

There are tons of reasons to NOT use optional. The main reason: You want to express that a value MUST be available. For example, when you open a file, you want the file name to be a string, not an optional string. Using nil as filename simply makes no sense.
I will consider two main use cases: Function arguments and function return values.
For function arguments, the following holds: If the argument needs to be provided, option should not be used. If handing in nothing is okay and a valid (documented!) input, then hand in an optional.
For function return values returning no optional is especially nice: You promise the caller that he will receive an object, not either an object or nothing. When you do not return an optional, the caller knows that he may use the value right away instead of checking for null first.
For example, consider a factory method. Such method should always return an object, so why should you use optional here? There are a lot of examples like this.
Actually, most APIs should rather use non-optionals instead of optionals. Most of the time, simply passing/receiving possibly nothing is just not what you want. There are rather few cases where nothing is an option.
Each case where optional is used must be thoroughly documented: In which circumstances will a method return nothing? When is it okay to hand nothing to a method and what will the consequences be? A lot of documentation overhead.
Then there is also conciseness: If you use an API that uses optional all over the place, your code will be cluttered with null-checks. Of course, if every use of optional is intentional, then these checks are fine and necessary. However, if the API only uses optional because its author was lazy and was simply using optional all over the place, then the checks are unnecessary and pure boilerplate.
But beware!
My answer may sound as if the concept of optionals is quite crappy. The opposite is true! By having a concept like optionals, the programmer is able to declare whether handing in/returning nothing is okay. The caller of a function is always aware of that and the compiler enforces safety. Compare that to plain old C: You could not declare whether a pointer could be null. You could add documentation comments that state whether it may be null, but such comments were not enforced by the compiler. If the caller forgot to check a return value for null, you received a segfault. With optionals you can be sure that noone dereferences a null pointer anymore.
So in conclusion, a null-safe type system is one of the major advances in modern programming languages.

The original idea of optionals (which existed long before Swift) is to force programmer to check value for nil before using it — or to prevent outside code from passing nil where it is not allowed. A huge part of crashes in software, maybe even most of them, happens at address 0x00000000 (or with NullPointerException, or alike) precisely because it is way too easy to forget about nil-pointer scenario. (In 2009, Tony Hoare apologized for inventing null pointers).
Not using optionals is as valid and widespread use case as using them: when the value absolutely can not be missing, there should be non-optional type; when it can, there should be an optional.
But currently, the existing frameworks are written in Obj-C without optionals in mind, so automatically generated bridges between Swift and Obj-C just have to take and return optionals, because it is impossible to automatically deeply analyze each method and figure out which arguments and return values should be optionals or not. I'm sure over time Apple will manually fix every case where they got it wrong; right now you should not use those frameworks as an example, because they are definitely not a good one. (For good examples, you could check a popular functional language like Haskell which had optionals since the beginning).

Related

Should 'as' keyword be avoided in dart? Should 'dynamic' be used over 'Object'?

Reviewing a question recently but could not post response due to lacking any reputation.
In this question regarding a compiletime error coming from using List<Map<String,Object>> there was a compile time error when trying to pull the value of the Object which was known to be either a String or a Widget.
My resolution was to use as when calling using the values 'as String' or 'as Widget' in the appropriate spots.
Another more elegant solution was to replace 'Object' with 'dynamic'.
I remember reading 'as' was discouraged where possible. I don't know why, and I feel it resolve the issue. Is this simply because it should be cast as a specific type when created?
When trying to recreate in Dartpad I had no issues, potentially just a flutter issue?
Why does dynamic work, but Object doesn't in this scenario? I mean everything will be a subtype of object right?
Thanks,
Can copy and paste code across if required, felt context of attached question was valuable.
I remember reading 'as' was discouraged where possible. I don't know why, and I feel it resolve the issue. Is this simply because it should be cast as a specific type when created? When trying to recreate in Dartpad I had no issues, potentially just a flutter issue?
Explicit type casts are a code smell. They're not necessarily wrong or bad, but they're frequently indicative of APIs that are unnecessarily awkward and perhaps could be designed better to use the correct types in the first place.
Explicit casts are also brittle. They introduce potential runtime failure points. That is, if the actual (runtime) type of the object changed, the cast could fail, and that failure wouldn't be noticed at compilation time.
Why does dynamic work, but Object doesn't in this scenario? I mean everything will be a subtype of object right?
dynamic is a special type that disables static (compile-time) type-checking. Object (like every other non-dynamic type) is statically type-checked, so any methods that you call on it must be statically known to exist on that type.
Note that using dynamic is brittle too since failures involving dynamic types are inherently runtime failures. Using dynamic also can be less readable in general; except when there's some obvious context, readers won't know what type you expect the object to be and therefore won't know what behavior you expect the called method to have.
Also see the Effective Dart recommendation: AVOID using dynamic unless you want to disable static checking.

Does Swift have an equivalent to Rust's `uninitialized`?

The Rust standard library has the std::mem::uninitialized function, which allows you to manually create an undefined (and possible invalid) value of any type. This essentially maps to LLVM's undef. I was wondering if Swift had an equivalent, as I haven't been able to find one skimming through the standard library documentation.
Motivation
The primary use for this is to bypass the compiler's normal memory initialization checks when they prove imprecise. For instance, you might want to initialize some members of a structure using methods (or in Swift's case, property setters), which the compiler usually would not allow you to do. Using dummy values works, but that's potentially less efficient (if the optimizer cannot prove that the dummy is meaningless).
In Rust, uninitialized values are treated as initialized by the initialization checker, but as uninitialized by LLVM, leading to more reliable optimization. Since the Swift compiler is also built atop LLVM, it seems like something the Swift compiler should also be able to support.
My Specific Use Case
I have a struct which encapsulates a set of bit fields compacted into one machine word (an unsigned integer type). The struct type provides a safe and convenient interface for reading and modifying the individual fields, through computed properties.
I also have an initializer that takes the relevant field values as parameters. I could initialize the underlying machine word using the same bitwise operations that the computed properties use (in which case I would be repeating myself), or I could initialize it simply by setting the values of the computed properties.
Currently, Swift does not support using computed properties before self has been fully initialized. It's also unlikely Swift will ever support this case, since the computed property setters modify the existing machine word, which would require it to already be initialized, at least as far as Swift is concerned. Only I know that all my setters, in concert, will fully initialize that machine word.
My current solution is to simply initialize the machine word to 0, and then run the setters. Since a constant 0 is trivially absorbed into the bitwise | chain that combines the fields, there's no CPU time lost, but that's always going to be the case. This is the kind of situation where, in Rust, I would have used an uninitialized value to express my intent to the optimizer.

Where to define typecast to struct in MATLAB OOP?

In the MATLAB OOP framework, it can be useful to cast an object to a struct, i.e., define a function that takes an object and returns a struct with equivalent fields.
What is the appropriate place to do this? I can think of several options:
Build a separate converter object that takes care of conversions between various classes
Add a function struct to the class that does the conversion to struct, and make the constructor accept structs
Neither option seems to be very elegant: the first means that logic about the class itself is moved to another class. On the other hand, in the second case, it provokes users to use the struct function for any object, which will in general give a warning (structOnObject).
Are there altenatives?
Personally I'd go with the second option, and not worry about provoking users to call struct on other classes; you can only worry about your own code, not that of a third-party, even if the third party is MathWorks. In any case, if they do start to call struct on an arbitrary class, it's only a warning; nothing actually dangerous is likely to happen, it's just not a good practice.
But if you're concerned about that, you can always call your converter method toStruct rather than struct. Or perhaps the best (although slightly more complex) way might be to overload cast for your class, accepting and handling the option 'struct', and passing any other option through to builtin('cast',....
PS The title of your question refers to typecasting, but what your after here is casting. In MATLAB, typecasting is a different operation, involving taking the exact bits of one type and reinterpreting them as bits of another type (possibly an array of the output type). See doc cast and doc typecast for more information on the distinction.
The second option sounds much better to me.
A quick and dirty way to get rid of the warning would be disabling it by calling
warning('off', 'MATLAB:structOnObject')
at the start of your program.
The solutions provided in Sam Roberts' answer are however much cleaner. I personally would go for the toStruct() method.

self. in trailing swift closures, meaning and purpose?

whenever I use a trailing closure on an action ... example:
run(SKAction.wait(forDuration: 10)){timeRemains = false}
I’m seeing this:
Reference to property (anything) in closure requires explicitly ‘self’
to make capture semantics explicit.
What does this mean? And what is it on about? I'm curious because I'm only ever doing this in the context/scope of the property or function I want to call in the trailing closure, so don't know why I need `self and fascinated by the use of the word
"semantics"
here. Does it have some profound meaning, and will I magically understand closures if I understand this?
Does it have some profound meaning, and will I magically understand closures if I understand this?
No and no. Or perhaps, maybe and maybe.
The reason for this syntactical demand is that this might really be a closure, that is, it might capture and preserve its referenced environment (because the anonymous function you are passing might be stored somewhere for a while). That means that if you refer here to some property of self, such as myProperty, you are in fact capturing a reference to self. Swift demands that you acknowledge this fact explicitly (by saying self.myProperty, not merely myProperty) so that you understand that this is what's happening.
Why do you need to understand it? Because under some circumstances you can end up with a retain cycle, or in some other way preserving the life of self in ways that you didn't expect. This is a way of getting you to think about that fact.
(If it is known that this particular function will not act as a closure, i.e. that it will be executed immediately, then there is no such danger and Swift will not demand that you say self explicitly.)

Why to use empty parentheses in Scala if we can just use no parentheses to define a function which does not need any arguments?

As far as I understand, in Scala we can define a function with no parameters either by using empty parentheses after its name, or no parentheses at all, and these two definitions are not synonyms. What is the purpose of distinguishing these 2 syntaxes and when should I better use one instead of another?
It's mostly a question of convention. Methods with empty parameter lists are, by convention, evaluated for their side-effects. Methods without parameters are assumed to be side-effect free. That's the convention.
Scala Style Guide says to omit parentheses only when the method being called has no side-effects:
http://docs.scala-lang.org/style/method-invocation.html
Other answers are great, but I also think it's worth mentioning that no-param methods allow for nice access to a classes fields, like so:
person.name
Because of parameterless methods, you could easily write a method to intercept reads (or writes) to the 'name' field without breaking calling code, like so
def name = { log("Accessing name!"); _name }
This is called the Uniform Access Principal
I have another light to bring to the usefulness of the convention encouraging an empty parentheses block in the declaration of functions (and thus later in calls to them) with side effects.
It is with the debugger.
If one add a watch in a debugger, such as, say, process referring for the example to a boolean in the focused debug context, either as a variable view, or as a pure side-effect free function evaluation, it creates a nasty risk for your later troubleshooting.
Indeed, if the debugger keeps that watch as a try-to-evaluate thing whenever you change the context (change thread, move in the call stack, reach another breakpoint...), which I found to be at least the case with IntelliJ IDEA, or Visual Studio for other languages, then the side-effects of any other process function possibly found in any browsed scope would be triggered...
Just imagine the kind of puzzling troubleshooting this could lead to if you do not have that warning just in mind, because of some innocent regular naming. If the convention were enforced, with my example, the process boolean evaluation would never fall back to a process() function call in the debugger watches; it might just be allowed in your debugger to explicitly access the () function putting process() in the watches, but then it would be clear you are not directly accessing any attribute or local variables, and fallbacks to other process() functions in other browsed scopes, if maybe unlucky, would at the very least be very less surprising.