- Julia 1.0 Programming Complete Reference Guide
- Ivo Balbaert Adrian Salceanu
- 571字
- 2021-06-24 14:21:44
First-class functions and closures
In this section, we will demonstrate the power and flexibility of functions (example code can be found in Chapter 3\first_class.jl). Firstly, functions have their own type: Function. Functions can also be assigned to a variable by their name:
julia> m = mult julia> m(6, 6) #> 36
This is useful when working with anonymous functions, such as c = x -> x + 2, or as follows:
julia> plustwo = function (x) x + 2 end (anonymous function) julia> plustwo(3) 5
Operators are just functions written with their arguments in an infix form; for example, x + y is equivalent to +(x, y). In fact, the first form is parsed to the second form when it is evaluated. We can confirm it in the REPL: +(3,4) returns 7 and typeof(+) returns Function.
A function can take a function (or multiple functions) as its argument, which calculates the numerical derivative of a function f; as defined in the following function:
function numerical_derivative(f, x, dx=0.01) derivative = (f(x+dx) - f(x-dx))/(2*dx) return derivative end
The function can be called as numerical_derivative(f, 1, 0.001), passing an anonymous function f as an argument:
f = x -> 2x^2 + 30x + 9 println(numerical_derivative(f, 1, 0.001)) #> 33.99999999999537
A function can also return another function (or multiple functions) as its value. This is demonstrated in the following code, which calculates the derivative of a function (this is also a function):
function derivative(f) return function(x) # pick a small value for h h = x == 0 ? sqrt(eps(Float64)) : sqrt(eps(Float64)) * x xph = x + h dx = xph - x f1 = f(xph) # evaluate f at x + h f0 = f(x) # evaluate f at x return (f1 - f0) / dx # divide by h end end
As we can see, both are excellent use cases for anonymous functions.
Here is an example of a counter function that returns (a tuple of) two anonymous functions:
function counter() n = 0 () -> n += 1, () -> n = 0 end
We can assign the returned functions to variables:
(addOne, reset) = counter()
Notice that n is not defined outside the function:
julia> n ERROR: n not defined
Then, when we call addOne repeatedly, we get the following output:
addOne() #=> 1 addOne() #=> 2 addOne() #=> 3 reset() #=> 0
What we see is that, in the counter function, the variable n is captured in the anonymous functions. It can only be manipulated by the functions, addOne and reset. The two functions are said to be closed over the variable n and both have references to n. That's why they are called closures.
Currying (also called a partial application) is the technique of translating the evaluation of a function that takes multiple arguments (or a tuple of arguments) into evaluating a sequence of functions, each with a single argument. Here is an example of function currying:
function add(x) return function f(y) return x + y end end
The output returned is add (generic function with 1 method).
Calling this function with add(1)(2) returns 3. This example can be written more succinctly as add(x) = f(y) = x + y or, with an anonymous function, as add(x) = y -> x + y. Currying is especially useful when passing functions around, as we will see in the Map, filter, and list comprehensions section.
- Learning Java Functional Programming
- C程序設計簡明教程(第二版)
- JavaScript 從入門到項目實踐(超值版)
- Unity 2020 Mobile Game Development
- DevOps入門與實踐
- Animate CC二維動畫設計與制作(微課版)
- Mastering Julia
- Mastering KnockoutJS
- 深入淺出RxJS
- MATLAB for Machine Learning
- Selenium Testing Tools Cookbook(Second Edition)
- MongoDB,Express,Angular,and Node.js Fundamentals
- 編程可以很簡單
- Instant Zurb Foundation 4
- Scala編程實戰