Odd Shortened Syntax for Closures in Swift? - ios

I'm trying to fully wrap my head around closures in Swift. I think I understand the basics. However, I ran into some odd syntax and would appreciate if someone can understand what it means.
I'm going to show the shortened syntax that I came across, but first I'll show how I would write this code without the shortned syntax. I think I understand everything that's going on in the following code, but I'll narrate it just to make sure :)
//function
func manipulate(numbers: [Int], using algorithm: (Int) -> Int){
for number in numbers{
let result = algorithm(number)
print("Manipulating \(number) produced \(result)")
}
}
//trailing closure syntax
manipulate(numbers: [1,2,3]){(number: Int) -> Int in
return number * number
}
Okay, so we're basically declaring a function called manipulate that takes 2 parameters. One of these parameters is numbers and it is an array of Ints. The second parameter, known as using externally and algorithm internally is a closure, which takes an Int as a parameter, and returns an Int.
Okay cool, the function then goes through all the numbers in the array numbers and applies the result of calling the closure, algorithm on each number.
Okay, so that's what the function does, now, let's call it with trailing closure syntax.
What I did was call the function, manipulate and pass in the first parameter, numbers, and then, going by the trailing closure syntax, defined the closure that I'm going to be using. It's taking a parameter, which I called number, that is an Int, and it's returning another Int, number * number.
This code makes perfect sense to me.
Here's the variant that tripped me up. The definition of the function was exactly the same, but, the function was called in a way that I don't understand.
//function
func manipulate(numbers: [Int], using algorithm: (Int) -> Int){
for number in numbers{
let result = algorithm(number)
print("Manipulating \(number) produced \(result)")
}
}
//trailing closure syntax
manipulate(numbers: [1,2,3]){ number in
number * number
}
First of all, we're not specifying the type of the parameter that the closure takes, and we're also not specifying the type of the return value. Also, what does number even mean in this context when we're calling the function?
I'd appreciate it if someone could explain what's going on here. I'm pretty sure it's some idiomatic syntax in Swift, but I don't quite understand it.
Thanks!

Related

How to create Compiler warning for my function in Swift

I want to validate my inputs to function with some conditions and show as a compiler warning/error.
How it is possible?
For example:
func getPoints(start: Int, end: Int) {
}
I want to show compiler warning/error when someone tries to give input high for start than end.
getPoints(start: 3, end: 10) // No warnings
getPoints(start: 6, end: 2) // Compiler warning like: end value can not be less than start value
Actually this is for a framework purpose. I want to ensure that the parameters are not bad inputs.
Such a constraint can't be enforced at compile time. Take Range for example, which enforces that the lowerBound always compares as less or equal to the upperBound. That's just an assertion that runs at run-time, and crashes if it's not met.
I would suggest you just change your API design to use a Range<Int> or ClosedRange<Int> taking pairs of Ints to model ranges is a bad idea, for many reasons:
It doesn't communicate the semantics of a range. Two integers could be anything, but a range is something much more specific.
It doesn't have any of the useful methods, like contains(_:), or support for pattern matching via the ~= operator.
Its error prone, because when passing pairs around, you might make a copy/paste error leading you to accidentally use the same param twice.
It reads better: getPoint(3...10)
You can't generate a warning at compile time, since the arguments are not evaluated beyond checking for type conformance.
In your example, you have used constants, so it would, in theory, be possible to perform the check you want, but what if you passed a variable, or the result of another function? How much of your code would the compiler need to execute in order to perform the check?
You need to enforce your requirements at run time. For example, you could have your function throw if the parameters were incorrect:
enum MyErrors: Error {
case rangeError
}
func getPoints(start: Int, end: Int) throws {
guard start <= end else {
throw MyErrors.rangeError
}
...
}
Or you could have the function simply handle the problem:
func getPoints(start: Int, end: Int) {
let beginning = min(start,end)
let ending = max(start,end)
...
}
Also, I recommend Alexander's suggestion of using Range instead of Int; it is always a good idea to take advantage of Foundation types, but I will leave my answer as it shows some approaches for handling issues at runtime.

Is there a difference between slicing and an explicit reborrow when converting Strings to &strs?

Are the following two examples equivalent?
Example 1:
let x = String::new();
let y = &x[..];
Example 2:
let x = String::new();
let y = &*x;
Is one more efficient than the other or are they basically the same?
In the case of String and Vec, they do the same thing. In general, however, they aren't quite equivalent.
First, you have to understand Deref. This trait is implemented in cases where a type is logically "wrapping" some lower-level, simpler value. For example, all of the "smart pointer" types (Box, Rc, Arc) implement Deref to give you access to their contents.
It is also implemented for String and Vec: String "derefs" to the simpler str, Vec<T> derefs to the simpler [T].
Writing *s is just manually invoking Deref::deref to turn s into its "simpler form". It is almost always written &*s, however: although the Deref::deref signature says it returns a borrowed pointer (&Target), the compiler inserts a second automatic deref. This is so that, for example, { let x = Box::new(42i32); *x } results in an i32 rather than a &i32.
So &*s is really just shorthand for Deref::deref(&s).
s[..] is syntactic sugar for s.index(RangeFull), implemented by the Index trait. This means to slice the "whole range" of the thing being indexed; for both String and Vec, this gives you a slice of the entire contents. Again, the result is technically a borrowed pointer, but Rust auto-derefs this one as well, so it's also almost always written &s[..].
So what's the difference? Hold that thought; let's talk about Deref chaining.
To take a specific example, because you can view a String as a str, it would be really helpful to have all the methods available on strs automatically available on Strings as well. Rather than inheritance, Rust does this by Deref chaining.
The way it works is that when you ask for a particular method on a value, Rust first looks at the methods defined for that specific type. Let's say it doesn't find the method you asked for; before giving up, Rust will check for a Deref implementation. If it finds one, it invokes it and then tries again.
This means that when you call s.chars() where s is a String, what's actually happening is that you're calling s.deref().chars(), because String doesn't have a method called chars, but str does (scroll up to see that String only gets this method because it implements Deref<Target=str>).
Getting back to the original question, the difference between &*s and &s[..] is in what happens when s is not just String or Vec<T>. Let's take a few examples:
s: String; &*s: &str, &s[..]: &str.
s: &String: &*s: &String, &s[..]: &str.
s: Box<String>: &*s: &String, &s[..]: &str.
s: Box<Rc<&String>>: &*s: &Rc<&String>, &s[..]: &str.
&*s only ever peels away one layer of indirection. &s[..] peels away all of them. This is because none of Box, Rc, &, etc. implement the Index trait, so Deref chaining causes the call to s.index(RangeFull) to chain through all those intermediate layers.
Which one should you use? Whichever you want. Use &*s (or &**s, or &***s) if you want to control exactly how many layers of indirection you want to strip off. Use &s[..] if you want to strip them all off and just get at the innermost representation of the value.
Or, you can do what I do and use &*s because it reads left-to-right, whereas &s[..] reads left-to-right-to-left-again and that annoys me. :)
Addendum
There's the related concept of Deref coercions.
There's also DerefMut and IndexMut which do all of the above, but for &mut instead of &.
They are completely the same for String and Vec.
The [..] syntax results in a call to Index<RangeFull>::index() and it's not just sugar for [0..collection.len()]. The latter would introduce the cost of bound checking. Gladly this is not the case in Rust so they both are equally fast.
Relevant code:
index of String
deref of String
index of Vec (just returns self which triggers the deref coercion thus executes exactly the same code as just deref)
deref of Vec

How to return a single value with edge cases in Swift?

Should I return a optional value like:
func someFunc(#num: Int) -> Obj? {
if num < 0 {
return nil
}
...
}
Or just use assert:
func someFunc(#num: Int) -> Obj {
assert(num >= 0, "Number should greater or equal then zero")
...
}
Edit: Now the conditions are identical in two cases, the number should greater or equal then 0. Negative values are not permitted.
If you use assert and the caller passes an invalid argument it is a non-recoverable error/crash. The caller may not be aware of all the ways the assert may be caused, that is internal logic the caller is not supposed to know.
Really the only time assert is meaningful is to check the calling arguments on method entry and even in that case it must be made clear to the user exactly what is invalid and that can never be made more stringent for the life of the method.
Since this is about Swift returning an Optional seems to make the most sense and it will be clear to the caller that a possible error must be handled. Optionals are a major feature of Swift, use them.
Or always return a useful result the way atan() handles being called with ±0 and ±Inf.
It depends on what you want the precondition of the function to be: if it is an error call it with a negative value (or non-positive; your two examples are contradictory), then go with the assert and document this. Then it becomes part of the contract that the user of the function must check the value if it's uncertain. Or if it makes more sense to support these values and return nil (e.g., the function will typically be called with such values and the nil is not an issue for that typical use), do that instead… Without knowing the details it's impossible to tell which suits best, but my guess would be the former.

Erlang function with number for parameter

Hi I'm learning Erlang via Learn You Some Erlang by Fred Hebert.
And I've come across a code that I'm confuse about:
sword(1) -> throw(slice);
sword(2) -> erlang:error(cut_arm);
sword(3) -> exit(cut_leg);
sword(4) -> throw(punch);
sword(5) -> exit(cross_bridge).
talk() -> "blah blah".
black_knight(Attack) when is_function(Attack, 0) ->
try Attack() of
_ -> "None shall pass."
catch
throw:slice -> "It is but a scratch.";
error:cut_arm -> "I've had worse.";
exit:cut_leg -> "Come on you pansy!";
_:_ -> "Just a flesh wound."
end.
So here's the confusion. I don't understand sword(#) function. Why are there number as parameter? The function is_function actually check if these function are of arity 0 and apparently all the sword(#) functions are of arity 0.
Also the way to pass in the sword(#) function to the black_knight function is different compare to the talk function.
Here's how the book pass a sword function and the talk function.
exceptions:black_knight(fun exceptions:talk/0).
vs
exceptions:black_knight(fun() -> exceptions:sword(1) end).
The talk function we just pass the function where as the sword(1) function we have to wrap it with a anonymous function. I don't get it.
So the questions are:
Why is passing these sword(#) different from talk function.
Why sword(#) have a number as a parameter?
Why sword(#) have 0 arity when it seems like it have an arity of 1 (I'm counting the number parameter as a parameter)?
The chapter of the book I'm at.
Thank you for your time.
If you look at the guard statement for the black_knight function, is_function(Attack, 0), it will only match the definition if the function passed in takes 0 parameters. Since talk takes 0 parameters, it can be passed in directly. sword takes one parameter, so you need to wrap it in an anonymous function that takes 0 parameters before you can pass it in.
The number in the definition of each clause is an example of pattern matching. If you call sword with 1 as the argument, you will execute the code in the clause sword(1) ->. If you pass in 2 as the argument, you will execute the clause sword(2) ->. See this section in Learn You Some Erlang for a more complete description.
sword does have an arity of 1, so you were counting parameters correctly.
The purpose of the sword function is to show off different kinds of errors that can be thrown. It accepts a parameter so it can have more than one clause. Fred probably chose integers because they are short, but that doesn't really matter.
The sword function really has an arity of one.
The black_knight/1 function is supposed to show you how to catch the different error classes that exist in Erlang. It does this by calling the zero-arity function that is passed into it and providing a different response for different errors it might throw.
sword/1 is passed into black_knight/1 using an anonymous function
because black_knight/1 only accepts functions of arity zero.
The anonymous function that is created by
fun () -> sword(1) end
is a function of arity zero that calls sword/1 with one argument.
talk/0 can be passed directly because it already is a zero arity function.

Custom Array Functions in Open Office Calc

Could someone please tell me how to write a custom function in Open Office Basic to be used in Open Office Calc and that returns an array of values. An example of one such built-in function is MINVERSE. I need to write a custom function that populates a range of cells in much the same way.
Help would be much appreciated.
Yay, I just figured it out: all you do is return an array from your macro, BUT you also have to press Ctrl+Shift+Enter when typing in the cell formula to call your function (which is also the case when working with other arrays in calc). Here's an example:
Function MakeArray
Dim ret(2,2)
ret(0,0) = 1
ret(1,0) = 2
ret(0,1) = 3
ret(1,1) = 4
MakeArray = ret
End Function
FWIW, damjan's MakeArray function returns a Variant containing an array, I think. (The type returned by MakeArray is unspecified, so it defaults to Variant. A Variant is a container with a descriptive header, apparently cast as needed by the interpreter.)
Almost, but not quite, the same thing as returning an array. According to http://www.cpearson.com/excel/passingandreturningarrays.htm, Microsoft did not introduce the ability to return an array until 2000. His example [ LoadNumbers(Low As Long, High As Long) As Long()] does not compile in OO, flagging a syntax error on the parens following Long. It appears that OO's Basic emulates the pre-2k VBA.

Resources