Jump to content
Main menu
Main menu
move to sidebar
hide
Navigation
Main page
Recent changes
Random page
Help about MediaWiki
Special pages
Niidae Wiki
Search
Search
Appearance
Create account
Log in
Personal tools
Create account
Log in
Pages for logged out editors
learn more
Contributions
Talk
Editing
Closure (computer programming)
(section)
Page
Discussion
English
Read
Edit
View history
Tools
Tools
move to sidebar
hide
Actions
Read
Edit
View history
General
What links here
Related changes
Page information
Appearance
move to sidebar
hide
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
=== Closure leaving === Yet more differences manifest themselves in the behavior of other lexically scoped constructs, such as <code>return</code>, <code>break</code> and <code>continue</code> statements. Such constructs can, in general, be considered in terms of invoking an [[escape continuation]] established by an enclosing control statement (in case of <code>break</code> and <code>continue</code>, such interpretation requires looping constructs to be considered in terms of recursive function calls). In some languages, such as ECMAScript, <code>return</code> refers to the continuation established by the closure lexically innermost with respect to the statement—thus, a <code>return</code> within a closure transfers control to the code that called it. However, in [[Smalltalk]], the superficially similar operator <code>^</code> invokes the escape continuation established for the method invocation, ignoring the escape continuations of any intervening nested closures. The escape continuation of a particular closure can only be invoked in Smalltalk implicitly by reaching the end of the closure's code. These examples in ECMAScript and Smalltalk highlight the difference: <syntaxhighlight lang="smalltalk"> "Smalltalk" foo | xs | xs := #(1 2 3 4). xs do: [:x | ^x]. ^0 bar Transcript show: (self foo printString) "prints 1" </syntaxhighlight> <syntaxhighlight lang="javascript"> // ECMAScript function foo() { var xs = [1, 2, 3, 4]; xs.forEach(function (x) { return x; }); return 0; } alert(foo()); // prints 0 </syntaxhighlight> The above code snippets will behave differently because the Smalltalk <code>^</code> operator and the JavaScript <code>return</code> operator are not analogous. In the ECMAScript example, <code>return x</code> will leave the inner closure to begin a new iteration of the <code>forEach</code> loop, whereas in the Smalltalk example, <code>^x</code> will abort the loop and return from the method <code>foo</code>. [[Common Lisp]] provides a construct that can express either of the above actions: Lisp <code>(return-from foo x)</code> behaves as [[Smalltalk]] <code>^x</code>, while Lisp <code>(return-from nil x)</code> behaves as [[JavaScript]] <code>return x</code>. Hence, Smalltalk makes it possible for a captured escape continuation to outlive the extent in which it can be successfully invoked. Consider: <syntaxhighlight lang="smalltalk"> "Smalltalk" foo ^[ :x | ^x ] bar | f | f := self foo. f value: 123 "error!" </syntaxhighlight> When the closure returned by the method <code>foo</code> is invoked, it attempts to return a value from the invocation of <code>foo</code> that created the closure. Since that call has already returned and the Smalltalk method invocation model does not follow the [[spaghetti stack]] discipline to facilitate multiple returns, this operation results in an error. Some languages, such as [[Ruby (programming language)|Ruby]], enable the programmer to choose the way <code>return</code> is captured. An example in Ruby: <syntaxhighlight lang="ruby"> # Ruby # Closure using a Proc def foo f = Proc.new { return "return from foo from inside proc" } f.call # control leaves foo here return "return from foo" end # Closure using a lambda def bar f = lambda { return "return from lambda" } f.call # control does not leave bar here return "return from bar" end puts foo # prints "return from foo from inside proc" puts bar # prints "return from bar" </syntaxhighlight> Both <code>Proc.new</code> and <code>lambda</code> in this example are ways to create a closure, but semantics of the closures thus created are different with respect to the <code>return</code> statement. In [[Scheme (programming language)|Scheme]], definition and scope of the <code>return</code> control statement is explicit (and only arbitrarily named 'return' for the sake of the example). The following is a direct translation of the Ruby sample. <syntaxhighlight lang="Scheme"> ; Scheme (define call/cc call-with-current-continuation) (define (foo) (call/cc (lambda (return) (define (f) (return "return from foo from inside proc")) (f) ; control leaves foo here (return "return from foo")))) (define (bar) (call/cc (lambda (return) (define (f) (call/cc (lambda (return) (return "return from lambda")))) (f) ; control does not leave bar here (return "return from bar")))) (display (foo)) ; prints "return from foo from inside proc" (newline) (display (bar)) ; prints "return from bar" </syntaxhighlight>
Summary:
Please note that all contributions to Niidae Wiki may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
Encyclopedia:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Search
Search
Editing
Closure (computer programming)
(section)
Add topic