Skip to content

Latest commit

 

History

History
187 lines (116 loc) · 8.55 KB

04-data.asciidoc

File metadata and controls

187 lines (116 loc) · 8.55 KB

Data

Let’s think back to our find! “program”/“function” that we wrote for the pacman-bot system.

(find! object) means:
  if object is cherry:
    (goto! cherryX cherryY)
  if object is ghost:
    (goto! ghostX ghostY)

find! would take an object as input (cherry or ghost) and change the state of the pacman-bot system so that pacman-bot would end up in the same position as the specified object. It would make use of the v><^ functions, which were provided by the system. It also needed to know the positions of pacman-bot, the cherry and the ghost (which were provided by the system as pacmanX, cherryX, ghostX…​)

The input object and the positions pacman-bot, the cherry and the ghost were all pieces of information that our find! program needed to function. We refer to these kinds of pieces of information, in a broad sense, as “data”.

Real world programs deal with a lot of data — lists of friends, blog posts, photos, addresses of businesses — and as a programmer, much of what you will be doing is transforming, combining, seperating and recombining data (using functions!).

In our programs, data will be used in various ways:

  • as inputs into our program (ex. a stream of Twitter updates), so that we can write one program and use it with different sets of data

  • passed into functions and returned from functions

  • to represent the state of the system (ex. the positions of the objects in our pacman-bot system)

  • as a “hardcoded” reference to help our programs do what they need to do (for example, a table to from months-of-the-year in english to their numerical equivalents)

There are infinite kinds of data we might want to handle in a program, but, it turns out, we can represent almost any kind of information using a few simple building blocks:

Primitive Values

Primitive values are the simplest forms of data; you can think of them as the atoms of the programming world. They include numbers (such as 1 and 1.5), “strings” (which represent text, such as "hello" and "goodbye") and other types of things called “booleans”, “keywords” and “nil”. Let’s take a look at each.

Numbers

A “number” is a numerical values. Clojure, which is the language we’ll be using for the rest of this book understands three kinds of numbers:

Integers (ex. 25)

Decimals (ex. 23.234) (also called “doubles”, “floats”, and “longs” in some languages)

Fractions (ex. 7/23)

From now on, we’ll refer to all three of these forms as “numbers”.

Strings

A “string” represents text. It can be a single character: "a", a word: "elephant", a sentence: "This is a string", or the entire corpus of Shakespeare’s works: (uhhh…​ to save space, we’ll skip the example for this one).

In Clojure, as in most programming languages, strings are written with quotation marks around them, like so: "hello again!". The quotation marks are necessary to help differentiate strings from names of functions in our program (so, goto! would be the function, while "goto!" would just be the text). In a similar vein, 2 is the number 2, while "2" is a string - they are completely different things, as far as Clojure is concerned.

Booleans

A “boolean” is a fancy programmer term for the concepts of “true” and “false”. In Clojure, that’s exactly how we write them: true and false. They come in handy for representing certain information (ex. is John late? → true), as results of comparisons (ex. is 3 greater than 5? → false) and as return values from functions (ex. (even? 5)false).

Just to make it super clear, true is not the same things as "true" (the first is a boolean, the second is a string).

nil

“nil” is a special value that represents the “lack of a value” or “nothingness”. In math, that honor is usually bestowed to 0, but because 0 is already number, it ends up being very useful to have a way to say “nothing”. In Clojure, you can write it simply as nil.

keywords

A “keyword” is a label that is used in our programs to help us name things (we’ll see them very soon in maps). For example, we might have a program that deals with colors, which we could represent in Clojure with keywords as so: :red, :white, :green, :purple. Keywords start with a colon (:).

Keywords might seem similar to strings (and in some languages, there are no keywords), but they’re not meant to be “broken down” like strings; with a string, we might ask for the 10th character, or count the number of characters, or count the number of words, or split a string into seperate words — these operations can’t be done with keywords. Strings can be thought of as a “collection of characters” while keywords are just a handy label to use in our programs.

If the distinction is confusing, don’t worry about it. If you use strings instead of keywords, your programs will still work.

compound values

Primitive values are nice, but we often need to deal with collections of values, and that’s where “vectors” and “maps” come in. If primitive values were the atoms of the programming world, then “compound values” are the molecules.

vectors

A “vector” is an ordered lists of values. In Clojure, we represent a vector by listing values in between square brackets ([]). For example, here is a vector of numbers: [10 4 2 6], and here is a vector of strings and numbers: [1 "hello" 4 "goodbye"].

In other languages, you may also hear vectors referred to as “lists”, “arrays” or “sequences”.

Being able to store values in lists ends up being very, very useful. Vectors will also allow us to add values to them, remove values, do something for each value inside, and retrieve values based on their position.

Vectors can also contain non-primitive values, such as other vectors: [1 2 3 ["four" [:five]]]

maps

A “maps” is like a real-world dictionary; it contains a list of “keys”, each of which correponds to a certain “value”. In a real-world dictionary, the “keys” are the words and the “values” are the definitions.

Here is an example of an (abridged) real-world dictionary in Clojure, written as a map of strings to strings:

{ "Chair"  "A piece of furniture used for sitting."
  "Orange" "A citrus fruit or color."
  "Guitar" "A musical instrument." }

Just as with a real-world dictionary, we can lookup the corresponding definition (“value”) to a word (“key”). We could do this by writing: (dictionary "chair") which would return "A piece of furniture used for sitting".

Maps end up being useful for representing lots of different real world data, such as people: { :name "Bob" :age 23 } or places: { :name "Ghost Town" :population 0 }

Maps can have any values as “keys” and any values as “values”. This is a totally legitimate map:

{ [1 2] "one two"
  :three "three"
  {} nil }

other types

There are more types in Clojure than mentioned here, but these ones will do for now, and we’ll see the others in the future (notably: “sets”, “datetimes” and “uuids”).

putting things together

Now that we know various kinds of values that we can work with, let’s represent some non-trivial data using them.

How might we represent the countries of the world, their areas, populations and capital cities?

Here’s one way:

[
  { :name "Canada"
    :population 1234
    :area 4567
    :capital "Toronto"
    :cities [{:name "Toronto"
              :area 456
              :population 1252}
             {:name "Montreal"
              :area 512
              :population 1262}]}

  { :name "China"
    :population 2345
    :area 5678
    :capital "Beijing"
    :cities [{:name "Beijing"
              :area 123
              :population 1235}
             {:name "Shanghai"
              :area 456
              :population 542}]}

  ...
]
Exercise

Try coming up with ways of representing the following data sets:

  • a contact list (each with names, an email and multiple phone numbers)

  • the pacman-bot system

  • the system you came up with in <previous chapter exercise>

  • a count of how many times each letter occurs in a piece of text

Derived Values

Exercise
  • a shopping receipt

Transformations

Constants

State

Helper Functions

Actions