How to resolve the algorithm Call a function step by step in the Clojure programming language
Published on 12 May 2024 09:40 PM
How to resolve the algorithm Call a function step by step in the Clojure programming language
Table of Contents
Problem Statement
Demonstrate the different syntax and semantics provided for calling a function.
This may include:
This task is not about defining functions.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Call a function step by step in the Clojure programming language
Source code in the clojure programming language
(defn one []
"Function that takes no arguments and returns 1"
1)
(one); => 1
(defn total-cost [item-price num-items]
"Returns the total price to buy the given number of items"
(* item-price num-items))
(total-cost 1 5); => 5
(defn total-cost-with-discount [item-price num-items & [discount-percentage]]
"Returns total price to buy the items after discount is applied (if given)"
(let [discount (or discount-percentage 0)] ;; Assign discount to either the discount-percentage (if given) or default 0 if not
(-> item-price
(* num-items) ;; Calculate total cost
(* (- 100 discount)) ;; Apply discount
(/ 100.0))))
;; Now we can use the function without the optional arguments, and see the same behaviour as our total-cost function
(total-cost-with-discount 1 5); => 5
;; Or we can add the third parameter to calculate the cost with 20% discount
(total-cost-with-discount 1 5 20); => 4
(defn make-address
([city place-name] (str place-name ", " city))
([city street house-number] (str house-number " " street ", " city))
([city street house-number apartment] (str house-number " " street ", Apt. " apartment ", " city)))
;; To call the function you just need to pass whatever arguments you are supplying as you would with a fixed number
;; First case- the queen doesn't need a street name
(make-address "London" "Buckingham Palace"); => "Buckingham Palace, London"
;; Second case
(make-address "London" "Downing Street" 10); => "10 Downing Street, London"
;; Third case
(make-address "London" "Baker Street" 221 "B"); => "221 Baker Street, Apt. B, London"
(defn make-mailing-label [{:keys [name address country]}]
"Returns the correct text to mail a letter to the addressee"
(str name "\n" address "\n" (or country "UK"))) ;; If country is nil, assume it is the UK
;; We can call it with all three arguments in a map to get mickey's international address
(make-mailing-label {:name "Mickey Mouse"
:address "1 Disney Avenue, Los Angeles"
:country "USA"}); => "Mickey Mouse\n1 Disney Avenue, Los Angeles\nUSA"
;; Or we can call it with fewer arguments for domestic mail
(make-mailing-label {:name "Her Majesty"
:address "Buckingham Palace, London"}); => "Her Majesty\nBuckingham Palace, London\nUK"
(defn multiply-by-10 [number]
(* 10 number))
(def fifty (multiply-by-10 5))
fifty; => 50
(defn make-discount-function [discount-percent]
"Returns a function that takes a price and applies the given discount"
(fn [price] (-> price
(* (- 100 discount-percent))
(/ 100.0))))
;; Now we can create a '20% off' function to calculate prices with your discount card
(def discount-20pc (make-discount-function 20))
;; Use the function to calculate some discount prices
(discount-20pc 100); => 80
(discount-20pc 5); => 4
;; Your friend has a better discount card, we can use the same function to create their discount card function
(def discount-50pc (make-discount-function 50))
(discount-50pc 100); => 50
(discount-50pc 5); => 2.5
;; Continuing on the same example, let's imagine Anna has a 20% discount card and Bill has 50%. Charlie pays full price
;; We can store their discount functions in a map
(def discount-cards {"Anna" discount-20pc
"Bill" discount-50pc
"Charlie" identity}) ;; Identity returns whatever value was passed to the function (in this case it will be price)
;; Now we can access them by cardholder name in another function
(defn calculate-discounted-price [price shopper-name]
"Applies the correct discount for the person"
(let [discount-fn (get discount-cards shopper-name)] ;; Get the right discount function
(discount-fn price))) ;; Apply discount function to the price
(calculate-discounted-price 100 "Anna"); => 80
(calculate-discounted-price 100 "Bill"); => 50
(calculate-discounted-price 100 "Charlie"); => 100
;; Here we have two functions to format a price depending on the country
(defn format-price-uk [price]
(str "£" price))
(defn format-price-us [price]
(str "$" price))
;; And one function that takes a price formatting function as an argument
(defn format-receipt [item-name price price-formatting-function]
"Return the item name and price formatted according to the function"
(str item-name
" "
(price-formatting-function price))) ;; Call the format function to get the right representation of the price
(format-receipt "Loo Roll" 5 format-price-uk); => "Loo Roll £5"
(format-receipt "Toilet Paper" 5 format-price-us); => "Toilet Paper $5"
;;You can assign it to a variable:
(def receipt-us (format-receipt "Toilet Paper" 5 format-price-us))
;; Then the variable holds the value
receipt-us; => "Toilet Paper $5"
;; Or you can use it in a call to another function
(defn add-store-name [receipt]
"A function to add a footer to the receipt"
(str receipt "\n Thanks for shopping at Safeway" ))
;; Calls add-store-name with the result of the format function
(add-store-name (format-receipt "Toilet Paper" 5 format-price-us)); => "Toilet Paper $5\n Thanks for shopping at Safeway"
;; They are indistinguishable in Clojure, and you can even override a built in one
;; Using built-in addition
(+ 5 5); => 10
;; Using custom defined addition
(defn ? [a b]
"Returns the sum of two numbers"
(+ a b))
(? 5 5); => 10
;; Overriding a built in function is possible but not recommended
(defn * [a b] ;; Redefining the multiplication operator
"Returns the sum of two numbers"
(+ a b))
(* 5 5); => 10
;; They are the same thing - indeed, everything in clojure is a function
;; Functions without return values simply return nil
(defn no-return-value [a]
(print (str "Your argument was" a "; now returning nil")))
(no-return-value "hi"); => nil
;; Set up a variable that we will pass to a function
(def the-queen {:name "Elizabeth"
:title "Your Majesty"
:address "Buckingham Palace"
:pets ["Corgi" "Horse"]})
;; A function to modify the data
(defn adopt-pet [person pet]
"Adds pet to the person's list of pets"
(update person
:pets
#(conj % pet)))
;; Calling the function returns a new data structure with the modified pets
(adopt-pet the-queen "Ferret"); => {:name "Elizabeth":title "Your Majesty" :address "Buckingham Palace" :pets ["Corgi" "Horse" "Ferret]}
;; The original data structure is not changed
the-queen; => {:name "Elizabeth" :title "Your Majesty" :address "Buckingham Palace" :pets ["Corgi" "Horse"]}
(defn apply-discount [discount-percentage price]
"Function to apply a discount to a price"
(-> price
(* (- 100 discount-percentage)) ;; Apply discount
(/ 100.0)))
;; Here we have assigned the variable to a partial function
;; It means 'call apply-discount with 10 as the first argument'
(def discount-10pc-option-1 (partial apply-discount 10))
;; And is equivalent to this:
(defn discount-10pc-option-2 [price]
(apply-discount 10 price))
(discount-10pc-option-1 100); => 90
(discount-10pc-option-2 100); => 90
You may also check:How to resolve the algorithm Euclid-Mullin sequence step by step in the ALGOL W programming language
You may also check:How to resolve the algorithm Composite numbers k with no single digit factors whose factors are all substrings of k step by step in the C programming language
You may also check:How to resolve the algorithm A+B step by step in the Phixmonti programming language
You may also check:How to resolve the algorithm HTTPS step by step in the Common Lisp programming language
You may also check:How to resolve the algorithm Giuga numbers step by step in the XPL0 programming language