Andy Bulka Technical Director Austhink Software www.austhink.com
Overview <ul><li>What are they? </li></ul><ul><li>What languages have them? </li></ul><ul><li>What can you do with them? <...
Definition <ul><li>A closure is a block of code that can be passed around </li></ul><ul><li>It continues to have ongoing a...
Language support <ul><li>Closures originated in Lisp. F unctional programming languages use them a lot e.g. Haskell </li><...
Example – C# class Program  { delegate void Action(); static Action GetAction() { int x = 0; Action a =  delegate  { Conso...
Example – C# class Program { delegate void SomeDelegate(); public static void  InvokeMethod () { SomeDelegate del = delega...
Example – Python <ul><li>A closure is an  anonymous function  that ‘closes’ over its surrounding scope. Thus when the func...
Uses – Summary <ul><li>Elegant short code fragments – no wrapping class baggage </li></ul><ul><ul><li>Bits of code passed ...
What’s a “block of code” <ul><li>Code Blocks – pass in a block vs. return a block </li></ul><ul><ul><li>Pass code block as...
How are parameters handled? Groovy <ul><li>In Groovy, closure parameters are listed before the -> token, like so: </li></u...
How are parameters handled? Python  <ul><li>In the case of returning a code block for someone else to use, it is returned ...
How are parameters handled? C# <ul><li>DotNet has a List.FindAll() which expects a “predicate/delegate” that takes one par...
Java – the final var problem e.g. <ul><li>Java's anonymous inner classes can access locals - but only if they are final.  ...
Java – the final var problem <ul><li>The second restriction to notice is that an inner class can only refer to variables f...
Java – final – hack using array <ul><li>public   interface  Counter { </li></ul><ul><li>public   int  current(); </li></ul...
Java inner classes vs closures <ul><li>Java inner classes are a bit verbose though (need an interface name  (thus not very...
Closures add “state” <ul><li>The essential difference between an anonymous/inline function and a closure is that the closu...
Closure “tricks” <ul><li>The ability of a closure to have ongoing access to state from its context allows various tricks. ...
Why not just use objects? <ul><li>Why not pass an object or return an object.  The receiver code simply calls a method on ...
Why not just use anonymous inner classes? <ul><li>It is certainly true that for any program you can write using closures, ...
Uses – injecting strategy <ul><li>Write to console vs. to a file etc. – choice of strategy </li></ul>a = delegate { Consol...
Uses – injecting strategy – Use OO <ul><li>Setting up a method on an object etc. (strategy pattern). </li></ul><ul><li>Yes...
Uses - iteration - filtering <ul><li>Iterating over lists, and filtering / collecting </li></ul><ul><li>More elegant code ...
Uses – iteration – filtering – Requires Library support <ul><li>All these Ruby closure tricks require deep library support...
Uses - iteration –  filtering – Use List Comprehensions <ul><li>Python has alternative facility called “list comprehension...
Uses - iteration –  filtering – Use Loops or OO <ul><li>What’s wrong with a for loop?  ;-) Easy to understand, though more...
Uses - Caching <ul><li>The solution is to build delayed objects so that the first time they are forced, they store the val...
Uses - Caching <ul><li>C# translation </li></ul>static   SomeDelegate  Cache( SomeDelegate  f) {      bool  alreadyrun =  ...
Uses - Caching <ul><li>C# usage of caching – proof it works </li></ul>     class   Program      {          delegate   int ...
Uses – Caching – Use OO <ul><li>Use lazy instantiation code (manually write each time). </li></ul><ul><li>Use proxy patter...
Uses - set up, then clean up <ul><li>in encapsulating operations that must be set up, and then cleaned up after. </li></ul...
Uses - set up, then clean up <ul><li>E.g. in Ruby encapsulating operations that must be set up, and then cleaned up after....
Uses - set up,  then clean up – Use OO <ul><li>Is the idea then: </li></ul><ul><ul><li>fp = open(“file.txt)  // step 1 </l...
Uses – delay evaluation <ul><li>Closures delay evaluation—i.e., they do not &quot;do&quot; anything until they are called ...
Uses – delay evaluation <ul><li>My python situation builds a list of functions, then I execute them much later, when all t...
Uses – delay evaluation <ul><li>Original solution </li></ul>class  Node: def __init__(self, val): self.val = val def  get(...
Uses – delay evaluation – Use OO <ul><li>Another way to do it.  Pure OO. </li></ul>def  get2(node): class  Late: def  __in...
Uses – delay evaluation – Use eval <ul><li>Another way to do it would be to create the code as a string and then later eva...
Uses – share private state <ul><li>Share state in a local scope place.  Two or more places that use a closure can store in...
Uses – share private state <ul><li>Closures can be used to create additional scopes that can be used to group interrelated...
Uses – share private  state – Use OO <ul><li>Use OO instead ! </li></ul><ul><li>Instances of objects, shared state via pro...
Uses – thread safety <ul><li>Prototype cloning can help with thread safety cos making copies of code not sharing a central...
Uses – thread safety <ul><li>One possibility might be tempting to place a lock on &quot;g_StartingText&quot;. This would c...
Uses – thread safety <ul><li>Even with the verbosity of anonymous methods, the code has been greatly reduced. And, assumin...
Uses – thread safety – use OO <ul><li>Yeah but can use alternative OO technique: </li></ul>class Searcher { string g_Start...
Uses - new control structures  <ul><li>Closures allow you to add  new control structures  to your language. With closures,...
Uses - new control structures  <ul><li>It’s the ability to return out of the closure OR out of the enclosing method (Ruby ...
Uses - new control  structures – Use OO  <ul><li>Iterator? </li></ul><ul><li>Define an object model which supports pluggab...
Uses - function factory <ul><li>Function factory – define a function with a parameter for use later e.g. javascript  this ...
Uses - function factory – Use OO <ul><li>Function factory – define a function with a parameter for use later e.g. javascri...
Uses – command Pattern <ul><li>Closures are also great for implementing the Command pattern. Command implementations that ...
Uses - command Pattern <ul><li>Function 1 that returns a function 2 with state </li></ul><ul><li>Timer invokes function 2 ...
Uses - command Pattern – Use OO <ul><li>Technique came from javascript where there are no classes (as usually understood) ...
Are Closures really that cool? <ul><li>The inventor of Python – Guido van Rossum – resists adding any further closure supp...
Summary – OO vs closures <ul><li>Arguably….     Stateful functions should be implemented as methods of classes.  Behaviou...
Upcoming SlideShare
Loading in …5
×

Andy On Closures

2,057 views

Published on

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,057
On SlideShare
0
From Embeds
0
Number of Embeds
89
Actions
Shares
0
Downloads
48
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Andy On Closures

  1. 1. Andy Bulka Technical Director Austhink Software www.austhink.com
  2. 2. Overview <ul><li>What are they? </li></ul><ul><li>What languages have them? </li></ul><ul><li>What can you do with them? </li></ul><ul><li>Can you do the same things using regular OO? </li></ul>
  3. 3. Definition <ul><li>A closure is a block of code that can be passed around </li></ul><ul><li>It continues to have ongoing access to variables in the scope where it was defined </li></ul><ul><li>Ie. they are a block of code plus the bindings to the environment they came from </li></ul>
  4. 4. Language support <ul><li>Closures originated in Lisp. F unctional programming languages use them a lot e.g. Haskell </li></ul><ul><li>Most languages have them: </li></ul><ul><ul><li>Smalltalk, </li></ul></ul><ul><ul><li>Lisp / Scheme, </li></ul></ul><ul><ul><li>Boo, Python </li></ul></ul><ul><ul><li>Groovy, </li></ul></ul><ul><ul><li>Ruby, </li></ul></ul><ul><ul><li>C# </li></ul></ul><ul><li>C/C++/Java don’t </li></ul>
  5. 5. Example – C# class Program { delegate void Action(); static Action GetAction() { int x = 0; Action a = delegate { Console.WriteLine(x); }; x = 1; return a; } static void Main(string[] args) { Action a = GetAction(); a(); } }
  6. 6. Example – C# class Program { delegate void SomeDelegate(); public static void InvokeMethod () { SomeDelegate del = delegate() { Console.WriteLine(&quot;Hello2&quot;); }; del(); } } class Program { delegate void SomeDelegate(); public static void InvokeMethod () { SomeDelegate del = new SomeDelegate( SomeMethod ); del(); } static void SomeMethod() { Console.WriteLine(&quot;Hello&quot;); } } static void Main(string[] args) { InvokeMethod (); }
  7. 7. Example – Python <ul><li>A closure is an anonymous function that ‘closes’ over its surrounding scope. Thus when the function defined by the closure is executed, it has access to all the local variables that were in scope when it was created. </li></ul>x = 1 def getf(y): return lambda n, m : n + m + x + y f = getf(1) print f(1,2) x += 100 print f(1,2) x = 1 def getf(y): def myf (n, m): return n + m + x + y return myf f = getf(1) print f(1,2) x += 100 print f(1,2)
  8. 8. Uses – Summary <ul><li>Elegant short code fragments – no wrapping class baggage </li></ul><ul><ul><li>Bits of code passed to filtering/collecting methods, and for assigning methods to event handlers </li></ul></ul><ul><li>Single function – no wrapping class baggage </li></ul><ul><ul><li>inject a method as a parameter to something </li></ul></ul><ul><ul><li>return a method for later use </li></ul></ul><ul><li>Injecting strategy </li></ul><ul><li>Iteration - Collecting and Filtering lists </li></ul><ul><li>Caching </li></ul><ul><li>Setup / Cleanup </li></ul><ul><li>Delay Evaluation </li></ul><ul><li>Shared private state (local vars shared) </li></ul><ul><li>Thread safety – creating multiple instances of closures </li></ul><ul><li>New control structures </li></ul><ul><li>Function Factories </li></ul><ul><ul><li>Params configure custom functions </li></ul></ul><ul><ul><li>Command pattern usage </li></ul></ul>
  9. 9. What’s a “block of code” <ul><li>Code Blocks – pass in a block vs. return a block </li></ul><ul><ul><li>Pass code block as a parameter to something </li></ul></ul><ul><ul><li>Return the code block for someone else to use (like defining a function) </li></ul></ul><ul><li>Language needs to have a function passing ability </li></ul><ul><ul><li>C function pointers, Python functions are objects, C# delegates are type safe pointers, Java has anonymous inner classes </li></ul></ul><ul><li>Anonymous function vs. Named function </li></ul><ul><ul><li>Named functions work though anonymous more elegant </li></ul></ul><ul><ul><li>Anonymity means lose the function name – but you still need to have a syntax for handling parameters </li></ul></ul>
  10. 10. How are parameters handled? Groovy <ul><li>In Groovy, closure parameters are listed before the -> token, like so: </li></ul><ul><li>def clos = { println &quot;hello! } // without params </li></ul><ul><li>clos() </li></ul><ul><li>def clos = { a, b -> print a+b } // with params </li></ul><ul><li>clos( 5, 7 ) </li></ul>
  11. 11. How are parameters handled? Python <ul><li>In the case of returning a code block for someone else to use, it is returned as a function e.g. </li></ul><ul><li>def paidMore(amount): </li></ul><ul><li>return lambda e: e.salary > amount </li></ul><ul><li>where e is a parameter thus </li></ul><ul><li>f = paidMore(150) // closure assigned to a variable </li></ul><ul><li>f(sam) // closure called, with parameter </li></ul>
  12. 12. How are parameters handled? C# <ul><li>DotNet has a List.FindAll() which expects a “predicate/delegate” that takes one parameter. </li></ul>result = gNames.FindAll( delegate(string name) { return name.StartsWith(startingText); } ); Where there delegate is declared public delegate bool Predicate<T>(T obj)
  13. 13. Java – the final var problem e.g. <ul><li>Java's anonymous inner classes can access locals - but only if they are final. or if they are instance attributes, apparently </li></ul>public void example() { final double use=Math.random()*10000; SwingUtilities.invokeLater( new Runnable() { public void run() { System.out.println(use); } } ); }
  14. 14. Java – the final var problem <ul><li>The second restriction to notice is that an inner class can only refer to variables from the outer lexical scope if those variables are declared to be final. This keyword tells the compiler that the binding of that variable cannot be modified at runtime. </li></ul><ul><li>In order for an instance of an inner class to modify an outer variable, the trick is to declare the variable to be an array. Then the binding of the array is final but the element of the array is not! - Patrick Logan </li></ul>
  15. 15. Java – final – hack using array <ul><li>public interface Counter { </li></ul><ul><li>public int current(); </li></ul><ul><li>} </li></ul><ul><li> … </li></ul><ul><li>final int [] count = new int [1]; </li></ul><ul><li>return new Counter() { </li></ul><ul><li>public int current() { </li></ul><ul><li>return count[0] += 1; </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>
  16. 16. Java inner classes vs closures <ul><li>Java inner classes are a bit verbose though (need an interface name (thus not very anonymous!) and method name wrapping the code) </li></ul><ul><li>No local variable access either, unless variable is final </li></ul><ul><li>Closures - which are like inner classes but have read and write access local variables </li></ul><ul><li>C# 2.0 has true closure support in the form of anonymous delegates. This includes reading and modifying variables outside the context of the closure - unlike Java's anonymous inner classes. </li></ul>
  17. 17. Closures add “state” <ul><li>The essential difference between an anonymous/inline function and a closure is that the closure continues to have ongoing access to all the variables in scope at the time it was defined. </li></ul><ul><li>E.g. A closure has access to the local vars and even the parameters of the enclosing method if the closure was returned from a method </li></ul><ul><li>This gives the closure not only its own internal state, but the state of its context. </li></ul><ul><li>Thus a closure could be viewed as really an “object” since it has attributes, not just behaviour. </li></ul>
  18. 18. Closure “tricks” <ul><li>The ability of a closure to have ongoing access to state from its context allows various tricks. </li></ul><ul><li>Pithy loops to filter and collect lists </li></ul><ul><li>The ability of a closure to be passed around (returned from a method, passed as parameters to other methods) means the closure acts as a “prototype” and many instances can be created/cloned. </li></ul><ul><li>Tricks (or uses) means you can create “factory methods” that return instances of closures, where each closure is configured differently due to the parameters passed into the enclosing factory method being different at the time of creation. </li></ul><ul><li>Conversely, instances of closures can share state of local vars inside the factory method. Thus it’s a way of protected/private shared data amongst instances of closure “objects” </li></ul>
  19. 19. Why not just use objects? <ul><li>Why not pass an object or return an object. The receiver code simply calls a method on the object to do the work. Simple. </li></ul><ul><li>Why all the fuss about passing functions as first class objects, or blocks of code “closures” as first class objects? </li></ul><ul><li>E.g. Java’s use of anonymous inner classes are arguably a nice compromise – declaring a thin OO wrapper around a single method. </li></ul>
  20. 20. Why not just use anonymous inner classes? <ul><li>It is certainly true that for any program you can write using closures, you can write a roughly equivalent program using anonymous inner classes. That's because the Java programming language is Turing-complete. But you will probably find yourself resorting to a significant and awkward refactoring of the code that has nothing to do with the purpose of the code. </li></ul>
  21. 21. Uses – injecting strategy <ul><li>Write to console vs. to a file etc. – choice of strategy </li></ul>a = delegate { Console.WriteLine(x); }; a();
  22. 22. Uses – injecting strategy – Use OO <ul><li>Setting up a method on an object etc. (strategy pattern). </li></ul><ul><li>Yes more wiring… </li></ul>
  23. 23. Uses - iteration - filtering <ul><li>Iterating over lists, and filtering / collecting </li></ul><ul><li>More elegant code e.g. pass the algorithm as a block of code e.g. Ruby: </li></ul><ul><li>The closure technique allows you to use a one-liner. </li></ul>offices = [] for e in employees offices << e.office end offices = employees.collect {|e| e.office}
  24. 24. Uses – iteration – filtering – Requires Library support <ul><li>All these Ruby closure tricks require deep library support anyway (not necessarily a bad thing…) viz. </li></ul><ul><li>Designers of software libraries can allow users to customize behavior by passing closures as arguments to important functions. </li></ul><ul><li>E.g. C# List.FindAll() takes a function/delegate as a parameter to use as the match function </li></ul>managersOffices = employees. select {|e| e.manager?}. map {|m| m.office} managers, plebs = employees. partition {|e| e.manager?} allManagers = employees. all ? {|e| e.manager?} noManagers = ! employees. any ? {|e| e.manager?} sortedEmployees = employees. sort {|a,b| a.lastname <=> b.lastname} sortedEmployees = employees. sort_by {|e| e.lastname}
  25. 25. Uses - iteration – filtering – Use List Comprehensions <ul><li>Python has alternative facility called “list comprehensions” </li></ul><ul><li>Very powerful… can also have if statements in them: </li></ul><ul><li>Sure, doesn’t handle everything that closures can do, but handles 90% of the select/collect/filter jobs well. Very popular addition to the python language. </li></ul>offices = [e.office for e in employees] managersOffices = [e.office for e in employees if e.isManager]
  26. 26. Uses - iteration – filtering – Use Loops or OO <ul><li>What’s wrong with a for loop? ;-) Easy to understand, though more verbose </li></ul><ul><li>If there is so much library support needed anyway, why not avoid closures and invent library/framework support that takes objects as parameters and calls a method on it </li></ul><ul><li>E.g. a collection could have a method called FindAll(o) that calls Match() on the object passed in to determine if each item in the collection makes it into the result list. Injecting an object (or anon inner class method) as a strategy – simple, though possibly more verbose since you have to declare and instantiate each strategy class. Apparently this is laborious to use in practice, but doable. </li></ul>
  27. 27. Uses - Caching <ul><li>The solution is to build delayed objects so that the first time they are forced, they store the value that is computed. Subsequent forcings will simply return the stored value without repeating the computation. In other words, we implement delay as a special-purpose memoized procedure similar to the one described in exercise  3.27 . One way to accomplish this is to use the following procedure, which takes as argument a procedure (of no arguments) and returns a memoized version of the procedure. The first time the memoized procedure is run, it saves the computed result. On subsequent evaluations, it simply returns the result. </li></ul><ul><li>(define (memo-proc proc)   (let ((already-run? false) (result false))     (lambda ()       (if (not already-run?)           (begin (set! result (proc))                  (set! already-run? true)                  result)           result)))) </li></ul>
  28. 28. Uses - Caching <ul><li>C# translation </li></ul>static SomeDelegate Cache( SomeDelegate f) {     bool alreadyrun = false ;     int result = -1;     return delegate     {         if (!alreadyrun)         {             result = f();  // run it             alreadyrun = true ;         }         return result;     }; }
  29. 29. Uses - Caching <ul><li>C# usage of caching – proof it works </li></ul>    class Program     {         delegate int SomeDelegate ();         static void Main( string [] args)         {             int rez;             SomeDelegate del;                         del = Cache(Calculate);             rez = del();             Console .WriteLine(rez);             rez = del();  // this time, will return the cached value.             Console .WriteLine(rez);         }         static int Calculate()   // the function we are trying to cache         {             Console .Write( &quot;... &quot; );             return 5;         } ... 5 5 Press any key to continue . . .
  30. 30. Uses – Caching – Use OO <ul><li>Use lazy instantiation code (manually write each time). </li></ul><ul><li>Use proxy pattern to cache </li></ul><ul><li>Hard to generalise the closure to work with any number/combination of parameters and return values so using the OO proxy design pattern just as easy/hard to generalise. </li></ul>
  31. 31. Uses - set up, then clean up <ul><li>in encapsulating operations that must be set up, and then cleaned up after. </li></ul><ul><li>E.g. in Ruby </li></ul><ul><li>File.open(filename) {|f| doSomethingWithFile(f)} </li></ul><ul><li>Here the open method opens the file, executes the supplied block, and then closes it. This can be a very handy idiom for things like transactions (remember to commit or rollback) or indeed anything where you have to remember to do something at the end. I use this extensively in my xml transformation routines. </li></ul>
  32. 32. Uses - set up, then clean up <ul><li>E.g. in Ruby encapsulating operations that must be set up, and then cleaned up after. Here's an example that does both: </li></ul><ul><li>IO.foreach(&quot;foo.txt&quot;) do |line| </li></ul><ul><li>if (line =~ /total: (d+)/) </li></ul><ul><li>puts $1; </li></ul><ul><li>end </li></ul><ul><li>end </li></ul><ul><li>This code searches a file, and prints the matches. The IO.foreach takes care of opening the file, delivering each line to our closure, then closing the file. </li></ul>
  33. 33. Uses - set up, then clean up – Use OO <ul><li>Is the idea then: </li></ul><ul><ul><li>fp = open(“file.txt) // step 1 </li></ul></ul><ul><ul><li>fp.write( CODEBLOCK ) // step 2 </li></ul></ul><ul><ul><li>fp.close() // step 3 </li></ul></ul><ul><li>Isn’t it just a matter of organising your code? </li></ul><ul><li>Use try/finally </li></ul><ul><li>Use C#’s “using” construct which always cleans up </li></ul><ul><li>Use “template method” design pattern instead and override the middle step </li></ul>
  34. 34. Uses – delay evaluation <ul><li>Closures delay evaluation—i.e., they do not &quot;do&quot; anything until they are called </li></ul>
  35. 35. Uses – delay evaluation <ul><li>My python situation builds a list of functions, then I execute them much later, when all the info available. </li></ul>class View(object): def __init__(self, viewname): self.cmds = [] def SetLocation(self, node , x, y): f = lambda : &quot; &quot; + &quot;view.SetLocation(%s, %d, %d)&quot; % ( node .ToNodeName(), x, y) self.cmds.append(f) def SetOffset(self, node1, node2 , x, y): f = lambda : &quot; &quot; + &quot;view.SetOffset(%s, %s, %d, %d)&quot; % ( node1 .ToNodeName(), node2 .ToNodeName(), x, y) self.cmds.append(f) # store lambdas/closures since don't want to execute each node.ToNodeName() till each rootnode.RecalcIndexes has been called for c in self.cmds: resultstr += c() + CRLF // executes the lambda
  36. 36. Uses – delay evaluation <ul><li>Original solution </li></ul>class Node: def __init__(self, val): self.val = val def get(node): return lambda n, m : str(n) + &quot; &quot; + str(m+1) + &quot; &quot; + str(node.val) node = Node(10) f = get(node) print f(1,2) # 1, 3, 10 node.val = 100 print f(1,2) # 1, 3, 100
  37. 37. Uses – delay evaluation – Use OO <ul><li>Another way to do it. Pure OO. </li></ul>def get2(node): class Late: def __init__(self, node): self.node = node def Execute(self, n, m): return str(n) + &quot; &quot; + str(m+1) + &quot; &quot; + str(self.node.val) return Late(node) node = Node(10) o = get2(node) print o.Execute(1,2) # 1, 3, 10 node.val = 100 print o.Execute(1,2) # 1, 3, 100
  38. 38. Uses – delay evaluation – Use eval <ul><li>Another way to do it would be to create the code as a string and then later eval(code) </li></ul><ul><li>Only supported in dynamic languages, or languages with ability to compile at runtime. </li></ul>
  39. 39. Uses – share private state <ul><li>Share state in a local scope place. Two or more places that use a closure can store info into the closure’s local namespace. Closure acts as a ‘object’ with behaviour and state </li></ul><ul><li>Multiple functions can be produced which close over the same environment, enabling them to communicate privately by altering that environment (in languages that allow assignment). </li></ul>
  40. 40. Uses – share private state <ul><li>Closures can be used to create additional scopes that can be used to group interrelated and dependent code in a way that minimises the risk of accidental interaction. Suppose a function is to build a string and to avoid the repeated concatenation operations (and the creation of numerous intermediate strings) the desire is to use an array to store the parts of the string in sequence and then output the results using the Array.prototype.join method (with an empty string as its argument). The array is going to act as a buffer for the output, but defining it locally to the function will result in its re-creation on each execution of the function, which may not be necessary if the only variable content of that array will be re-assigned on each function call. </li></ul><ul><li>A Closure allows the buffer array to be associated (and neatly packaged) with the function that is dependent upon it and simultaneously keep the property name to which the buffer array as assigned out of the global namespace and free of the risk of name conflicts and accidental interactions. </li></ul><ul><li>See http://www.jibbering.com/faq/faq_notes/closures.html and http://www.litotes.demon.co.uk/js_info/private_static.html and http://www.crockford.com/javascript/private.html for details on how javascript does this. Its all a bit much, frankly for a regular OO programmer ;-) </li></ul>
  41. 41. Uses – share private state – Use OO <ul><li>Use OO instead ! </li></ul><ul><li>Instances of objects, shared state via protected static </li></ul><ul><li>or use aggregation – all instances point to shared object </li></ul><ul><li>Etc. </li></ul>
  42. 42. Uses – thread safety <ul><li>Prototype cloning can help with thread safety cos making copies of code not sharing a central shared piece of code. (though object instances make copies too). So its about shared data really. </li></ul>
  43. 43. Uses – thread safety <ul><li>One possibility might be tempting to place a lock on &quot;g_StartingText&quot;. This would certainly make the function thread-safe but it has some drawbacks. The biggest issue with this approach is that threads will not be able to access this function concurrently. If a thread acquires the lock, all other threads must wait until that thread is finished. In other words, this method becomes a potential bottleneck because only one thread can access it at a time and if there any additional processors on the machine they won't be used. </li></ul><ul><li>The solution is to use an anonymous method to create a closure and remove the shared state: </li></ul>
  44. 44. Uses – thread safety <ul><li>Even with the verbosity of anonymous methods, the code has been greatly reduced. And, assuming that &quot;g_Names&quot; will never be modified, this function could run concurrently on multiple threads and multiple cores without any synchronization. </li></ul>static List<string> GetNamesStartingWith(string startingText) { return g_Names.FindAll( delegate(string name) { return name.StartsWith(startingText); }); } static string g_StartingText; static bool NameStartsWith(string name) { return name.StartsWith(g_StartingText); } static List<string> GetNamesStartingWith(string startingText) { g_StartingText = startingText; return g_Names.FindAll(NameStartsWith); }
  45. 45. Uses – thread safety – use OO <ul><li>Yeah but can use alternative OO technique: </li></ul>class Searcher { string g_StartingText; // local to each instance  public Searcher(string s) { g_StartingText = s; } public bool NameStartsWith(string name) { return name.StartsWith(g_StartingText); } } static List<string> GetNamesStartingWith(string startingText) { Searcher s = new Searcher(startingText); // use object to hide shared state return g_Names.FindAll(s.NameStartsWith); }
  46. 46. Uses - new control structures <ul><li>Closures allow you to add new control structures to your language. With closures, such language constructs become unnecessary (Ruby has only very primitive native looping constructs) because you can define your own. </li></ul><ul><li>Because closures delay evaluation—i.e., they do not &quot;do&quot; anything until they are called—they can be used to define control structures. </li></ul><ul><li>For example, all Smalltalk's standard control structures, including branches (if/then/else) and loops (while and for), are defined using objects whose methods accept closures. Users can easily define their own control structures as well. </li></ul>
  47. 47. Uses - new control structures <ul><li>It’s the ability to return out of the closure OR out of the enclosing method (Ruby has syntax for both) which allows new control structures to be built. </li></ul><ul><li>The latter return style (return out of the enclosing method) would lend itself to defining new control structure. </li></ul><ul><li>Example: ? </li></ul>
  48. 48. Uses - new control structures – Use OO <ul><li>Iterator? </li></ul><ul><li>Define an object model which supports pluggable algorithms for iteration control, passing in your “code block” as an object with a method in it. </li></ul>
  49. 49. Uses - function factory <ul><li>Function factory – define a function with a parameter for use later e.g. javascript this technique is a prelude to command pattern use in the next section </li></ul>function AdderFactory(y) { return function(x){return x + y;} } var MyFunc; if (whatever) MyFunc = AdderFactory(5); else MyFunc = AdderFactory(10); print(MyFunc(123)); // Either 133 or 128. The anonymous inner function remembers what the value of y was when it was returned, even though y has gone away by the time the inner function is called! We say that the inner function is closed over the containing scope, or for short, that the inner function is a closure.
  50. 50. Uses - function factory – Use OO <ul><li>Function factory – define a function with a parameter for use later e.g. javascript. Result is either 133 or 128. </li></ul>def AdderFactory(y): return lambda x : x + y if False: MyFunc = AdderFactory(5); else: MyFunc = AdderFactory(10); print MyFunc(123) class Adder: def __init__(self, y): self.y = y def Add(self, x): return x + self.y if False: o = Adder(5) else: o = Adder(10) print o.Add(123)
  51. 51. Uses – command Pattern <ul><li>Closures are also great for implementing the Command pattern. Command implementations that use objects must explicitly have their state set up for them, closures can just close over whatever state is around when they are created. </li></ul><ul><li>Provide parameters for functions  closure “object” = command object </li></ul><ul><li>The closure provides parameters for the execution of a function prior to the execution of that function. For example, when a function is to be provided as the first argument to the setTimout function that is common in web browser environments. </li></ul><ul><li>setTimeout( function(){alert(msg) }, 1000); </li></ul>
  52. 52. Uses - command Pattern <ul><li>Function 1 that returns a function 2 with state </li></ul><ul><li>Timer invokes function 2 (no params allowed – command pattern) </li></ul>
  53. 53. Uses - command Pattern – Use OO <ul><li>Technique came from javascript where there are no classes (as usually understood) and doing things functionally – calling functions – is prevalent. </li></ul><ul><li>Surely objects do this better/just as well? </li></ul><ul><ul><li>Configure an object and pass that in. </li></ul></ul><ul><ul><li>The Timer calls the .Execute() method. </li></ul></ul><ul><ul><li>I.e. just use the traditional Command Pattern </li></ul></ul>
  54. 54. Are Closures really that cool? <ul><li>The inventor of Python – Guido van Rossum – resists adding any further closure support to Python </li></ul><ul><ul><li>Anonymous lambdas are restricted to one statement </li></ul></ul><ul><ul><li>Otherwise you can use a named function </li></ul></ul><ul><li>Guido believes behaviour + data = instance (not closure) </li></ul><ul><li>Doesn’t want too much hard core “functional programming” weirdness to get into Python. Functional programming is a different paradigm! </li></ul><ul><li>Existing List Comprehensions cover 90% of use cases. </li></ul>
  55. 55. Summary – OO vs closures <ul><li>Arguably….  Stateful functions should be implemented as methods of classes. Behaviour + data = instance (not closure) </li></ul><ul><li>In Javascript you e.g. create “objects” via functions birthing closure functions with various params plugged in. Apparently you get used to this alternative OO paradigm, and still do OO coding as normal - eventually. </li></ul><ul><li>There are many paradigms for programming – lets not build too many techniques into the one language or we confuse people </li></ul><ul><li>Objects can do anything that closures can </li></ul><ul><li>Zen parable – study both and discover that each can do what the other can. Enlightenment. </li></ul>

×