News for hackers. Stuff that matters.
Re:Fun with Swift by coldtea on Monday January 04, 2016 @11:47AM (#10836598)
>Which to my mind is horrendous. The closure f does not capture the value of i at the time when f is defined, changing i after f was defined make nonsense of the idea of a closure.

Of course it should change i after the closure was defined, since the closure doesn't copy but refer to that i.

Looks like a fully proper closure.

Which language does this differently?

Re:Fun with Swift by hellofunk on Monday January 04, 2016 @11:52AM (#10836645)
The problem is that closures don't usually refer to mutable entities, and most functional programmers are used to an immutable language. The idea that a closure itself is mutated (its return value can change) just because something outside and separate of it mutated goes against the very heart of functional programming, and is not how functional languages behave at all.
Re:Fun with Swift by john_butts on Monday January 04, 2016 @12:08PM (#10836745)
This gets back to the point that Swift is not a functional language. By default, the closure is capturing an immutable reference - the fact that the value might change is implicit to the way you must think about programming in a non-functional language. The mechanism to capture a constant value is to declare it in in a capture list:

  var f = {[i] in print("hello I'm a callback and i =", i)}
Re:Fun with Swift by rdtsc on Monday January 04, 2016 @02:43PM (#10837962)
> By default, the closure is capturing an immutable reference

I think some imperative languages still refer to those things as closures, which is unfortunate. Capturing a closure then having everything in there mutable kind of defeats the purpose in my opinion. But maybe I've been damaged/spoiled by functional programming and/or have spent to much time debugging issues related to concurrency and shared mutable state.

Re:Fun with Swift by qwertyuiop924 on Monday January 04, 2016 @03:45PM (#10838427)
Wait, What? Immutable closures are way less useful than mutable closures. Immutable closures can pretty much only be used to create thunks. Mutable closures are basically objects.

On the other hand, if your closure depends on global mutable state, than you have a piece of GLOBAL state that is VARIABLE. Sometimes known as the root of all evil.

But maybe I've been damaged/spoiled by scheme and/or not done enough concurrency programming to get your point.

Re:Fun with Swift by hellofunk on Monday January 04, 2016 @03:57PM (#10838538)
Anytime I see someone claim that immutability is "less useful" than mutability, I know that the individual has not spent a long time working in an immutable language. Because things are tremendously easier when mutation rarely enters the picture. But, it can take some experience to grasp this.
Re:Fun with Swift by DrJokepu on Monday January 04, 2016 @08:18PM (#10840262)
Meh, depends on the situation. Some problems are easily solved in a functional way, some problems aren't, and then there are problems that are best solved using a mixed approach. Sometimes a good old-fashioned for loop (or the equivalent) and stateful I/O is "tremendously easier" to work with than layers of tail recursion and I/O monads. Professional developers are expected to know which tool to use when, rather than religiously sticking to one approach in all circumstances.
Re:Fun with Swift by hellofunk on Tuesday January 05, 2016 @06:10AM (#10842609)
I have yet to encounter any problem that would be better served with an imperative for loop or nested for loop than an immutable list comprehension in Clojure, for instance.
Re:Fun with Swift by coldtea on Tuesday January 05, 2016 @04:12PM (#10846088)
Do you have actual science (comparative studies --plural, not some single paper--, etc) behind the assertion of "better" for the functional approach or is it just blind faith?

An empirical observation says that the most important software in the world, including most of the internet infrastructure, OSes, databases, filesystems, office suites, embedded systems and such, powering 99% of the modern era is written in an imperative or OO language.

That's a fact. Whereas "there would be less issues if we had made them in a functional language" is mere conjecture, unless proven otherwise.

Note that common errors such as null pointer exceptions are not only avoided in functional languages for example, but in any imperative language with optionals, bounds checking etc too. So if one is gonna bring those up as something in favor of functional programming they're not giving the full picture.

Re:Fun with Swift by qwertyuiop924 on Tuesday January 05, 2016 @06:01PM (#10846810)
I've never met a problem where tailcalls were more awkward than loops. But then, scheme kind of pushes you toward tail-calls, so hey.
Re:Fun with Swift by fleitz on Monday January 04, 2016 @06:13PM (#10839509)
I think swift really found the sweet spot in this regard by not thinking about mutability but value/reference semantics.

I've found that in swift the things that should be values are and the things that should be references are, rather than taking an all or nothing approach.

Re:Fun with Swift by hellofunk on Tuesday January 05, 2016 @06:11AM (#10842611)
Except in swift, a truly value-oriented thought process is hampered by its copy-on-write semantics, which are a far cry from immutable structures found in functional languages.
Re:Fun with Swift by fleitz on Tuesday January 05, 2016 @03:50PM (#10845907)
Value semantics are certainly not ideal, but it is very practical.
Re:Fun with Swift by qwertyuiop924 on Monday January 04, 2016 @04:03PM (#10838586)
hellofunk: Reasoning is easier in functional languages, so fair enough.
Re:Fun with Swift by DrJokepu on Monday January 04, 2016 @08:32PM (#10840322)
Cocoa and Cocoa Touch were designed with imperative programming in mind though, so this is what the creators of Swift had to work with. I think the main use case for mutable captured values is mutable self, in particular the following, extremely common pattern:

    dispatch_async(my_background_queue) {
        do_some_io()
        let result = do_expensive_computation()
        dispatch_async(dispatch_get_main_queue()) {
            self.value = result
            update_ui()
        }
    }
Re:Fun with Swift by mikeash on Monday January 04, 2016 @01:41PM (#10837493)
Objective-C does it differently by default:

    int x = 0;
    void (^block)(void) = ^{ NSLog(@"%d", x); };
    x++;
    block();
This will log 0, not 1. If you want to capture by reference rather than by value, you add __block to the declaration of x.

For a lot of people coming to Swift from Objective-C, this is a surprising change, especially if Objective-C was their first language with closures.

Re:Fun with Swift by qwertyuiop924 on Monday January 04, 2016 @03:47PM (#10838448)
That's a block, not a closure. It's still an anonymous function, but the semantics are slightly odd, and derived from Smalltalk, probably altered some.
Re:Fun with Swift by mikeash on Monday January 04, 2016 @04:02PM (#10838578)
"Blocks" is what Objective-C calls closures.

A closure is just a function that captures ("closes over") the surrounding scope.

Edit: strictly speaking, the construct here is an anonymous function. Objective-C calls them "blocks" and Swift calls them "unnamed closures" or "closure expressions." Both are, or at least can be, closures. (I'm not sure if the term "closure" can be used to refer to a function that could refer to variables in the enclosing scope but doesn't. Probably not.)

Re:Fun with Swift by qwertyuiop924 on Tuesday January 05, 2016 @05:59PM (#10846784)
What you seem to be calling a closure refers to a lambda in a lexically scoped language. Particularly when they refer to free variables.

Blocks are in fact lambdas, or at least closures. I was wrong in the above. In some early versions of smalltalk, blocks had some odd semantics that made them different, but this is no longer true. However, judging by the Objective-C example above, Objective-C blocks don't create true closures, as a true closure would have the semantics of the Swift code from the article.

Re:Fun with Swift by tarentel on Monday January 04, 2016 @06:06PM (#10839465)
This is only surprising because of the ambiguity of value types in certain cases in Swift. If you passed it to a function and mutated it then it would work as your example. I'm still not sure why they made it work this way for closures. Using reference types closures and blocks are more or less the same.
Re:Fun with Swift by mikeash on Monday January 04, 2016 @07:56PM (#10840145)
What ambiguity are you referring to? It has nothing to do with value versus reference types. Reference types have the exact same difference between the two languages. In Swift, mutable variables are captured by reference by default, and in Objective-C they're copied by default. Value versus reference doesn't make a difference. For example:

    NSView *view = [NSButton new];
    void (^block)(void) = ^{ NSLog(@"%@", view); };
    view = [NSTextField new];
    block();
In Objective-C, this will log an NSButton. Translate it to Swift and it will log an NSTextField.

I don't think either behavior is more correct, it's just a fairly arbitrary choice. IMO it's surprising only if you've learned to expect one way because you worked in a language that does it that way, then encounter a language that does it the other way.

Re:Fun with Swift by masklinn on Monday January 04, 2016 @12:03PM (#10836700)
> Which language does this differently?

Languages with immutable bindings (the author is one of the original designers and implementers of Erlang)

Re:Fun with Swift by icebraining on Monday January 04, 2016 @12:04PM (#10836711)
In fact, he expands on closures in an earlier post (about Elixir):

Proper closures should only contain pointers into immutable data (which is the case in Erlang) - no pointers into mutable data. If a closure contains a pointer into mutable data and you change the data later you break the closure. This means you can’t parallelize your program and even sequential code can contain weird errors.

http://joearms.github.io/2013/05/31/a-week-with-elixir.html

Re:Fun with Swift by qwertyuiop924 on Monday January 04, 2016 @04:00PM (#10838563)
That's just wrong, in most cases. Mutable closures are incredibly useful. Erlang, however doesn't actually need them, because where I (a scheme programmer) would use a closure with mutable state, Erlang programmers would use a process running a function that takes that state as an argument and runs forever, tail-calling itself to change the state. In most languages this is impractical, because most languages don't have erlang's threading semantics.
Re:Fun with Swift by lostcolony on Monday January 04, 2016 @08:00PM (#10840165)
They are, however, incredibly useful in Erlang. Most languages don't ~need~ closures. The whole point is that they're useful, though.

Haskell doesn't have mutable state; it still has closures.

Mutable or immutable is somewhat orthogonal; I admit, coming from Erlang to Javascript I was -shocked- and very facepalmy when I learned that closures close over variables that can still vary. That is, I couldn't just pass back a function and expect it to behave the same way depending when I called it. I had to add an additional scope in place and bind the values anew (i.e., a new function, passing the values being closed over into it as params). Immutable is much easier to reason about, much easier to write with, and despite being more limited in what you can do with them, I'd argue just as useful. Everything it prevents you from doing there is some other, safe way of achieving; the same as comparing mutable vs immutable in other contexts.

Re:Fun with Swift by adrusi on Monday January 04, 2016 @01:29PM (#10837397)
They don't do it differently, they simply avoid the question by not letting you change any binding ever. In languages that embrace immutable bindings but don't enforce them, like scheme, closures work exactly as the parent describes.
Re:Fun with Swift by rdtsc on Monday January 04, 2016 @02:35PM (#10837912)
> Of course it should change i after the closure was defined, since the closure doesn't copy but refer to that i.

Well it should not allow it and make ia clone / copy-on-write thing /etc. Calling that a closure sounds broken. Just like Joe points out.

> Which language does this differently?

Haskell, Elixir, OCaml, Erlang

Re:Fun with Swift by qwertyuiop924 on Monday January 04, 2016 @03:56PM (#10838522)
No, those languages just don't allow you to modify state. In non-functional languages like swift, you can modify state, and closures respond to that.

What I think a lot of people fail to understand is that a closure is not a special object, with magical powers, but a direct consequence of lexical scoping: closures just follow the lexical scope rules, even if their lexical scope isn't within the current dynamic scope. If a variable within the closure's lexical scope changes, the closure won't keep the value the same. Here's an example of these semantics in C:

  int global = 4;
  void oh_noes(){
    printf("%d", global);
  }
  global++;
  oh_noes(); //prints 5
If somebody complained that the function oh_noes should print 4 in this example, you'd think they were insane. Closures actually work in exactly the same way.
Re:Fun with Swift by rdtsc on Monday January 04, 2016 @05:28PM (#10839223)
> What I think a lot of people fail to understand is that a closure is not a special object, with magical powers, but a direct consequence of lexical scoping:

That is how it is implemented. It doesn't have to be, I have a list of example languages where it is not the case.

> What I think a lot of people fail to understand is that a closure is not a special object, with magical powers,

Maybe that's why I like functional languages, it does seem like they have magical powers ;-) there.

Re:Fun with Swift by wtetzner on Monday January 04, 2016 @10:12PM (#10840821)
> That is how it is implemented. It doesn't have to be, I have a list of example languages where it is not the case.

No, you don't. Closures in those are also a direct consequence of lexical scoping. But those languages don't have mutable variables, regardless of closures.

Re:Fun with Swift by rdtsc on Tuesday January 05, 2016 @12:35AM (#10841436)
> No, you don't.

Functions defined in modules in Erlang are different from closures. Here is a example:

   -module(e).
   -compile(export_all).
   f()->  1.
   g()-> fun ()-> 1 end.

   $ erl
   > c(e).

   > erlang:fun_info(fun e:f/0).
   [{module,e},{name,f},{arity,0},{env,[]},{type,external}]

   > erlang:fun_info(e:g()).  
   [{pid,<0.42.0>},
   {module,e},
   {new_index,0},
   {new_uniq,<<136,230,191,77,132,145,66,52,216,215,111,24,
             18,188,4,169>>},
    {index,0},
    {uniq,71775738},
    {name,'-g/0-fun-0-'},
    {arity,0},
    {env,[]},
    {type,local}]
To get info on e:f it has to be become a closure-like object, but if you see internally it is still represented differently than a closure.

> Closures in those are also a direct consequence of lexical scoping.

Not sure what you mean a direct consequence. Are you saying that closures follow scoping rules? The point was that it doesn't necessarily follow that they have to be implemented as object instances in object oriented languages, or function pointers, or functions (say like in Erlang).

Re:Fun with Swift by qwertyuiop924 on Tuesday January 05, 2016 @05:50PM (#10846722)
Well, yes, closures can be implemented however you want, in a true lexical scoped language, every function is a closure, not just lambdas, only most don't really close over anything, and can be optimized away. The case of C is, again, instructive.

    //foo.c
    int global = 0;
    int quuxify(){
        return global++;
    }

    //bar.c
    extern int quuxify();
    printf("%d", quuxify());//prints "0"
    printf("%d", quuxify());//prints "1"
even though quuxify() depends on global, which is out of scope in bar.c, the call still compiles. Why? because C is a lexically scoped language, and so variable references in functions refer to the scope the function was declared in, NOT the one it was called in.

And you thought C didn't have closures ;-D

Re:Fun with Swift by losvedir on Tuesday January 05, 2016 @03:34AM (#10842086)
It's a bit weird. I don't think Joe would have an issue with mutating the closed over variable, but having the closure just be the binding rather than the value, and then being able to rebind it to something else seems brittle.

> Which language does this differently?

Rust does it this way but in a less error prone way due to its sophisticated ownership tracking. If you close over a variable in the environment, it gives the ownership to the closure and you can't then rebind it outside.

Re:Fun with Swift by malisper on Monday January 04, 2016 @01:33PM (#10837426)
He's not saying that closures over mutable variables is a bad thing in Swift. He is saying it's a bad idea in any language, even though most languages with closures allow it.
Re:Fun with Swift by golergka on Monday January 04, 2016 @02:02PM (#10837670)
I see how programmers can mistake mutable closure references for immutable, but if we imagine that this confusion is solved somehow (for example, closures copy values by defualt and reference only with a special keyword), how is it bad?
Re:Fun with Swift by raffomania on Monday January 04, 2016 @01:38PM (#10837465)
This behavior is one of the reasons not to call JS a 'functional' language, IMHO.
Re:Fun with Swift by qwertyuiop924 on Monday January 04, 2016 @04:05PM (#10838600)
Well then scheme isn't one either. But then, scheme isn't one. And javascript is just a language in which the functional paradigm is common. it's a multi-paradigm language. Anybody who says otherwise doesn't know what their talking about.