Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
First-class function
(section)
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!
== Language support == Functional programming languages, such as [[Erlang (programming language)|Erlang]], [[Scheme (programming language)|Scheme]], [[ML (programming language)|ML]], [[Haskell (programming language)|Haskell]], [[F Sharp (programming language)|F#]], and [[Scala (programming language)|Scala]], all have first-class functions. When [[Lisp (programming language)|Lisp]], one of the earliest functional languages, was designed, not all aspects of first-class functions were then properly understood, resulting in functions being dynamically scoped. The later [[Scheme (programming language)|Scheme]] and [[Common Lisp]] dialects do have lexically scoped first-class functions. Many scripting languages, including [[Perl]], [[Python (programming language)|Python]], [[PHP]], [[Lua (programming language)|Lua]], [[Tcl]]/Tk, [[JavaScript]] and [[Io (programming language)|Io]], have first-class functions. For imperative languages, a distinction has to be made between Algol and its descendants such as Pascal, the traditional C family, and the modern garbage-collected variants. The Algol family has allowed nested functions and higher-order taking function as arguments, but not higher-order functions that return functions as results (except Algol 68, which allows this). The reason for this was that it was not known how to deal with non-local variables if a nested-function was returned as a result (and Algol 68 produces runtime errors in such cases). The C family allowed both passing functions as arguments and returning them as results, but avoided any problems by not supporting nested functions. (The gcc compiler allows them as an extension.) As the usefulness of returning functions primarily lies in the ability to return nested functions that have captured non-local variables, instead of top-level functions, these languages are generally not considered to have first-class functions. Modern imperative languages often support garbage-collection making the implementation of first-class functions feasible. First-class functions have often only been supported in later revisions of the language, including C# 2.0 and Apple's Blocks extension to C, C++, and Objective-C. C++11 has added support for anonymous functions and closures to the language, but because of the non-garbage collected nature of the language, special care has to be taken for non-local variables in functions to be returned as results (see below). {| class=wikitable width=100% style="font-size: 85%" ! colspan=2 rowspan=2 | Language !! colspan=2 | [[Higher-order function]]s !! colspan=2 | [[Nested function]]s !! colspan=2 | [[Non-local variable]]s !! rowspan=2 width=25% | Notes |- ! Arguments !! Results !! Named !! [[Anonymous function|Anonymous]] !! [[Closure (computer programming)|Closures]] !! [[Partial application]] |- | rowspan=6 | Algol family | [[ALGOL 60]] || {{yes}} || {{no}} || {{yes}} || {{no}} || {{partial|Downwards}} || {{no}} || rowspan=6 | Have [[function type]]s. |- | [[ALGOL 68]] || {{yes}} || {{Partial|Yes}}<ref name=compa68pascal>{{cite journal|page=319|title=A comparison of PASCAL and Algol 68|journal=The Computer Journal|volume=21|number=4|year=1977|first=A.S.|last=Tanenbaum|doi=10.1093/comjnl/21.4.316|doi-access=free|url=https://research.vu.nl/files/110789276/11054}}</ref> || {{yes}} || {{yes}} || {{partial|Downwards}}<ref>{{Cite web|url=http://python-history.blogspot.nl/2009/04/origins-of-pythons-functional-features.html?showComment=1243166621952#c702829329923892023|title = The History of Python: Origins of Python's "Functional" Features|date = 21 April 2009}}</ref> || {{no}} |- | [[Pascal (programming language)|Pascal]] || {{yes}} || {{no}} || {{yes}} || {{no}} || {{partial|Downwards}} || {{no}} |- | [[Ada (programming language)|Ada]] || {{yes}} || {{no}} || {{yes}} || {{no}} || {{partial|Downwards}} || {{no}} |- | [[Oberon (programming language)|Oberon]] || {{yes}} || {{partial|Non-nested only}} || {{yes}} || {{no}} || {{partial|Downwards}} || {{no}} |- | [[Delphi (programming language)|Delphi]] || {{yes}} || {{yes}} || {{yes}} || {{yes|2009}} || {{yes|2009}} || {{no}} |- | rowspan=9 | C family | [[C (programming language)|C]] || {{yes}} || {{yes}} || {{Partial|Yes in GNU C}} || {{Partial|Yes in Clang([[Blocks (C language extension)|Blocks]])}} || {{Partial|Yes in Clang([[Blocks (C language extension)|Blocks]])}} || {{no}} || Has [[function pointer]]s. |- | [[C++]] || {{yes}} || {{yes}} || {{yes|C++11<ref>[https://stackoverflow.com/a/4324829 Nested functions using lambdas/closures]</ref>}} || {{yes|C++11}}<ref name=doc1968>Doc No. [http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1968.pdf 1968]: V Samko; J Willcock, J JΓ€rvi, D Gregor, A Lumsdaine (February 26, 2006) ''Lambda expressions and closures for C++''</ref> || {{partial|C++11}}<ref name=doc1968/> || {{partial|C++11}} || Has function pointers, [[function object]]s. (Also, see below.) Explicit partial application possible with <code>std::bind</code>. |- | [[C Sharp (programming language)|C#]] || {{yes}} || {{yes}} || {{yes|7}} || {{yes|2.0 / 3.0}} || {{yes|2.0}} || {{yes|3.0}} || Has [[Delegate (CLI)|delegate]]s (2.0) and lambda expressions (3.0). |- | [[Objective-C]] || {{yes}} || {{yes}} || {{partial|Using anonymous}} || {{yes|2.0 + Blocks<ref>{{cite web |url=https://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html |url-status=dead |archive-url=https://web.archive.org/web/20090831133626/http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html |archive-date=2009-08-31 |title=Mac Dev Center: Blocks Programming Topics: Introduction}}</ref>}} || {{yes|2.0 + Blocks}} || {{no}} || Has function pointers. |- | [[Java (programming language)|Java]] || {{yes}} || {{yes}} || {{partial|Using anonymous}} || {{yes|Java 8}} || {{yes|Java 8}} || {{yes}} || Has [[anonymous inner class]]es. |- | [[Go (programming language)|Go]] || {{yes}} || {{yes}} || {{partial|Using anonymous}} || {{yes}} || {{yes}} || {{yes}}<ref>{{cite web |url=https://play.golang.org/p/lZHXrX-yR6 |title=2 examples in Go that you can have partial application }}</ref> || |- | [[Limbo (programming language)|Limbo]] || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{no}} || |- | [[Newsqueak]] || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{no}} || |- | [[Rust (programming language)|Rust]] || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}}<ref>{{cite web |url=https://docs.rs/partial_application |title=partial_application |website=Docs.rs |access-date=2020-11-03}}</ref> || |- | rowspan=12 | Functional languages || [[Lisp (programming language)|Lisp]] || {{partial|Syntax}} || {{partial|Syntax}} || {{yes}} || {{yes}} || {{partial|Common Lisp}} || {{no}} || (see below) |- | [[Scheme (programming language)|Scheme]] || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes|SRFI 26}}<ref>{{Cite web|url=http://srfi.schemers.org/srfi-26/srfi-26.html|title=SRFI 26: Notation for Specializing Parameters without Currying}}</ref> || |- | [[Julia (programming language)|Julia]] || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || |- | [[Clojure]] || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || |- | [[ML (programming language)|ML]] || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || |- | [[Haskell (programming language)|Haskell]] || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || |- | [[jq (programming language)|jq]] || {{yes}} || {{no}} || {{yes}} ||{{partial|Expressions only}} || {{partial|Downwards}} || {{no}} |- | [[Scala (programming language)|Scala]] || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || |- | [[Erlang (programming language)|Erlang]] || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || |- | [[Elixir (programming language)|Elixir]] || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || |- | [[F Sharp (programming language)|F#]] || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || |- | [[OCaml]] || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || |- | rowspan=7 | Scripting languages | [[Io (programming language)|Io]] || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{no}} || |- | [[JavaScript]] || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes|ECMAScript 5}} || Partial application possible with user-land code on ES3 <ref>{{Cite web|url=http://ejohn.org/blog/partial-functions-in-javascript/|title=John Resig - Partial Application in JavaScript}}</ref> |- | [[Lua (programming language)|Lua]] || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}}<ref>{{cite web |last1=Katz |first1=Ian |url=http://tinylittlelife.org/?p=249 |title=Lua Code for Curry (Currying Functions) |date=2010-07-23 |df=mdy |archive-url=https://web.archive.org/web/20181106235506/http://tinylittlelife.org/?p=249 |archive-date=2018-11-06}}</ref> || |- | [[PHP]] || {{yes}} || {{yes}} || {{partial|Using anonymous}} || {{yes|5.3}} || {{yes|5.3}} || {{no}} || Partial application possible with user-land code. |- | [[Perl]] || {{yes}} || {{yes}} || {{yes|6}} || {{yes}} || {{yes}} || {{yes|6}}<ref>{{Cite web|url=http://perlgeek.de/blog-en/perl-5-to-6/28-currying.html|title = Blog | Perlgeek.de :: Currying}}</ref> || |- | [[Python (programming language)|Python]] || {{yes}} || {{yes}} || {{yes}} || {{partial|Expressions only}} || {{yes}} || {{yes|2.5}}<ref>{{Cite web|url=https://docs.python.org/whatsnew/2.5.html#pep-309-partial-function-application|title=What's New in Python 2.5 β Python 3.10.0 documentation}}</ref> || (see below) |- | [[Ruby (programming language)|Ruby]] || {{partial|Syntax}} || {{partial|Syntax}} || {{no|Unscoped}} || {{yes}} || {{yes}} || {{partial|1.9}} || (see below) |- | rowspan=6 | Other languages | [[Fortran]] || {{yes}} || {{yes}} || {{yes}} || {{no}} || {{no}} || {{no}} || |- | [[Maple (software)|Maple]] || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{no}} || |- | [[Mathematica]] || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{no}} || |- | [[MATLAB]] || {{yes}} || {{yes}} || {{yes}} || {{yes}}<ref>{{Cite web|url=http://www.mathworks.co.uk/help/matlab/matlab_prog/anonymous-functions.html|title=Anonymous Functions - MATLAB & Simulink - MathWorks United Kingdom}}</ref> || {{yes}} || {{yes}} || Partial application possible by automatic generation of new functions.<ref>[https://stackoverflow.com/q/9154271 Partial Function Evaluation in MATLAB]</ref> |- | [[Smalltalk]] || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{partial}} || Partial application possible through library. |- | [[Swift (programming language)|Swift]] || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || {{yes}} || |} ; C++: [[C++11]] closures can capture non-local variables by copy construction, by reference (without extending their lifetime), or by [[C++11#Rvalue references and move constructors|move construction]] (the variable lives as long as the closure does). The first option is safe if the closure is returned but requires a copy and cannot be used to modify the original variable (which might not exist any more at the time the closure is called). The second option potentially avoids an expensive copy and allows to modify the original variable but is unsafe in case the closure is returned (see [[dangling reference]]s). The third option is safe if the closure is returned and does not require a copy but cannot be used to modify the original variable either. ; Java: [[Java 8]] closures can only capture final or "effectively final" non-local variables. Java's [[function type]]s are represented as Classes. Anonymous functions take the type inferred from the context. Method references are limited. For more details, see {{slink|Anonymous function|Java limitations}}. ; Lisp : [[Lexically scoped]] Lisp variants support closures. [[Dynamically scoped]] variants do not support closures or need a special construct to create closures.<ref>[https://common-lisp.net/project/bknr/static/lmman/fd-clo.xml Closures in ZetaLisp] {{webarchive|url=https://web.archive.org/web/20120319071329/http://common-lisp.net/project/bknr/static/lmman/fd-clo.xml |date=2012-03-19 }}</ref> : In [[Common Lisp]], the identifier of a function in the function namespace cannot be used as a reference to a first-class value. The special operator <code>function</code> must be used to retrieve the function as a value: <code>(function foo)</code> evaluates to a function object. <code>#'foo</code> exists as a shorthand notation. To apply such a function object, one must use the <code>funcall</code> function: <code>(funcall #'foo bar baz)</code>. ; Python : Explicit partial application with <code>[https://docs.python.org/library/functools.html#functools.partial functools.partial]</code> since version 2.5, and <code>[https://docs.python.org/library/operator.html#operator.methodcaller operator.methodcaller]</code> since version 2.6. ; Ruby : The identifier of a regular "function" in Ruby (which is really a method) cannot be used as a value or passed. It must first be retrieved into a <code>Method</code> or <code>Proc</code> object to be used as first-class data. The syntax for calling such a function object differs from calling regular methods. : Nested method definitions do not actually nest the scope. : Explicit currying with <code>[https://docs.ruby-lang.org/en/master/Proc.html#method-i-curry]</code>.
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)