CSC/ECE 517 Fall 2011/ch1 1d ss: Difference between revisions
Line 40: | Line 40: | ||
=== statically typed languages, difficulty === | === statically typed languages, difficulty === | ||
*We can explain this via an example. | |||
Method setBlock is defined as | |||
|n| | |||
... | |||
b := [ n >= 0 ifTrue: ^1 ifFalse: ^0 ]. | |||
where b is an instance variable.After calling setBlock, a method of the same class may be called and may execute the above block - b value. | |||
Inside the block there will be a return (^1 or ^0) from a method call of setBlock that no longer exists — a runtime error. | |||
<br> | |||
It seems impossible to add true closures to statically typed languages because of the above described run time errors.Although these errors may be considered as "type errors", they make the language unsafe which is against the norm of statically typed languages.[1] | |||
*Closures will need access to the lexical scope, ie, the scope in which the routine was generated as mentioned above. This is a problem for statically typed languages as they keep track of local variables in the stack. Once those variables go out of scope and the routine tries to access them, it will throw an exception. This problem must be overcome as closures must have access to that environment, even when it's out of scope. | *Closures will need access to the lexical scope, ie, the scope in which the routine was generated as mentioned above. This is a problem for statically typed languages as they keep track of local variables in the stack. Once those variables go out of scope and the routine tries to access them, it will throw an exception. This problem must be overcome as closures must have access to that environment, even when it's out of scope. | ||
*In order to accomplish this, the compiler must somehow keep the associated variables even when they go out of scope. In addition, since they must be first class functions, ie, the ability to use them as a normal data type, the statically typed language must have a specific type defined for functions. Also,in the case of Java and C# the garbage collector must keep those objects around, as well as their associated lexical environments, until there are no remaining references to that object. | *In order to accomplish this, the compiler must somehow keep the associated variables even when they go out of scope. In addition, since they must be first class functions, ie, the ability to use them as a normal data type, the statically typed language must have a specific type defined for functions. Also,in the case of Java and C# the garbage collector must keep those objects around, as well as their associated lexical environments, until there are no remaining references to that object. |
Revision as of 17:26, 8 September 2011
Closures in statically typed languages. Most languages that implement closures are dynamically typed. It is a challenge to implement closures in a statically typed language. Explain why, and cover attempts to mix the two. Consider also closures and static scoping, as in Scheme.
Introduction
We start off with a brief difference between statically and dynamically typed languages.We try to explain what a closure is, its advantages, how it can be implemented in various typed languages, why is it easier or difficult in some languages.Finally we conclude with static scoping.
statically vs dynamically typed
One simple way to differentiate between the two is:
In statically typed languages,type checking is done at the compile time where as in dynamically typed languages, type checking is done at run-time.
Examples of statically typed : C,C++,Java,JADE,Pascal etc
Examples of dynamically typed : PHP,Prolog,Python,Ruby,Small talk etc.[1]
Closures
In the words of Matsumoto, the creator of Ruby language: A closure object has code to run, the executable, and state around the code, the scope. So you capture the environment, namely the local variables, in the closure. As a result, you can refer to the local variables inside a closure. Even after the function has returned, and its local scope has been destroyed, the local variables remain in existence as part of the closure object. When no one refers to the closure anymore, it's garbage collected, and the local variables go away. [2]
what exactly is Closure
- A closure is a first-class block of code that has access to the environment in which it was defined.
- A first class function is one that can be passed around just like any other object.
- The function can access ‘free variables’, ie, variables that are not an argument to, or a local variable of that function. For example, if we have a function that returns a lambda function:
public Func<int,int> GetFunc() { int y = 4; Func<int, int> myfunc = x => { return x+y; }; return myfunc; }
y is neither an input parameter nor a local variable declared within myfunc. The free variable is bound in the lexical environment. This means that even when GetFunc goes out of scope, myfunc will still have access to it.
Advantages of Closures
- It allows access to contextual information that wouldn’t be available inside a standard method of a class.
- It can be passed around as an object and retain that context, even if the variables are outside their original scope.
- There is no need to pass around internal variables for every call.
- Offers a more concise and clean method of programming operations.
Implementation of Closures
In dynamically typed languages
statically typed languages, difficulty
- We can explain this via an example.
Method setBlock is defined as
|n| ... b := [ n >= 0 ifTrue: ^1 ifFalse: ^0 ].
where b is an instance variable.After calling setBlock, a method of the same class may be called and may execute the above block - b value.
Inside the block there will be a return (^1 or ^0) from a method call of setBlock that no longer exists — a runtime error.
It seems impossible to add true closures to statically typed languages because of the above described run time errors.Although these errors may be considered as "type errors", they make the language unsafe which is against the norm of statically typed languages.[1]
- Closures will need access to the lexical scope, ie, the scope in which the routine was generated as mentioned above. This is a problem for statically typed languages as they keep track of local variables in the stack. Once those variables go out of scope and the routine tries to access them, it will throw an exception. This problem must be overcome as closures must have access to that environment, even when it's out of scope.
- In order to accomplish this, the compiler must somehow keep the associated variables even when they go out of scope. In addition, since they must be first class functions, ie, the ability to use them as a normal data type, the statically typed language must have a specific type defined for functions. Also,in the case of Java and C# the garbage collector must keep those objects around, as well as their associated lexical environments, until there are no remaining references to that object.