0Pricing
Clojure Functional Programming & JVM Backend Development · 课时

一等函数与高阶函数

了解将函数作为值使用的方法、如何传递函数,以及如何创建强大的高阶函数。

一等函数与高阶函数 是 CoddyKit 上的免费 Clojure Functional Programming & JVM Backend Development 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Clojure Functional Programming & JVM Backend Development 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Clojure Functional Programming & JVM Backend Development 课程共包含 4 节课。

本课时的部分内容尚未翻译,以英文显示。

Functions: First-Class Citizens

In Clojure, functions are "first-class citizens." This means they are treated just like any other value, such as numbers or strings.

You can:

  • Assign them to variables.
  • Pass them as arguments to other functions.
  • Return them as results from other functions.

This powerful concept is fundamental to functional programming!

Assigning Functions to Names

Let's see how we can treat functions as values by assigning them to a name using def or let. Think of it as giving a nickname to a function.

Try running this example:

(ns coddykit.core
  (:gen-class))

(defn greet [name]
  (str "Hello, " name "!"))

(defn -main [& args]
  (println "--- Output ---")
  (def my-greeting greet) ; Assign 'greet' function to 'my-greeting'
  (println (my-greeting "Alice")))

Passing Functions as Arguments

A key aspect of first-class functions is the ability to pass them as arguments to other functions. This allows for highly flexible and reusable code.

Imagine a function that performs an operation, but what operation it performs is decided by another function you pass to it!

Try running this example:

(ns coddykit.core
  (:gen-class))

(defn operate [f x y]
  (f x y)) ; Call the function 'f' with arguments 'x' and 'y'

(defn -main [& args]
  (println "--- Output ---")
  (println (operate + 5 3)) ; Pass the '+' function
  (println (operate * 5 3))) ; Pass the '*' function

Functions that Return Functions

Functions can also create and return new functions. This is useful for building "function factories" that produce specialized functions based on some input.

Here, make-adder takes a number and returns a new function that adds that number to its input.

Try running this example:

(ns coddykit.core
  (:gen-class))

(defn make-adder [x]
  (fn [y] (+ x y))) ; Returns an anonymous function

(defn -main [& args]
  (println "--- Output ---")
  (def add-five (make-adder 5))
  (def add-ten (make-adder 10))
  (println (add-five 2))
  (println (add-ten 2)))

What are Higher-Order Functions?

When a function either takes one or more functions as arguments, or returns a function as its result, it's called a Higher-Order Function (HOF).

HOFs are incredibly powerful because they allow you to:

  • Abstract common patterns.
  • Write more concise and expressive code.
  • Create flexible and reusable program components.

Let's look at some common HOFs in Clojure!

Transform with `map`

map is a fundamental higher-order function. It applies a given function to each item in a collection (like a list or vector) and returns a new collection containing the results.

It's perfect for transforming data without changing the original collection.

Try running this example:

(ns coddykit.core
  (:gen-class))

(defn square [x] (* x x))

(defn -main [& args]
  (println "--- Output ---")
  (def numbers [1 2 3 4])
  (def squared-numbers (map square numbers))
  (println "Original numbers:" numbers)
  (println "Squared numbers:" squared-numbers))

Filter Collections with `filter`

The filter HOF takes a "predicate" function (a function that returns true or false) and a collection. It returns a new collection containing only the elements for which the predicate function returns true.

This is great for selecting specific items from a list.

Try running this example:

(ns coddykit.core
  (:gen-class))

(defn is-even? [n]
  (= (mod n 2) 0))

(defn -main [& args]
  (println "--- Output ---")
  (def numbers (range 1 11)) ; Numbers from 1 to 10
  (def even-numbers (filter is-even? numbers))
  (println "All numbers:" numbers)
  (println "Even numbers:" even-numbers))

Combine with `reduce`

reduce is another powerful HOF that combines all elements of a collection into a single result. It takes a combining function, an optional initial value, and a collection.

The function is applied cumulatively to each item, often used for summing, finding max/min, or concatenating.

Try running this example:

(ns coddykit.core
  (:gen-class))

(defn -main [& args]
  (println "--- Output ---")
  (def numbers [1 2 3 4 5])
  (def sum (reduce + numbers)) ; Sums all numbers
  (def product (reduce * numbers)) ; Multiplies all numbers
  (println "Numbers:" numbers)
  (println "Sum:" sum)
  (println "Product:" product))

Quick Functions: Lambdas

Often, the functions we pass to HOFs are small and used only once. For these, Clojure provides anonymous functions, also known as lambdas.

They use the shorthand #(...) syntax, where % refers to the first argument, %1 for the first, %2 for the second, and so on.

Try running this example:

(ns coddykit.core
  (:gen-class))

(defn -main [& args]
  (println "--- Output ---")
  (def numbers [1 2 3 4])
  (def doubled-numbers (map #(* % 2) numbers)) ; Anonymous function
  (def greater-than-two (filter #(> % 2) numbers)) ; Another anonymous function
  (println "Doubled:" doubled-numbers)
  (println "Greater than 2:" greater-than-two))

HOFs in Action

You've learned about first-class and higher-order functions. Now, let's test your understanding of how they can be combined to achieve specific data transformations.

Consider the sequence of numbers (range 1 6), which evaluates to (1 2 3 4 5).

Which Clojure expression correctly uses higher-order functions to get a list of squared even numbers from this sequence?

Recap: Functions as Superpowers

Congratulations! You've unlocked the power of first-class and higher-order functions in Clojure!

Here's what we covered:

  • First-Class Functions: Functions can be treated like any other data type – assigned to variables, passed as arguments, and returned from other functions.
  • Higher-Order Functions: Functions that operate on other functions (taking them as arguments or returning them).
  • Key HOFs: We explored map for transformation, filter for selection, and reduce for aggregation.
  • Anonymous Functions: The #(...) syntax for concise, inline function definitions.

These concepts are central to writing expressive and flexible Clojure code. Keep practicing!

常见问题解答

「一等函数与高阶函数」课时是免费的吗?

是的 — 「一等函数与高阶函数」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Clojure Functional Programming & JVM Backend Development 课程的其余内容,请升级到 CoddyKit PRO。 Clojure Functional Programming & JVM Backend Development 课程共包含 4 节课。

「一等函数与高阶函数」这节课中我会学到什么?

了解将函数作为值使用的方法、如何传递函数,以及如何创建强大的高阶函数。 你通过在浏览器中直接运行的动手代码来练习 Clojure Functional Programming & JVM Backend Development,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Clojure Functional Programming & JVM Backend Development 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Clojure Functional Programming & JVM Backend Development 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「一等函数与高阶函数」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Clojure Functional Programming & JVM Backend Development 课中编写并运行代码吗?

能。每节 Clojure Functional Programming & JVM Backend Development 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 一等函数与高阶函数
  2. 不可变性与持久化数据
  3. 惰性序列与性能
  4. 用于可组合转换的转导器
← 返回 Clojure Functional Programming & JVM Backend Development