We now have the basis to create a function. It will return a lazy infinite sequence of floating point numbers within an upper and lower bound. defn
is a Clojure function that takes an anonymous function and binds a name to it in a given namespace. A Clojure namespace
is an organizational tool used to map human readable names to things, such as functions, named data structures, and so on. Here, we're going to bind our function to the generate-prices
name in our current namespace. You'll notice that our function is starting to span multiple lines. This will be a good time to author the code in your text editor of choice. I'll be using Emacs (you can read more about Emacs at https://en.wikipedia.org/wiki/Emacs):
src/edgar/core.clj
. Make sure that (ns edgar.core)
is at the top of this file.(load "edgaru/core")
uses the load
function to load the Clojure code in src/edgaru/core.clj
:(defn generate-prices [lower-bound upper-bound] (filter (fn [x] (>= x lower-bound)) (repeatedly (fn [] (rand upper-bound)))))
In our REPL, we can pull in code in various namespaces with the help of the require
function. This applies to the src/edgar/core.clj
file we've just edited. Here is the code in the edgar.core
namespace:
(require '[edgar.core :as c])
; c
is just a handy alias we can use instead of the long name.(take 10 (c/generate-prices 12 35))
. (29.60706184716407 12.507593971664075 19.79939384292759 31.322074615579716 19.737852534147326 25.134649707849572 19.952195022152488 12.94569843904663 23.618693004455086 14.695872710062428)
Here's a sample graph output (your data may vary):
There's a subtle abstraction in the preceding code that deserves attention. (require '[edgar.core :as c])
introduces the quote symbol. '
is the reader shorthand for the quote
function. So, the equivalent invocation would be (require (quote [edgar.core :as c]))
. Quoting a form tells the Clojure reader not to evaluate the subsequent expression (or form
). Therefore, evaluating '(a b c)
returns a list of 3 symbols without trying to evaluate any part of that form. Even though these symbols haven't yet been assigned, it's okay because this expression (or form
) has not yet been evaluated.
But, this begs a larger question. What is the reader? Clojure (and all Lisps) are what's known as homoiconic (you can read more about it at http://en.wikipedia.org/wiki/Homoiconicity). This means that Clojure code is also data and data can be directly output and evaluated as code. The reader is what parses our src/edgar/core.clj
file (or the (+ 1 1)
input from the REPL prompt) and produces data structures that are evaluated. read
and eval
are the two essential processes by which Clojure code runs. The evaluation result is printed (or output) to the standard output device usually. Then, we loop
the process back to the read function. So, when REPL reads your src/edgar/two.clj
file, it directly transforms this text representation into data and evaluates it. A few things fall out of this. For example, it becomes trivial for Clojure programs to directly read, transform, and write out other Clojure programs. The implications of this will become clearer when we look at macros. But for now, know that there are ways to modify or delay the evaluation process, in this case by quoting a form.
3.142.200.109