Variable capture by closures in Swift and inout parameters - cocoa

I noticed that when a variable is captured by a closure in Swift, the closure can actually modify the value. This seems crazy to me and an excellent way of getting horrendous bugs, specially when the same var is captured by several closures.
var capture = "Hello captured"
func g(){
// this shouldn't be possible!
capture = capture + "!"
}
g()
capture
On the other hand, there's the inout parameters, which allow a function or closure to modify its parameters.
What's the need for inout, even captured variables can already be modified with impunity??!!
Just trying to understand the design decisions behind this...

Variables from an outer scope that are captured aren't parameters to the routine, hence their mutablility is inherited from context. By default actual parameters to a routine are constant (let) and hence can't be modified locally (and their value isn't returned)
Also note that your example isn't really capturing capture since it's a global variable.
var global = "Global"
func function(nonmutable:Int, var mutable:Int, inout returnable:Int) -> Void {
// global can be modified here because it's a global (not captured!)
global = "Global 2"
// nomutable can't be modified
// nonmutable = 3
// mutable can be modified, but it's caller won't see the change
mutable = 4
// returnable can be modified, and it's caller sees the change
returnable = 5
}
var nonmutable = 1
var mutable = 2
var output = 3
function(nonmutable, mutable, &output)
println("nonmutable = \(nonmutable)")
println("mutable = \(mutable)")
println("output = \(output)")
Also, as you can see, the inout parameter is passed differently so that it's obvious that on return, the value may be different.

David's answer is totally correct, but I thought I'd give an example how capture actually works as well:
func captureMe() -> (String) -> () {
// v~~~ This will get 'captured' by the closure that is returned:
var capturedString = "captured"
return {
// The closure that is returned will print the old value,
// assign a new value to 'capturedString', and then
// print the new value as well:
println("Old value: \(capturedString)")
capturedString = $0
println("New value: \(capturedString)")
}
}
let test1 = captureMe() // Output: Old value: captured
println(test1("altered")) // New value: altered
// But each new time that 'captureMe()' is called, a new instance
// of 'capturedString' is created with the same initial value:
let test2 = captureMe() // Output: Old value: captured
println(test2("altered again...")) // New value: altered again...
// Old value will always start out as "captured" for every
// new function that captureMe() returns.
The upshot of that is that you don't have to worry about the closure altering the captured value - yes, it can alter it, but only for that particular instance of the returned closure. All other instances of the returned closure will get their own, independent copy of the captured value that they, and only they, can alter.

Here are a couple of use cases for closures capturing variables outside their local context, that may help see why this feature is useful:
Suppose you want to filter duplicates out of an array. There’s a filter function that takes a filtering predicate and returns a new array of only entries matching that predicate. But how to pass the state of which entries have already been seen and are thus duplicates? You’d need the predicate to keep state between calls – and you can do this by having the predicate capture a variable that holds that state:
func removeDupes<T: Hashable>(source: [T]) -> [T] {
// “seen” is a dictionary used to track duplicates
var seen: [T:Bool] = [:]
return source.filter { // brace marks the start of a closure expression
// the closure captures the dictionary and updates it
seen.updateValue(true, forKey: $0) == nil
}
}
// prints [1,2,3,4]
removeDupes([1,2,3,1,1,2,4])
It’s true that you could replicate this functionality with a filter function that also took an inout argument – but it would be hard to write something so generic yet flexible as the possibilities with closures. (you could do this kind of filter with reduce instead of filter, since reduce passes state from call to call – but the filter version is probably clearer)
There is a GeneratorOf struct in the standard library that makes it very easy to whip up sequence generators of various kinds. You initialize it with a closure, and that closure can capture variables to use for the state of the generator.
Suppose you want a generator that serves up a random ascending sequence of m numbers from a range 0 to n. Here’s how to do that with GeneratorOf:
import Darwin
func randomGeneratorOf(#n: Int, #from: Int) -> GeneratorOf<Int> {
// state variable to capture in the closure
var select = UInt32(n)
var remaining = UInt32(from)
var i = 0
return GeneratorOf {
while i < from {
if arc4random_uniform(remaining) < select {
--select
--remaining
return i++
}
else {
--remaining
++i
}
}
// returning nil marks the end of the sequence
return nil
}
}
var g = randomGeneratorOf(n: 5, from: 20)
// prints 5 random numbers in 0..<20
println(",".join(map(g,toString)))
Again, it’s possible to do this kind of thing without closures – in languages without them, you’d probably have a generator protocol/interface and create an object that held state and had a method that served up values. But closure expressions allow a flexible way to do this with minimal boiler plate.

A closure being able to modify the captured variable in the outer scope is pretty common across languages. This is the default behavior in C#, JavaScript, Perl, PHP, Ruby, Common Lisp, Scheme, Smalltalk, and many others. This is also the behavior in Objective-C if the outer variable is __block, in Python 3 if the outer variable is nonlocal, in C++ if the outer variable is captured with &

Related

RxSwift: Convert Observable to a Variable

How do I convert an Observable of type Int to a Variable of type Int?
Here is what I have tried so far:
let obs: Observable<Int> = Observable.of(4)
let variable: Variable<Int> = obs
.flatMap { num in
return Variable<Int>(num)
}
Using flatMap feels like the most logical way of doing the conversion, however, I get a compiler error which essentially says that it does not like the flatMap returning anything that is not an observable. Any ideas?
EDIT:
Just to give some context as to why I need to convert the Observable into a Variable:
I need my viewModel to drive a UIPickerView inside a ViewController. Currently, I have two exposed properties in my ViewModel, items: Observable<[String]> (which is the datasource for the UIPickerView) and selectedIndex: Variable. The selectedIndex will drive the initial value of the UIPickerView but also keep track of any changes the user makes.
The reason I needed to convert from the Observable to Variable was that I needed to figure out which index of the UIPickerView should be selected initially:
items.map { days -> Int in
if let index = days.index(where: { str in
return str == selectedDay
}) {
return index
}
return 0
}
.flatMap { num in
return Variable<Int>(num)
}
I'm now wondering if I'm over complicating things, and if instead of the Variable in I should just have an Observable.
A few points here:
First, You should not use Variable as it's deprecated (gonna be entirely deprecated in Swift 5 probably). Look at BehaviorSubject and BehaviorRelay instead.
About your question, I'm not sure what is the use case for having a Variable equal to an Observable, so there are two different thoughts I have:
You can bind an Observable to a Variable/Subject/Relay (e.g. observable.bind(to: variable))
You can actually go the other way around an get an Observable from the Variable, which might make more sense. e.g. variable.asObservable()

How to provide optional parameters in Go?

I'm coming from a Node.js background, and there a typical pattern is to have a function which takes an options object, i.e. an object where you set properties for optional parameters, such as:
foo({
bar: 23,
baz: 42
});
This is JavaScript's "equivalent" to optional and named parameters.
Now I have learnt that there are no optional parameters in Go, except variadic parameters, but they lack the readability of named parameters. So the usual pattern seems to be to hand over a struct.
OTOH a struct can not be defined with default values, so I need a function to set up the struct.
So I end up with:
Call a function that creates the struct and then fills it with default values.
Overwrite the values I would like to change.
Call the function I actually want to call and hand over the struct.
That's quite complicated and lengthy compared to JavaScript's solution.
Is this actually the idiomatic way of dealing with optional and named parameters in Go, or is there a simpler version?
Is there any way that you can take advantage of zero values? All data types get initialized to a zero value, so that is a form of default logic.
An options object is a pretty common idiom. The etcd client library has some examples (SetOptions,GetOptions,DeleteOptions) similar to the following.
type MyOptions struct {
Field1 int // zero value (default) of int is 0
Field2 string // zero value (default) of string is ""
}
func DoAction(arg1, arg2 string, options *MyOptions){
var defaultValue1 int = 30 // some reasonable default
var defaultValue2 string = "west" // some reasonable default
if options != nil {
defaultValue1 = options.Field1 // override with our values
defaultValue2 = options.Field2
}
doStuffWithValues
An relevant question (and very much in the mindset of Go) would be, do you need this kind of complexity? The flexibility is nice, but most things in the standard library try to only deal with 1 default piece of info/logic at a time to avoid this.

Iterating over a collection in Swift: var vs. let

I have a method that iterates over an array and call other method with every element as argument. If I declare this method as:
func didFinishedListFiles(files: [FileModel]) {
for var fileData in files {
self.downloadSingleFile(NSUUID(UUIDString: fileData.uuid!)!);
}
}
Xcode shows a warning:
Variable 'fileData' was never mutated; consider changing to 'let' constant
But if I change var to let:
func didFinishedListFiles(files: [FileModel]) {
for let fileData in files {
self.downloadSingleFile(NSUUID(UUIDString: fileData.uuid!)!);
}
}
Xcode shows an error:
'let' pattern cannot appear nested in an already immutable context
How is a correct way to implement it without any warnings/errors?
The for-in pattern implicitly uses a constant binding (in the scope it creates. That is, your fileData binding is automatically a local let, and therefore constant for each pass through the loop.
So the following:
for fileData in files { /*...*/ }
...is equivalent to :
var index = 0
while index < files.count {
let fileData = files[index]
//...
index += 1
}
You'd want to add var to the for-in binding only when you want to mutate that binding -- that is, if it's an object reference that you want to be able to point at something else during a single pass through the loop, or a value type that you want to be able to change. But it doesn't look like you're doing either of those things, so using var for this binding would be superfluous here.
(Swift 3 got rid of a lot of the places where you could make implicitly immutable bindings mutable, but left for var as an exception — it's still possible if you want to change something during a loop.)

RXjs : How to create an operator on streams : scan operator where the accumulator state can be reset through an observable

I need to create a new instance operator on streams with the following characteristics
Signature
Rx.Observable.prototype.scan_with_reset(accumulator, seed$)
where :
Arguments
accumulator (Function): An accumulator function to be invoked on each element.
seed$ (Observable) : An observable whose values will be used to restart the accumulator function. The accumulator function has the following signature function accumulator_fn(accumulator_state, source_value). I want the value in seed$ to reset accumulator_state to the seed value and emit the seed value.
Returns
(Observable) : An observable sequence which results from the comonadic bind operation (whatever that means, I am copying Rxjs documentation here). Vs. the normal scan operator, what happens here is that when the accumulator function is 'restarted' from the seed value emitted by the seed$ observable, that seed value is emitted, and the next value to be emitted by the scan_with_reset operator will be accumulator_fn(seed, source_value)
Example of use :
var seed$ = Rx.Observable.fromEvent(document, 'keydown')
.map(function(ev){return ev.keyCode})
.startWith(0);
var result$ = counter$.scan_with_reset(seed$,
function accumulator_fn (acc, counter) {return acc+counter});
The following diagrams should explain more in details the expected results:
seed : 0---------13--------27------------
counter : -1--5--2----6---2-----4---1---3---
result : 0-1--6--8-13-19--21-27-31--32--35-
My initial attempt to do this was to modify the accumulator_fn to have the seed$ modify a variable that would in the scope of accumulator_fn so I can detect changes in the function itself.
I pursue two goals here:
have an implementation which is as stateless and closure-less as possible
understand the mechanics behind defining one's own operators on
streams, of which this would be hopefully a simple example
I had a look at scan source code : https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/scan.js
but I am not sure where to go from there.
Does anybody has any experience in creating Rxjs stream operators? What are the conventions to follow and traps to avoid? Are there any examples of custom-made operators that I could look at? How would you go about implementing this particular one?
[UPDATE] : Some test code for the accepted answer
var seed$ = Rx.Observable.fromEvent(document, 'keydown')
.map(function(ev){return ev.keyCode})
.startWith(0);
var counter$ = Rx.Observable.fromEvent(document, 'mousemove')
.map(function(ev){return 1});
var result$ = counter$.scanWithReset(seed$,
function accumulator_fn (acc, counter) {return acc+counter});
var s = function (x) {console.log("value: ", x)};
var disposable = result$.subscribe(s)
Moving the mouse should show a value increase by 1, and pressing a key should restart the counter with the value of the key pressed.
As a general case when creating operators it is generally easiest to use the Observable.create method which essentially defines how your Observable should behave when it is subscribed to or just wrap an existing set of operators ala share.
When you get more into performance there are some other considerations (Observable.create is not terribly efficient at scale) and you could look into creating a custom Observable like map.
For your case I would recommend the former for right now. I would think of your problem really as several independent streams that we would like to flatten into a single stream. Each new stream will start when reset is triggered. This is really sounding an awful lot like flatMap to me:
Rx.Observable.prototype.scanWithReset = function ($reset, accum, seed) {
var source = this;
//Creates a new Observable
return Rx.Observable.create(function (observer) {
//We will be reusing this source so we want to make sure it is shared
var p = source.publish();
var r = $reset
//Make sure the seed is added first
.startWith(seed)
//This will switch to a new sequence with the associated value
//every time $reset fires
.flatMapLatest(function (resetValue) {
//Perform the scan with the latest value
return source.scan(accum, resetValue);
});
//Make sure every thing gets cleaned up
return new Rx.CompositeDisposable(
r.subscribe(observer),
//We are ready to start receiving from our source
p.connect());
});
}

How do I downsample a control rate variable to a scalar value?

In SuperCollider: How do I downsample a control rate variable to a scalar value?
For instance, I have a scalar global called ~delay and a few functions care about that value. They assume it is a scalar. I wanted to set a envelope generator on that variable in order to change it via a control rate variable. Or use MouseX.kr, if I could convert a single value of MouseX.kr to a scalar value I would be happy.
Assume that I cannot refactor the code to allow for a k-rate global and thus I need to sample or downsample a single value from a control rate variable.
I can't do this:
MouseX.kr(1, 4, 1).rand.wait;
But I'd be happy with this:
downSample(MouseX.kr(1, 4, 1)).rand.wait;
Or
~mousex = MouseX.kr(1, 4, 1)
...
downSample(~mousex).rand.wait
This is the classic SuperCollider language-vs-server issue. You want to use MouseX (which represents the server's knowledge of mouse position) in a language-side calculation. ("Why the split? Why can't the language know it using the same object?" - well, imagine the two processes are running on different machines - different mice...)
To get the mouse position in the language, it's better to use one of:
Platform.getMouseCoords // SC up to 3.6
GUI.cursorPosition // SC recent versions
If you're sure you want to use server data in the language, then your own answer about sending via a Bus is one way to do it. Recent versions of SuperCollider have methods
Bus.getSynchronous
Bus.setSynchronous
which rely on the new "shared memory interface" between language and server. If the two are on the same machine, then this can be a nice way to do it which avoids the latency of asynchronously requesting the info.
After much research I came up with 1 solution: use a control Bus to grab values. We take a function as input (f) and then play it to a bus.
We then read from that bus by calling the get method on the bus and providing function that allows us to extract the value from the function thrown in.
~mkscalarfun = {
arg f={ 0 };
var last = 0.0;
var mbus = Bus.control(s, 1);
var pf = f.play(s,mbus);
var scalarf = {
mbus.get({|v| last = v;});
last;
};
scalarf; // This is a function
};
// Create a closure that includes the bus
~mousescalarf = ~mkscalarfun.({ MouseX.kr(1, 4, 1); });
~mousescalarf.();
~mousescalarf.().rand.wait;
I am not sure how idiomatic this solution or if it is appropriate or how well it performs.
One problem with this solution is that pf is hidden and thus you can't stop it.
One alternative is to use an OO solution where you make a class in your extension directory:
MakeScalarKR {
var last;
var mbus;
var pf;
var f;
*new { arg sbase,f;
^super.new.init(sbase,f)
}
init {
arg sbase,myf;
f = myf;
last = 0.0;
mbus = Bus.control(sbase, 1);
pf = f.play(sbase, mbus);
}
v {
mbus.get({|x| last=x;});
^last
}
free {
pf.free
}
}
Then you can invoke this class like so:
~mkr = MakeScalarKR(s,{ MouseX.kr(10,400,1) });
~mkr.v()

Resources