Computer Science

Higher Order Functions

Higher order functions are functions that take other functions as arguments or return functions as their results. They are a fundamental concept in functional programming and allow for more concise and modular code. Higher order functions can be used to implement powerful abstractions such as map, filter, and reduce.

Written by Perlego with AI-assistance

4 Key excerpts on "Higher Order Functions"

  • Book cover image for: Functional Programming in C#
    eBook - PDF

    Functional Programming in C#

    Classic Programming Techniques for Modern Projects

    • Oliver Sturm(Author)
    • 2011(Publication Date)
    • Wiley
      (Publisher)
    Higher Order Functions are also important in functional programming. Higher Order Functions are those that take other functions as parameters or return other functions as their results. Many programming languages have some support for this capability. Even C has a syntax to define a type of a function or, in C terms, to refer to the function through a function pointer. Obviously this enables C programmers to pass around such function pointers or to return them from other functions. Many C libraries contain functions, such as those for searching and sorting, that are implemented as Higher Order Functions, taking the essential data-specific comparison functions as parameters. Then again, C doesn’t have any support for anonymous functions — that is, functions created on-the-fly, in-line, like lambda expressions, or for related concepts such as closures. Other examples of language capabilities that help define functional programming are explored in the following chapters in this book. For some programmers, functional programming is a natural way of telling the computer what it should do, by describing the properties of a given problem in a concise language. You might have heard the saying that functional programming is more about telling computers what the problem is they should be solving, and not so much about specifying the precise steps of the solution. This saying is a result of the high level of abstraction that functional programming provides. Referential transparency means that the only responsibility of the programmer is the specification of functions to describe and solve a given set of problems. On the basis of that specification, the computer can then decide on the best evaluation order, potential parallelization opportunities, or even whether a certain function needs to be evaluated at all. For some other programmers, functional programming is not the starting point. They come from a procedural, imperative, or perhaps object oriented background.
  • Book cover image for: Programming Language Design Concepts
    • David A. Watt(Author)
    • 2006(Publication Date)
    • Wiley
      (Publisher)
    This has a major impact on programming style. A function with a functional parameter or functional result is called a higher- order function. We frequently exploit higher-order functions to make code reusable, by abstracting over those parts of it that are specific to a particular application. Allowing a function to compute another function as its result opens up many interesting possibilities, which are heavily exploited in functional programming. The simplest way to generate a new function is by composing two existing functions, as the following example illustrates. EXAMPLE 14.5 HASKELL function composition The ‘‘.’’ operator composes two given functions, and is defined as follows: (.) :: (t -> u) -> (s -> t) -> (s -> u) -- f.g computes a function h such that h(x) = f(g(x)). f . g = \ x -> f(g(x)) Given the following library functions: not :: Bool -> Bool odd :: Int -> Bool we can compose them as follows: even = not . odd This defines a function even whose type is Int -> Bool. 14.3 Case study: HASKELL 377 EXAMPLE 14.6 HASKELL curried function Consider the following function: power :: (Int, Float) -> Float -- power(n, b) computes the nth power of b (assuming that n≥0). power(n, b) = if n = 0 then 1.0 else b * power(n-1, b) This function, when applied to a pair consisting of an integer and a real number, will compute a real number. For example, ‘‘power(2, x)’’ computes the square of x. Now consider the following closely related function: powerc :: Int -> Float -> Float -- powercnb computes the nth power of b (assuming that n≥0). powerc n b = if n = 0 then 1.0 else b * powerc (n-1) b This function, when applied to an integer n, will compute another function; the latter function, when applied to a real number, will compute the nth power of that real number. For example, ‘‘powerc 2 x’’ computes the square of x. The advantage of powerc is that we can call it with only one argument.
  • Book cover image for: Learn Kotlin Programming
    No longer available |Learn more

    Learn Kotlin Programming

    A comprehensive guide to OOP, functions, concurrency, and coroutines in Kotlin 1.3, 2nd Edition

    • Stephen Samuel, Stefan Bocutiu(Authors)
    • 2019(Publication Date)
    • Packt Publishing
      (Publisher)

    Higher-Order Functions and Functional Programming

    In Chapter 4 , Functions in Kotlin , we introduced Kotlin's support for functions and the various features we can use while writing functions. In this chapter, we continue on that theme by discussing higher-order functions and how we can use them to write cleaner and more expressive code.
    In this chapter, we will cover the following topics:
    • Higher-order functions and closures
    • Anonymous functions
    • Function references
    • Functional programming idioms
    • Custom
      domain-specific language (
      DSLs )
    Passage contains an image

    Higher-order functions

    A higher-order function is a function that either accepts another function as a parameter, returns a function as its return value, or both. Let's consider the first example: fun foo(str: String, fn: (String) -> String): Unit { val applied = fn(str) println(applied) }
    Here, we have defined a foo function with two parameters. The first is a string, and the second is a function from string to string. When we say from string to string, we mean the function accepts a string input and returns another string as the output. Also, note the syntax used to define the function parameter. The input types are wrapped in parentheses, and the output type is separated by a thin arrow.
    To invoke this function, we can pass in a function literal (function literals were introduced in Chapter 4 , Functions in Kotlin ):
    foo("hello", { it.reversed() })
    As you can see, the string we pass in is hello. This value is then passed as the input to the next function, which returns the reversed value. This is then printed out, so the result of this invocation would be to output olleh. Remember that a function literal that only has one argument can use it as a shortcut to avoid naming the argument explicitly.
    At this stage, you may be wondering why this is useful. After all, we could have written code like the following:
  • Book cover image for: Introduction to Programming Languages
    However, all the functional languages use constants and variables inside the definition of functions. Higher-order functions are formed using map function (called apply in Lisp), which takes a function name as input data along with its arguments and converts it into a function. Using map function, func-tional forms like construction, apply-all , and insertion can be simulated. Composition is allowed in functional languages, because functions can be called within a function. All the modern functional programming languages support conditional functions, iteration, and recursion. The recursive style of programming and iterators using linked lists is natu-ral to functional programming languages, because sequences are traditionally modeled as linked lists. The major drawback of the pure functional programming is (1) the lack of storage of the partial computation because of the lack of the support of global variables and destructive updates and (2) excessive use of recursive programming because of the lack of iterative style of programming. Many programming languages such as the Lisp family of languages have supported limited amount of destructive update and global variables. Most of the functional programming languages support while-loop functional and iterators that step through every element of a sequence. Common Lisp has an extensive iteration handling capability and supports definite-loops like dotimes. Lisp is one of the earliest programming languages that mixes functional programming paradigm with the limited imperative programming paradigm. Lisp is a well-developed language with an extensive library, and it has multiple variations and descendants that integrate with other programming paradigms. Lisp supports implicit parametric polymor-phism. Although traditionally the major representation of sequence is a linked list, arrays are also used extensively. Lisp also uses an associative property-list that supports (key, value) pairs.
Index pages curate the most relevant extracts from our library of academic textbooks. They’ve been created using an in-house natural language model (NLM), each adding context and meaning to key research topics.