diff --git a/learnclj.clj b/learnclj.clj index f06d166..4d3217e 100644 --- a/learnclj.clj +++ b/learnclj.clj @@ -16,32 +16,44 @@ true ; => true (Boolean) nil ; => nil (Null/Nothing) -;; --- 2. Defining Values & Functions --- +;; === Function Basics === -;; def — binds a name to a value in the namespace -(def π 3.14159265) - -;; defn — defines a function +;; defn — defines a named function (defn greet [name] (str "Hello, " name "!")) -(greet "Sam") ;; => "Hello, Sam!" +(greet "Sam") ; => "Hello, Sam!" -;; Anonymous function -(#(+ %1 %2) 3 4) ; => 7 -(fn [x y] (+ x y)) ; => #object[clojure.core$fn__... 0x... "fn..."] (anonymous function) +;; Anonymous function — fn form +(fn [x y] (+ x y)) ; => #object[clojure.core$fn__... 0x...] -;; Function with default arguments +;; Anonymous function — sharp-syntax shorthand +(#(+ %1 %2) 3 4) ; => 7 + +;; Function with multiple parameters +(defn add [x y] + (+ x y)) +(add 3 4) ; => 7 + +;; Default arguments via destructuring in parameters (defn greet-default [name {:keys [formal] :or {formal false}}] (if formal (str "Good day, " name) (str "Hey, " name))) -(greet-default "Sam" {}) ; => "Hey, Sam" -(greet-default "Sam" {:formal true}) ; => "Good day, Sam" +(greet-default "Sam" {}) ; => "Hey, Sam" +(greet-default "Sam" {:formal true}) ; => "Good day, Sam" -;; Variadic function +;; Variadic function — & collects extra args into a seq (defn sum [& numbers] (reduce + 0 numbers)) -(sum 1 2 3 4) ; => 10 +(sum 1 2 3 4) ; => 10 + +;; Named parameters via map destructuring +(defn greet-named [& {:keys [name formal] :or {formal false}}] + (if formal + (str "Good day, " name) + (str "Hey, " name))) +(greet-named :name "Sam" :formal true) ; => "Good day, Sam" +(greet-named :name "Sam") ; => "Hey, Sam" ;; --- 3. Data Structures --- @@ -116,29 +128,48 @@ nil ; => nil (Null/Nothing) (map #(* % %))) [1 2 3 4 5 6 7]) ; => (1 9 25 49) -;; --- 6. Destructuring --- +;; === Destructuring === -;; Vector destructuring +;; Vector destructuring — bind positions to names (let [[first second & rest] [1 2 3 4 5]] [first second rest]) ; => [1 2 (3 4 5)] -;; Map destructuring +;; Map destructuring — bind keys to names (let [{name :name age :age} {:name "Bob" :age 25}] [name age]) ; => ["Bob" 25] +;; :keys shorthand — automatic key-to-name binding +(let [{:keys [name age]} {:name "Bob" :age 25}] + [name age]) +; => ["Bob" 25] + +;; :or — default values when key is missing or nil +(let [{:keys [name] :or {name "Anonymous"}} {:age 25}] + name) +; => "Anonymous" + ;; Nested destructuring (let [{:keys [x y] :as point} {:point {:x 10 :y 20}} {:keys [x y]} (:point point)] [x y]) ; => [10 20] -;; Function parameter destructuring +;; Destructuring in function parameters (same patterns as let) (defn show-point [{:keys [x y] :or {x 0 y 0}}] (str "Point: (" x ", " y ")")) -(show-point {:x 10 :y 20}) ; => "Point: (10, 20)" -(show-point {}) ; => "Point: (0, 0)" +(show-point {:x 10 :y 20}) ; => "Point: (10, 20)" +(show-point {}) ; => "Point: (0, 0)" + +;; Destructuring in loop bindings +(loop [[first & rest] [1 2 3]] + (if first + (do + (println "Got:" first) + (recur rest)) + :done)) +; => Got: 1, Got: 2, Got: 3, :done ;; --- 7. Namespaces ---