What is it about Kotlin's fold that allows me to put the operation function after the closing parentheses? - kotlin

What is it about Iterable.fold(...) in Kotlin that allows me to put the operation function after the closing parentheses?
val numbers = listOf(5, 2, 10, 4)
// operation function passed as the second param of fold
val sumDoubled1 = numbers.fold(0, { sum, n -> sum + n * 2 })
println(sumDoubled1)
// operation function after the closing paren of fold
val sumDoubled2 = numbers.fold(0) { sum, n -> sum + n * 2 }
println(sumDoubled2)

Further to Pavneet's answer, the rationale behind this that it allows you to write what look like language extensions.  For example:
repeat (10) {
// Do something
}
That looks like a new type of loop structure; but it's really just a function called repeat() that takes two parameters; an integer, and a lambda.
Also, if the lambda is the only parameter, you can omit the parens entirely, e.g.:
repeatForever {
// Do something
}
(repeat() is in the standard library; repeatForever() is left as an exercise for the reader :-)
The ability to neaten some inline method calls, such as someValue.takeIf{ it > 0 } is just a nice side-effect of that.

It is called Passing trailing lambdas means, if a methods takes last parameter input as function(aka method literal) then it can be placed outside that method call though you can also place it inside the brackets as well. A simple example would be:
fun main() {
processInput("Lambda", { println(it) })
processInput("Passing trailing lambda") { println(it) }
processInput("Passing trailing lambda with named param") { input -> println(input) }
}
fun processInput(input:String, method:(str:String)->Unit){
method(input.toUpperCase()) // additional logic
}
Output:
LAMBDA
PASSING TRAILING LAMBDA
PASSING TRAILING LAMBDA WITH NAMED PARAM

Related

When is it a block and when is it a lambda?

How does the Kotlin compiler decide whether an expression enclosed in { } is a block or a lambda?
Consider this:
val a: Int
if (cond)
a = 1
else
a = 2
can be written more succinctly as:
val a =
if (cond)
1
else
2
Similarly, one might think that this:
val a: () -> Int
if (cond)
a = { 1 }
else
a = { 2 }
should be able to be written more succinctly like this:
val a =
if (cond)
{ 1 }
else
{ 2 }
But this is not the same: a is now an Int, and not of type () -> Int, because now the { 1 } is no longer a lambda. What are the rules that say whether something is a lambda or a block?
I didn't look into the Kotlin lexer, but I guess there are few possible places in the code where the compiler expects either a single expression or a block of code. That includes the code immediately following most of control flow statements like: if, else, while, when (one of its cases), etc. If you put { in one of these places, it will be interpreted as a start of the block of code related to this control flow statement and not as a lambda.
This is as simple as that. Note that even if you hint the compiler about the type, it still won't work:
// compile error
val a: () -> Int = if (cond)
{ 1 }
else
{ 2 }
It will be interpreted more like this:
// compile error
val a: () -> Int = if (cond) {
1
} else {
2
}
{ after if condition is always interpreted as a start of block of code. You need to put double {, } in cases like this:
// works fine
val a: () -> Int = if (cond) {
{ 1 }
} else {
{ 2 }
}
To put it very succinctly and easy to remember, the first opening brace after an if/when/else/for is always assumed to be the opening of a block. Use double braces if you want a lambda in there.
This is specified in the Kotlin Language Specification, section 1.2: Syntax Grammar:
The grammar defines a block as statements between { and }. In most cases (such as function bodies) the syntax is different between a block and a lambda. Where it is the same is in the usage of controlStructureBody - these are the places where the block has a value, or where you could put a non-block expression in its place. If you search the whole spec document for "controlStructureBody", you'll find it's used in the following places:
For statement
While statement
Do-while statement
If expression
When expression
When entry
In every other place where a value is required, a '{' signifies the start of a lambda.

kotlin object conversion in lambdas convert

I'm trying to have this compiling:
val criteriaList = aList.stream().map { dateRange -> {
Criteria.where("KEY").`is`(dateRange) } }.toList().toTypedArray()
Criteria().orOperator(*criteriaList)
But:
Criteria().orOperator(*criteriaList)
Currently does not compile:
Type mismatch.
Required:
Array<(out) Criteria!>!
Found:
Array<(() → Criteria!)!>
Why?
You are mapping your dateRange to a () -> Criteria.
You do not need to wrap what is following after -> with curly braces. Check also the Kotlin reference regarding Lambda expression syntax:
val sum = { x: Int, y: Int -> x + y }
A lambda expression is always surrounded by curly braces [...], the body goes after an -> sign. If the inferred return type of the lambda is not
Unit, the last (or possibly single) expression inside the lambda body is treated as the return value.
So you could just write the following instead:
.map { dateRange -> Criteria.where("KEY").`is`(dateRange) }
Note also that you do not really need to call stream(), but you can directly call map on it (except it wouldn't be a real List in the first place).
So your code could probably be simplified to something like:
val criteriaList = aList.map { dateRange -> Criteria.where("KEY").`is`(dateRange) }
.toTypedArray()
or
val criteriaList = aList.map { Criteria.where("KEY").`is`(it) }
.toTypedArray()

Kotlin sequence concatenation

val seq1 = sequenceOf(1, 2, 3)
val seq2 = sequenceOf(5, 6, 7)
sequenceOf(seq1, seq2).flatten().forEach { ... }
That's how I'm doing sequence concatenation but I'm worrying that it's actually copying elements, whereas all I need is an iterator that uses elements from the iterables (seq1, seq2) I gave it.
Is there such a function?
Your code doesn't copy the sequence elements, and sequenceOf(seq1, seq2).flatten() actually does what you want: it generates a sequence that takes items first from seq1 and then, when seq1 finishes, from seq2.
Also, operator + is implemented in exactly this way, so you can just use it:
(seq1 + seq2).forEach { ... }
The source of the operator is as expected:
public operator fun <T> Sequence<T>.plus(elements: Sequence<T>): Sequence<T> {
return sequenceOf(this, elements).flatten()
}
You can take a look at the implementation of .flatten() in stdlib that uses FlatteningSequence, which actually switches over the original sequences' iterators. The implementation can change over time, but Sequence is intended to be as lazy as possible, so you can expect it to behave in a similar way.
Example:
val a = generateSequence(0) { it + 1 }
val b = sequenceOf(1, 2, 3)
(a + b).take(3).forEach { println(it) }
Here, copying the first sequence can never succeed since it's infinite, and iterating over (a + b) takes items one by one from a.
Note, however, that .flatten() is implemented in a different way for Iterable, and it does copy the elements. Find more about the differences between Iterable and Sequence here.
Something else you might need to do is create a sequence of sequences:
val xs = sequence {
yield(1)
yield(2)
}
val twoXs = sequence {
yieldAll(xs)
// ... interesting things here ...
yieldAll(xs)
}
This doesn't do anything that xs + xs doesn't do, but it gives you a place to do more complex things.

Objective C ^ Declare block in Swift [duplicate]

I am trying to rewrite from Objective-C to Swift, I cannot work out the syntax or understand the docs
Here is a simplified example in Objective-C I wrote:
[UIView animateWithDuration:10.0 animations:^{self.navigationController.toolbar.frame = CGRectMake(0,10,0,10);}];
How do I write this in Swift?
This is the template autocomplete gives:
UIView.animateWithDuration(duration: NSTimeInterval, animations: (() -> Void))
This is the swift closure format:
{(parameter:type, parameter: type, ...) -> returntype in
//do stuff
}
This is what you should do:
//The animation closure will take no parameters and return void (nothing).
UIView.animateWithDuration(duration: NSTimeInterval, animations: {() -> Void in
//Animate anything.
})
Here is the documentation for closures.
Since the expected argument types and return type to the animations argument are known the compiler can infer them without a problem. This should work (though I don't have the playground available right at the moment:
UIView.animateWithDuration(10.0, animations: {
self.navigationController.toolbar.frame = CGRect(x:0.0, y:10.0, width:10.0, height:0.0)
})
for more info about closures see the chapter in the swift docs
note about CGRect() - the developer docs show CGRect() being used in swift code. Perhaps it requires an import?
update for comments: you can also use a trailing closure like so:
UIView.animateWithDuration(10.0) {
self.navigationController.toolbar.frame = CGRect(x:0.0, y:10.0, width:10.0, height:0.0)
}
Following code can guide to write your own block.
class func testFunc(completion: ((list : NSArray!) -> Void)?) {
//--- block code.
if completion! != nil {
completion! (list: NSArray())
}
}
and you can call it like -
className.testFunc {
(list: NSArray!) -> Void in
}
You can basically write it in 3 identical ways:
write what to do right in the closure/code block:
UIView.animateWithDuration(10.0) {
self.navigationController.toolbar.frame = CGRect(x:0.0, y:10.0, width:10.0, height:0.0)
}
This is also known as trailing closure ( You can only do trailing closure if the closure parameter is the last parameter)
This doesn't mean the parameter 'animations' is no longer written. It is written but just as in the format of above.
Write exactly within the lines, most developers avoid such, because it's a little buggy to write with all the parenthesis and braces.
UIView.animateWithDuration(10.0, animations: {
self.navigationController.toolbar.frame = CGRect(x:0.0, y:10.0, width:10.0, height:0.0)
})
(Contrary to trailing closure you wrote name ie 'animations')
This is known as inline closure
Write in a more modular sense
UIView.animateWithDuration(duration: NSTimeInterval, animations: animatingFunc)
func animatingFunc() {
self.navigationController.toolbar.frame = CGRect(x:0.0, y:10.0, width:10.0, height:0.0)
}
Remember the type of the parameter 'animations' was () -> Void
Exactly as what we are doing, animatingFunc takes no parameters ie '()' and returns nothing ie 'void'
(In Swift, functions are types and can be passed in as parameters)
Some might say this is more readable some might say trailing closure is...
Side note1
You can also do nothing ( which really doesn't make sense but in many other handlers/animations/completion handlers you may not want to do anything)
UIView.animateWithDuration(duration: NSTimeInterval, animations: nil)
Side note2
Closures becomes more interesting when you have to capture a value. See this simple demonstration.
For more information about Swift closures see Apple's Documentation
How Do I Declare a Closure in Swift?
As a variable:
var closureName: (ParameterTypes) -> ReturnType
As an optional variable:
var closureName: ((ParameterTypes) -> ReturnType)?
As a type alias:
typealias ClosureType = (ParameterTypes) -> ReturnType
As a constant:
let closureName: ClosureType = { ... }
As a parameter to another function:
funcName(parameter: (ParameterTypes) -> ReturnType)
Note: if the passed-in closure is going to outlive the scope of the method, e.g. if you are saving it to a property, it needs to be annotated with #escaping.
As an argument to a function call:
funcName({ (ParameterTypes) -> ReturnType in statements })
As a function parameter:
array.sorted(by: { (item1: Int, item2: Int) -> Bool in return item1 < item2 })
As a function parameter with implied types:
array.sorted(by: { (item1, item2) -> Bool in return item1 < item2 })
As a function parameter with implied return type:
array.sorted(by: { (item1, item2) in return item1 < item2 })
As the last function parameter:
array.sorted { (item1, item2) in return item1 < item2 }
As the last parameter, using shorthand argument names:
array.sorted { return $0 < $1 }
As the last parameter, with an implied return value:
array.sorted { $0 < $1 }
As the last parameter, as a reference to an existing function:
array.sorted(by: <)
As a function parameter with explicit capture semantics:
array.sorted(by: { [unowned self] (item1: Int, item2: Int) -> Bool in return item1 < item2 })
As a function parameter with explicit capture semantics and inferred parameters / return type:
array.sorted(by: { [unowned self] in return $0 < $1 })
This site is not intended to be an exhaustive list of all possible uses of closures. ref: http://goshdarnclosuresyntax.com/

How to test a function's output (stdout/stderr) in unit tests

I have a simple function I want to test:
func (t *Thing) print(min_verbosity int, message string) {
if t.verbosity >= minv {
fmt.Print(message)
}
}
But how can I test what the function actually sends to standard output? Test::Output does what I want in Perl. I know I could write all my own boilerplate to do the same in Go (as described here):
orig = os.Stdout
r,w,_ = os.Pipe()
thing.print("Some message")
var buf bytes.Buffer
io.Copy(&buf, r)
w.Close()
os.Stdout = orig
if(buf.String() != "Some message") {
t.Error("Failure!")
}
But that's a lot of extra work for every single test. I'm hoping there's a more standard way, or perhaps an abstraction library to handle this.
One thing to also remember, there's nothing stopping you from writing functions to avoid the boilerplate.
For example I have a command line app that uses log and I wrote this function:
func captureOutput(f func()) string {
var buf bytes.Buffer
log.SetOutput(&buf)
f()
log.SetOutput(os.Stderr)
return buf.String()
}
Then used it like this:
output := captureOutput(func() {
client.RemoveCertificate("www.example.com")
})
assert.Equal(t, "removed certificate www.example.com\n", output)
Using this assert library: http://godoc.org/github.com/stretchr/testify/assert.
You can do one of three things. The first is to use Examples.
The package also runs and verifies example code. Example functions may include a concluding line comment that begins with "Output:" and is compared with the standard output of the function when the tests are run. (The comparison ignores leading and trailing space.) These are examples of an example:
func ExampleHello() {
fmt.Println("hello")
// Output: hello
}
The second (and more appropriate, IMO) is to use fake functions for your IO. In your code you do:
var myPrint = fmt.Print
func (t *Thing) print(min_verbosity int, message string) {
if t.verbosity >= minv {
myPrint(message) // N.B.
}
}
And in your tests:
func init() {
myPrint = fakePrint // fakePrint records everything it's supposed to print.
}
func Test...
The third is to use fmt.Fprintf with an io.Writer that is os.Stdout in production code, but bytes.Buffer in tests.
You could consider adding a return statement to your function to return the string that is actually printed out.
func (t *Thing) print(min_verbosity int, message string) string {
if t.verbosity >= minv {
fmt.Print(message)
return message
}
return ""
}
Now, your test could just check the returned string against an expected string (rather than the print out). Maybe a bit more in-line with Test Driven Development (TDD).
And, in your production code, nothing would need to change, since you don't have to assign the return value of a function if you don't need it.