Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Closures

Name: Anonymous 2011-05-23 0:34

can someone explain them to me.. I'm thinken they might be simple but my pee sized brain can't comprehend most definitions off of google

Name: Anonymous 2011-05-23 0:39

I don't think pee has a size. Maybe a bucket of pee, but not pee in general.

Name: Anonymous 2011-05-23 0:41

>>1
Arright. We can do this. We'll use Haskell as an example, since I'm more comfortable with it than Lisp, and Javascript is a pain in the ass.

A closure is a data structure that functional languages use to represent a half-called function. It has some of its arguments specified, but not all of them. You can pass it around as an object, and use it as a function, but it still needs more arguments specified before it will actually trigger.

Consider a function called add:


add :: Int -> Int -> Int
add x y = x + y


If you write z = (add 1), then z is now the following function:


z :: Int -> Int
z y = 1 + y


z is a closure of add. This also means that the syntax (add 1) 2 is equivalent to add 1 2.

Name: Anonymous 2011-05-23 0:43

For the record, this has nothing to do with a transitive closure, which is just applying a translation relationship until you produce a closed set.

Name: Anonymous 2011-05-23 0:45

Name: Anonymous 2011-05-23 0:50

>>5
That form of closure is a lot uglier than the nice, simple Haskell kind :<

Name: Anonymous 2011-05-23 1:08

>>3
I think i get it so you set z as a function pointer to add with the first parameter as 1 but insufficient params will not allow it to execute

Name: Anonymous 2011-05-23 1:16

Closures are simple.
Think of a function. Now think about the arguments and local variables. Local variables only exist within the scope of the function, that is, they are defined only within the function itself and lose their value upon exit (or they could be defined within the scope of some inner block). Arguments are similar to the locals, but they are passed from the caller function.
Now imagine you could wrap around a variable binding around the function (be it a named one, a lambda or whatever), the binding would expire when it's out of the context of itself, but within it, you have defined a function (or maybe more), thus this variable should be accessible from within the function. Should it be a global accessible from other functions outside its scope? No, it would be out of scope. What happens if you define a function (like a lambda) within another function, and you access one of the variables within the upper function from the lower function? They form a closure, that is, the inner function holds references to those variables and can change them or access them as it wishes.

In simplest terms, a closure is just some object holding a function (piece of code) and references to some variables, usually local variables defined in a heap. The variables may end up being shared by other pieces of code (such as other functions, closures, etc). The function (piece of code) knows how to access objects closed around it, the compiler takes care of how this is implemented (there are a variety of ways of implementing this, so I'm not going to give specifics, but a simple way of imagining a closure would be an instance of some class with the members being the variables and the only method being the closed over function).

Name: Anonymous 2011-05-23 1:17

>>3
z is a closure of add. This also means that the syntax (add 1) 2 is equivalent to add 1 2.
It also means you can't have &rest, &key and dynamic typing. It also means you have a duplicate functionality (a sign of bad design), which is already handled by lambda.


$ ghci
GHCi, version 6.8.2: http://www.haskell.org/ghc/  :? for help
Loading package base ... linking ... done.
Prelude> let fac 1 = 1; fac n = n * (fac n-1)
Prelude> (fac 4)
*** Exception: stack overflow
Prelude>

Name: Anonymous 2011-05-23 1:25

>>9
Nice parenthesis usage.
GHCi, version 7.0.1.20101209: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
Prelude> let fac 1 = 1; fac n = n * (fac [u][o](n - 1)[/o][/u])
Prelude> (fac 4)
24
Prelude>

Name: Anonymous 2011-05-23 1:26

aaaaaaaaaaaah noooooo
GHCi, version 7.0.1.20101209: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
Prelude> let fac 1 = 1; fac n = n * (fac [o][u](n - 1)[/u][/o])
Prelude> (fac 4)
24
Prelude>

Name: Anonymous 2011-05-23 1:29

>>10
In my Lisp DSL, fac 1 -> 1; fac N -> N * (fac N-1) works nicely, but haskell's syntax is horrible illogical mess at best.

Name: Anonymous 2011-05-23 1:31

now I just give up.

You need parenthesis around (n - 1). That's just how it works. As a lisper you should already be comfortable with Lots of Idiotic Superfluous Parentheses!

>>7 That's the idea, yeah. Now, the grown-up version of closures used in other languages has it so that you freeze functions in place with access to all of the variables they could get at when they were first made into a closure. If dynamic scope is used, this can have a lot of consequences.

Name: Anonymous 2011-05-23 1:44

>>13
As a lisper you should already be comfortable with Lots of Idiotic Superfluous Parentheses!
Lisp's parentheses follow simple, logical rules.

Name: Anonymous 2011-05-23 1:48

>>14

So do Haskell's. You just need to use real (+) operators, and you can S-express yourself to your heart's content.

Name: Anonymous 2011-05-23 2:14

>>15
Sometimes, you’re on a team, and you’re busy banging out the code, and somebody comes up to your desk, coffee mug in hand, and starts rattling on about how if you use multi-threaded COM apartments, your app will be 34% sparklier, and it’s not even that hard, because he’s written a bunch of templates, and all you have to do is multiply-inherit from 17 of his templates, each taking an average of 4 arguments, and you barely even have to write the body of the function. It’s just a gigantic list of multiple-inheritance from different classes and hey, presto, multi-apartment threaded COM. And your eyes are swimming, and you have no friggin’ idea what this frigtard is talking about, but he just won’t go away, and even if he does go away, he’s just going back into his office to write more of his clever classes constructed entirely from multiple inheritance from templates, without a single implementation body at all, and it’s going to crash like crazy and you’re going to get paged at night to come in and try to figure it out because he’ll be at some goddamn “Design Patterns” meetup.

Name: Anonymous 2011-05-23 2:38

>>16
I agree completely. Sadly? This is how most code monkeys perceive functional programming.

Name: Anonymous 2011-05-23 2:45

>>9
It also means you have a duplicate functionality (a sign of bad design), which is already handled by lambda.
Aren't you an idiot? Do you know what a curried function is?

Name: Anonymous 2011-05-23 2:51

>>18

(lambda (x) (+ x 1))

Name: Anonymous 2011-05-23 2:51

>>17
C++ templates are functional. Just look at STL.

Name: Anonymous 2011-05-23 2:52

It needs to be said very firmly that LISP is not a functional language at all. My suspicion is that the success of Lisp set back the development of a properly functional style of programming by at least ten years. -- David Turner, inventor of Miranda

Name: Anonymous 2011-05-23 3:14

>>21
No shit, sherlock. It's a multiparadigm language. And functional programming alone is not a silver bullet. Don't perceive it as such.

Name: Anonymous 2011-05-23 3:48

the success of Lisp
Does not compute.

Name: Anonymous 2011-05-23 4:00

>>19
That's partial application.

Name: Anonymous 2011-05-23 4:02

>>24
Haskells (+ 1) is partial application.

Name: Anonymous 2011-05-23 4:05

>>25
It's not. (+) is a curried function.

Name: Anonymous 2011-05-23 4:05

Lisp:

$ sbcl
This is SBCL 1.0.11.debian, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>;.

* +3
3
*


Haskell:

$ ghci
GHCi, version 6.8.2: http://www.haskell.org/ghc/  :? for help
Loading package base ... linking ... done.
Prelude> +3
<interactive>:1:0: parse error on input `+'
Prelude>

Name: Anonymous 2011-05-23 4:06

>>27
God, you really are a moron.

Name: Anonymous 2011-05-23 4:06

curried function = partial application

Name: Anonymous 2011-05-23 4:06

>>29
No.

Name: Anonymous 2011-05-23 4:09

http://en.wikipedia.org/wiki/Currying
currying is the technique of transforming a function that takes multiple arguments in such a way that it can be called with a single argument (partial application)

Name: Anonymous 2011-05-23 4:11

>>28
God
better being a moron, than believing in God and using Haskell.

http://en.wikipedia.org/wiki/Simon_Peyton_Jones
>married to Dorothy, a priest in the Church of England

Name: Anonymous 2011-05-23 4:21

>>31
(define (f x y z) (+ x (- y z))
(define f-curried ((curry f) 2))
(define f-partially-applied (papply f 2))

(f-curried 3 4) ; should be an error
((f-curried 3) 4) ; ok
(f-partially-applied 3 4) ; ok
((f-partially-applied 3) 4) ; should be an error

(curry f) ≡ (lambda (x) (lambda (y) (lambda (z) (f x y z))))
(papply f . a) ≡ (lambda b (apply f (append a b)))


In Lisp:
(defun f (x y z) (+ x (- y z)))
(setf (symbol-function 'f-curried) (funcall (curry f) 2))
(setf (symbol-function 'f-partially-applied) (papply f 2))

(f-curried 3 4) ; error
(funcall (f-curried 3) 4) ; ok
(f-partially-applied 3 4) ; ok
(funcall (f-partially-applied 3) 4) ; error


Haskell's functions all take only one argument. Functions with multiple arity are curried, they return a function that takes the other arguments.

From the page you just linked: http://en.wikipedia.org/wiki/Currying#Contrast_with_partial_function_application
From Partial Application: http://en.wikipedia.org/wiki/Partial_application#Definitions

Name: Anonymous 2011-05-23 4:23

>>32
I don't use Haskell, it disgusts me. I don't believe in God, but I don't shove my ``atheism'' down the throat of everyone. Even if I was a religious Haskeller, that wouldn't make you any less ignorant.

Name: Anonymous 2011-05-23 4:26

>>33
You neglect to mention that Haskell will never leave academic circles.

In other words, it's a SHIT language.

Name: Anonymous 2011-05-23 4:28

>>35
Who cares about Haskell.

Name: Anonymous 2011-05-23 4:29

>>33
Practical difference is insignificant and nobody cares about useless haskell theory.

) ≡ (
wut?

>>34
Ignorance of Haskell is bliss, because if you're interested in statically typed language, something is wrong with you.

Name: Anonymous 2011-05-23 4:31

>>35
Also, enjoy defining switch as ``multiple ifs''.

Name: Anonymous 2011-05-23 4:32

Also, being ignorant of Haskell (misusing concepts and confusing syntax) is a way to demonstrate that Haskell is too hard learn and easy to get wrong.

Name: Anonymous 2011-05-23 4:34

>>37
It's not Haskell theory, they are two different things, whose general use usually overlaps.

wut?
Learn to Unicode, or you don't use it because it has Jewish characters in it?

Ignorance of Haskell is bliss, because if you're interested in statically typed language, something is wrong with you.
No, you're ignorant in general.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List