Beefy Boxes and Bandwidth Generously Provided by pair Networks Bob
Keep It Simple, Stupid
 
PerlMonks  

Re: Why Closures?

by frankus (Priest)
on Apr 26, 2001 at 18:07 UTC ( #75798=note: print w/ replies, xml ) Need Help??


in reply to Why Closures?

For me at present, at worst a closure does the job of a static variable, at best it can be likened to a very simple object1.

sub function_called { my $calls = 0; return { return ++$callS } }
or

A larger closure to enable a generic SQL template maker and deployer.

sub late_bound_sql { my $string = join ('',@_); # collate args into SQL statement. my $late_bound_fields = m/ \? /g; # Count late bound fields. my $sql = $dbh->prepare($string); # Create sql template. return sub { return 0 if $#_ != $late_bound_fields; # bad param count. for (0..$#_) { # For each argument, assume in sequence. $sql->bind_param($_, $_[$_]); # Apply bind param. } if ($sql->execute()) { # Do _this_ sql. return 1; } else { return 0; } } } # Create closures. $lb1 = late_bound("INSERT INTO foo VALUES ( x = ?, y = ?) "); $lb2 = late_bound("INSERT INTO bar, VALUES (a = ?, b = NULL)"); # Use them. &$lb1(2,4); # Inserts x= 2, y= 4 to table foo. &$lb2("cuttlefish"); # Inserts a= cuttlefish, b= NULL to table bar
I make no claims as to the accuracy of this code, it's a variation, of one I did a while ago, without nice validation or passing, but enough I hope to clarify what I meant ;-)

--
Brother Frankus.


Comment on Re: Why Closures?
Select or Download Code
Re (tilly) 2: Why Closures?
by tilly (Archbishop) on Apr 26, 2001 at 21:25 UTC
    While closures may look like a poor man's object, I think the reverse is closer to the case.

    Using only closures you can build an OO system, with what looks like an OO syntax. I believe that Smalltalk's OO system works like this. Definitely Lisp's CLOS does.

    By making classes multiply like rabbits, you can mechanically translate code involving closures into code involving objects. But I am having trouble seeing how you could make those closures integrate into an OO language and look like they do in a functional language. (Perhaps my imagination is not very good though.)

    Anyways what I find that closures do which OO does not do so well is allow you to "inline" logic that in OO programming would involve having to create classes and methods just to do a small thing, privately, within a function.

    For instance take the DESTROY method. Perl offers a way to use it in an OO context. If I want to set up some sort of finalizing action on something, I can always create a class, with a constructor and a DESTROY method. Each different kind of action requires a whole class. Ick.

    However if you look at my ReleaseAction, it allows you to do the same thing, with the action defined by a closure. Now you can, within a small function, define any useful DESTROY behaviour that you need, without having to create a class for it. That allows you to put the definition of the behaviour where it is most maintainable, right where you need it. What you are doing isn't fundamentally different, but you think about it more compactly.

    Let me step back, and explain that differently, since in trying to say it I think I figured out a better way to understand it.

    Conceptually an object is the concept of a thing with multiple customized behaviours, and with a defined structure for building a system with lots of objects, some of which share some of the same (or similar) behaviours.

    Conceptually a closure is the concept of a thing with a customized behaviour.

    It turns out that closures are general enough to allow you to build arbitrary objects. They may not look like they can do that, but they can.

    However if what you need is a customized behaviour, objects have a ton of baggage that you cannot shed. This forces you to structure your code in a less natural manner for the ideas expressed, and that overhead limits how you tend to think about problems, forces unnecessary duplication of code, etc, etc. As a result there are solutions that are quite natural using closures which people do not naturally build without them. (And if they tried to build those solutions without closures, the result would be an order of magnitude less efficient, but I digress.)

    UPDATE
    In reply to hding, CLOS may not need to be implemented with closures, but it is possible to do so. Also note that I tend to be somewhat sloppy in my wording. When I start throwing around anonymous functions, I tend to call them closures even though the functions I am passed might not really be closures.

      Using only closures you can build an OO system, with what looks like an OO syntax. I believe that Smalltalk's OO system works like this. Definitely Lisp's CLOS does.

      I'm not so sure that I'd say that CLOS needs to use closures to quite the extent you imply. Take a look for example at the Closette implementation found in The Art of the Metaobject Protocol. I think it's an exaggeration to say that this uses only (or even primarily) closures to do its work.

      Update

      In reply to tilly's update :-) (Let me first qualify that IANALI - I am not a Lisp implementor - take me with the appropriate grain of salt.) Certainly it's possible to do the same thing with closures. And I cheated a little bit - the Closette implementation is a simple one that has a few problems which AMOP suggests are probably overcome using closures. But I'd be surprised if any widely used CLOS implementation is largely in terms of closures - I'd expect it to be more the melange of imperative, OO, and functional programming that is Common Lisp (and that is evidenced in Closette). It wouldn't surprise me, though, if some of the Scheme object systems out there were a little more functional, and if anyone around here knows, it'd be interesting to know how its done in OCaml, which is a much more functional language than CL.

      I think your point is that a system of closures is probably more powerful than a system of objects. I don't disagree with that [ I won't go quite so far as to agree, but I do suspect that you might be right (: ]. I think that frankus' point was that a single closure is very much like a single, very simple object. I will go so far as to completely agree with that.

      A closure is very much like an object with a single method. This can be a great advantage if you want "an object with a single method" because a closure doesn't require you to create all of that OO baggage (most notably a class name that must fit into a global namespace).

      Since I'm standing up here and some of you are looking at me, here is my breakdown of the major programming methodologies supported by Perl:

      Procedural programming has data and subroutines and you associate them together "by hand". Object-oriented programming has data where each type of data is tightly associated with a collection of subroutines. Functional programming treats subroutines as data and allows you to associate items of data with each subroutine.

      Now, if you do a whole project using one methodology, then more differences crop up. But I like to mix methodologies in Perl so those are the main difference for me.

      So if I want a collection of subroutines that work on similar data, I'll create a class (and make it a module).

      If I have a single subroutine that works on different instances of similar data, then I have to decide whether I'm likely to want to add more subroutines later. If so, I'll make a class. If not, I'll make closures.

      If I have a chunk of behavior that I want to allow people to change, then I'll probably use a code reference. If that behavior should be associated to different instance of similar data, then I'll use a closures.

              - tye (but my friends call me "Tye")

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://75798]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (6)
As of 2014-04-17 23:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (459 votes), past polls