Naming data structuresλ︎
We have seen that defining things is as simple as giving a name to a value using the def
function. It is the same for the Clojure data structures and any other values.
Names are of course case sensitive, so Person is not the same as person
Clojure uses dynamic typing, this means its trivial to mix and match different kinds of data. Here we are defining a name for a vector, which contains numbers, a string and name of another def.
Data structures are immutable, names are mutableλ︎
You can dynamically re-define a name to points to a different value.
Hint This re-definition (or rebinding) of names to new values is typically used only during the development of your code, especially in REPL driven development.
The original value that defined my-data remains unchanged (its immutable), so anything using that value remains unaffected. Essentially we are re-mapping my-data to a new value.
Lets define a name to point to a list of numbers
We are returned that list of numbers when we evaluate the name
We can use the cons function to add a number to our list, however because lists are immutable, rather than changing the original list, a new one is returned. So if we want to keep on referring to our "changed" list, we need to give it a name
As you can see we have not changed the original list
;; The new list does have the change though.
You could therefore give the impression of mutable state by applying a function to data structure and redefining the original name to point to the resulting data structure.
Hint In practice, the ability to redefine functions and data structures live helps you develop your application quickly in the REPL.
In production you typical do not redefine functions or data structures in a live running application. That could be part of a new release of your application though.
So now when we evaluate the original name, we get the updated list
Naming Scopeλ︎
All def names are publicly available via their namespace. As def values are immutable, then keeping things private is of less concern than languages built around Object Oriented design.
Private definitions syntax can be used to limit the access to def names to the namespace they are declared in.
To limit the scope of a def, add the :private true metadata key value pair.
The second form is syntax sugar for the first one.
You could also define a macro for def-
You would then use this macro as follows: