Reader small image

You're reading from  The Clojure Workshop

Product typeBook
Published inJan 2020
Reading LevelBeginner
PublisherPackt
ISBN-139781838825485
Edition1st Edition
Languages
Right arrow
Authors (5):
Joseph Fahey
Joseph Fahey
author image
Joseph Fahey

Joseph Fahey has been a developer for nearly two decades. He got his start in the Digital Humanities in the early 2000s. Ever since then, he has been trying to hone his skills and expand his inventory of techniques. This lead him to Common Lisp and then to Clojure when it was first introduced. As an independent developer, Joseph was able to quickly start using Clojure professionally. These days, Joseph gets to write Clojure for his day job at Empear AB.
Read more about Joseph Fahey

Thomas Haratyk
Thomas Haratyk
author image
Thomas Haratyk

Thomas Haratyk graduated from Lille University of Science and Technology and has been a professional programmer for nine years. After studying computer science and starting his career in France, he is now working as a consultant in London, helping start-ups develop their products and scale their platforms with Clojure, Ruby, and modern JavaScript.
Read more about Thomas Haratyk

Scott McCaughie
Scott McCaughie
author image
Scott McCaughie

Scott McCaughie lives near Glasgow, Scotland where he works as a senior Clojure developer for Previse, a Fintech startup aiming to solve the problem of slow payments in the B2B space. Having graduated from Heriot-Watt University, his first 6 years were spent building out Risk and PnL systems for JP Morgan. A fortuitous offer of a role learning and writing Clojure came up and he jumped at the chance. 5 years of coding later and it's the best career decision he's made. In his spare time, Scott is an avid reader, enjoys behavioral psychology and financial independence podcasts, and keeps fit by commuting by bike, running, climbing, hill walking, snowboarding. You get the picture!
Read more about Scott McCaughie

Yehonathan Sharvit
Yehonathan Sharvit
author image
Yehonathan Sharvit

Yehonathan Sharvit has been a software developer since 2001. He discovered functional programming in 2009. It has profoundly changed his view of programming and his coding style. He loves to share his discoveries and his expertise. He has been giving courses on Clojure and JavaScript since 2016. He holds a master's degree in Mathematics.
Read more about Yehonathan Sharvit

Konrad Szydlo
Konrad Szydlo
author image
Konrad Szydlo

Konrad Szydlo is a psychology and computing graduate from Bournemouth University. He has worked with Clojure for the last 8 years. Since January 2016, he has worked as a software engineer and team leader at Retailic, responsible for building a website for the biggest royalty program in Poland. Prior to this, he worked as a developer with Sky, developing e-commerce and sports applications, where he used Ruby, Java, and PHP. He is also listed in the Top 75 Datomic developers on GitHub.
Read more about Konrad Szydlo

View More author details
Right arrow

3. Functions in Depth

Overview

In this chapter, we will take a deep dive into Clojure's functions. We discover destructuring techniques and advanced call signatures. We take a closer look at the first-class aspect of functions and learn how it enables functional composition, as well as advanced polymorphism techniques. This chapter teaches techniques that will significantly improve the conciseness and readability of your code. It lays down a solid basis to prepare you for the second part of this book about manipulating collections.

By the end of this chapter, you will be able to implement features such as destructuring, variadic functions and multimethods when writing functions.

Introduction

Clojure is a functional programming language, and functions are of primordial importance to the Clojure programmer. In functional programming, we avoid mutating the state of a program, which, as we have seen in the previous chapter, is greatly facilitated by Clojure's immutable data structures. We also tend to do everything with functions, such that we need functions to be able to do pretty much everything. We say that Clojure functions are first-class citizens because we can pass them to other functions, store them in variables, or return them from other functions: we also call them first-class functions. Consider an e-commerce application, for example, where a user is presented with a list of items with different search filters and sorting options. Developing such a filtering engine with flags and conditions in an imperative programming way can quickly become unnecessarily complex; however, it can be elegantly expressed with functional programming. Functional composition...

Destructuring

Destructuring allows you to remove data elements from their structure or disassemble a structure. It is a technique that improves the readability and conciseness of your code by providing a better tool for a widely used pattern. There are two main ways of destructuring data: sequentially (with vectors) and associatively (with maps).

Imagine that we need to write a function that prints a formatted string given a tuple of coordinates, for example, the tuple [48.9615, 2.4372]. We could write the following function:

(defn print-coords [coords]
  (let [lat (first coords)
        lon (last coords)]
    (println (str "Latitude: " lat " - " "Longitude: " lon))))

This print-coords function takes a tuple of coordinates as a parameter and prints out the coordinates to the console in a nicely formatted string, for example, Latitude: 48.9615Longitude: 2...

Advanced Call Signatures

So far, we have been declaring functions with one arity (with only a fixed number of arguments), and simply binding the arguments passed to a function to some parameter names. However, Clojure has a few techniques to allow more flexibility when calling functions.

Destructuring Function Parameters

First, everything we have just learned about destructuring applies to function parameters. Yes, you read that correctly – we can use destructuring techniques right in the function parameter declaration! As promised, here's our first stab at refactoring the print-flight functions from the previous exercise. Observe, in the following example, how sequential destructuring is used directly in the function parameters:

user=>
(defn print-flight
  [[[lat1 lon1] [lat2 lon2]]]
    (println (str "Flying from: Lat " lat1 " Lon " lon1 " Flying to: Lat " lat2 " Lon " lon2)))
#'user...

Higher-Order Programming

Higher-order programming means that programs, and specifically functions, can operate on other programs or functions, as opposed to first-order programming, where functions operate on data elements such as strings, numbers, and data structures. In practice, it means that a function can take some programming logic as a parameter (another function) and/or return some programming logic to be eventually executed. It is a powerful feature that allows us to compose single, modular units of logic in our programs to reduce duplication and promote the reusability of code.

Writing simpler functions increases their modularity. We want to create simple units of functionality that can be used as small bricks to build our programs with. Writing pure functions reduces the complexity of those bricks, and allows us to craft better, sturdier programs. Pure functions are functions that don't alter the state of our program – they produce no side effects; a pure...

Multimethods

Clojure offers a way to implement polymorphism with multimethods. Polymorphism is the ability of a unit of code (in our case, functions) to behave differently in different contexts, for example, based on the shape of the data received by the code. In Clojure, we also call it runtime polymorphism because the method to call is determined at runtime rather than at compile time. A multimethod is a combination of a dispatch function and of one or more methods. The two main operators for creating those multimethods are defmulti and defmethod. defmulti declares a multimethod and defines how the method is chosen with the dispatch function. defmethod creates the different implementations that will be chosen by the dispatch function. The dispatch function receives the arguments of the function call and returns a dispatch value. This dispatch value is used to determine which function, defined with defmethod, to invoke. Those are a lot of new terms but don't worry, the following...

Summary

In this chapter, we took a closer look at Clojure's powerful functions. We learned how to simplify our functions with destructuring techniques, and then discovered the great benefits of higher-order functions: modularity, simplicity, and composability. We also introduced an advanced concept to write code that is more extensible with Clojure's polymorphism mechanism: multimethods. Now that you are familiar with the REPL, data types, and functions, you can move on to learning about tools and functional techniques to manipulate collections.

In the next chapter, we will explore sequential collections in Clojure and take a look at two of the most useful patterns: mapping and filtering.

lock icon
The rest of the chapter is locked
You have been reading a chapter from
The Clojure Workshop
Published in: Jan 2020Publisher: PacktISBN-13: 9781838825485
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Authors (5)

author image
Joseph Fahey

Joseph Fahey has been a developer for nearly two decades. He got his start in the Digital Humanities in the early 2000s. Ever since then, he has been trying to hone his skills and expand his inventory of techniques. This lead him to Common Lisp and then to Clojure when it was first introduced. As an independent developer, Joseph was able to quickly start using Clojure professionally. These days, Joseph gets to write Clojure for his day job at Empear AB.
Read more about Joseph Fahey

author image
Thomas Haratyk

Thomas Haratyk graduated from Lille University of Science and Technology and has been a professional programmer for nine years. After studying computer science and starting his career in France, he is now working as a consultant in London, helping start-ups develop their products and scale their platforms with Clojure, Ruby, and modern JavaScript.
Read more about Thomas Haratyk

author image
Scott McCaughie

Scott McCaughie lives near Glasgow, Scotland where he works as a senior Clojure developer for Previse, a Fintech startup aiming to solve the problem of slow payments in the B2B space. Having graduated from Heriot-Watt University, his first 6 years were spent building out Risk and PnL systems for JP Morgan. A fortuitous offer of a role learning and writing Clojure came up and he jumped at the chance. 5 years of coding later and it's the best career decision he's made. In his spare time, Scott is an avid reader, enjoys behavioral psychology and financial independence podcasts, and keeps fit by commuting by bike, running, climbing, hill walking, snowboarding. You get the picture!
Read more about Scott McCaughie

author image
Yehonathan Sharvit

Yehonathan Sharvit has been a software developer since 2001. He discovered functional programming in 2009. It has profoundly changed his view of programming and his coding style. He loves to share his discoveries and his expertise. He has been giving courses on Clojure and JavaScript since 2016. He holds a master's degree in Mathematics.
Read more about Yehonathan Sharvit

author image
Konrad Szydlo

Konrad Szydlo is a psychology and computing graduate from Bournemouth University. He has worked with Clojure for the last 8 years. Since January 2016, he has worked as a software engineer and team leader at Retailic, responsible for building a website for the biggest royalty program in Poland. Prior to this, he worked as a developer with Sky, developing e-commerce and sports applications, where he used Ruby, Java, and PHP. He is also listed in the Top 75 Datomic developers on GitHub.
Read more about Konrad Szydlo