change examples to use defn macro

This commit is contained in:
Pekka Laiho 2020-12-06 11:04:04 +07:00
parent 82c8f3b52b
commit 732b923552
3 changed files with 26 additions and 23 deletions

View File

@ -10,46 +10,49 @@
;; ;;
;; Define commands ;; Define commands
(def cmdAdd (fn (args) (apply + args))) (defn cmdAdd (args) (apply + args))
(def cmdDiv (fn (args) (apply / args))) (defn cmdDiv (args) (apply / args))
(def cmdMul (fn (args) (apply * args))) (defn cmdMod (args) (apply % args))
(def cmdSub (fn (args) (apply - args))) (defn cmdMul (args) (apply * args))
(def cmdHelp (fn (args) (str "Available commands: " (apply join ", " (keys cmdMap))))) (defn cmdSub (args) (apply - args))
(defn cmdHelp (args) (str "Available commands: " (apply join ", " (keys cmdMap))))
;; And we define a hash-map for command lookups with minimum number of arguments ;; And we define a hash-map for command lookups with minimum number of arguments
(def cmdMap { (def cmdMap {
"add": [cmdAdd 2] "add": [cmdAdd 2]
"div": [cmdDiv 2] "div": [cmdDiv 2]
"mod": [cmdMod 2]
"mul": [cmdMul 2] "mul": [cmdMul 2]
"sub": [cmdSub 2] "sub": [cmdSub 2]
"help": [cmdHelp 0] "help": [cmdHelp 0]
}) })
;; Find the first command which starts with the given name, or null ;; Find the first command which starts with the given name, or null
(def findCmd (fn (name) (defn findCmd (name)
(if (empty? name) null (if (empty? name) null
(let (matches (filterh (fn (v k) (prefix? k name)) cmdMap)) (let (matches (filterh (fn (v k) (prefix? k name)) cmdMap))
(if (empty? matches) null (if (empty? matches) null
(get matches (first (keys matches)))))))) (get matches (first (keys matches)))))))
;; Split input by spaces, find command that matches the first word ;; Split input by spaces, find command that matches the first word
;; and call it, giving the rest of the words as arguments. ;; and call it, giving the rest of the words as arguments.
(def parseInput (fn (inp) (defn parseInput (inp)
(let (words (split " " inp) cname (first words) args (tail words) cmd (findCmd cname)) (let (words (split " " inp) cname (first words) args (tail words) cmd (findCmd cname))
(if (null? cmd) (print "Unknown command, try 'help'.") (if (null? cmd) (print "Unknown command, try 'help'.")
(if (< (len args) (second cmd)) (print (str "Give at least 2 arguments to " cname ".")) (if (< (len args) (second cmd)) (print (str "Give at least 2 arguments to " cname "."))
((first cmd) args)))))) ((first cmd) args)))))
;; Define a file for readline and load it ;; Define a file for readline and load it
(def readlineFile (str HOME "calc_history")) (def readlineFile (str HOME "calc_history"))
(readline-load readlineFile) (readline-load readlineFile)
;; Main loop: Read input from user, add it to readline, and parse it ;; Main loop: Read input from user, add it to readline, and parse it
(def mainLoop (fn () (let (inp (readline "> ")) (defn mainLoop ()
(let (inp (readline "[calc] "))
(do (readline-add inp) (do (readline-add inp)
(readline-save readlineFile) (readline-save readlineFile)
(print (str (parseInput inp) EOL)) (print (str (parseInput inp) EOL))
true)))) true)))
;; Run it ;; Run it
(loop mainLoop) (loop mainLoop)

View File

@ -1,11 +1,11 @@
;; Functions to calculate factorial ;; Functions to calculate factorial
;; Recursive version, not tail call optimized ;; Recursive version, not tail call optimized
(def recFact (fn (n) (if (< n 2) 1 (* n (recFact (dec n)))))) (defn recFact (n) (if (< n 2) 1 (* n (recFact (dec n)))))
;; Apply version ;; Apply version
(def applyFact (fn (n) (if (< n 2) 1 (apply * (range 1 (inc n)))))) (defn applyFact (n) (if (< n 2) 1 (apply * (range 1 (inc n)))))
;; Add documentation ;; Add docstrings
(doc recFact "Calculate the factor of n recursively.") (doc recFact "Calculate the factor of n recursively.")
(doc applyFact "Calculate the factor of n iteratively using apply.") (doc applyFact "Calculate the factor of n iteratively using apply.")

View File

@ -1,16 +1,16 @@
;; Functions to calculate Fibonacci numbers ;; Functions to calculate Fibonacci numbers
;; Slow recursive version ;; Slow recursive version
(def slowFib (fn (n) (if (< n 2) n (+ (slowFib (- n 1)) (slowFib (- n 2)))))) (defn slowFib (n) (if (< n 2) n (+ (slowFib (- n 1)) (slowFib (- n 2)))))
;; Return the sum of the last 2 numbers in a sequence ;; Return the sum of the last 2 numbers in a sequence
(def sumOfLast (fn (l) (+ (last l) (penult l)))) (defn sumOfLast (l) (+ (last l) (penult l)))
;; Faster version, return vector of n numbers, tail call optimized ;; Faster version, return vector of n numbers, tail call optimized
(def fibListRec (fn (n l) (if (< (len l) n) (fibListRec n (push l (sumOfLast l))) l))) (defn fibListRec (n l) (if (< (len l) n) (fibListRec n (push l (sumOfLast l))) l))
(def fibList (fn (n) (fibListRec n [0 1]))) (defn fibList (n) (fibListRec n [0 1]))
(def fastFib (fn (n) (sumOfLast (fibList n)))) (defn fastFib (n) (sumOfLast (fibList n)))
;; Add documentation ;; Add docstrings
(doc slowFib "Return the nth number from the Fibonacci sequence recursively.") (doc slowFib "Return the nth number from the Fibonacci sequence recursively.")
(doc fastFib "Return the nth number from the Fibonacci sequence iteratively.") (doc fastFib "Return the nth number from the Fibonacci sequence iteratively.")