News for hackers. Stuff that matters.
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