True Consciousness? – Maybe?

Very interesting piece about Reziine a UK based startup that is seeking to crowd funding to create the first conscious mind. In support , f this it has published the entire blueprint for a true conscious mind. All you need is several PhDs in Physics, Quantum Computing and Computer Science to understand it……

Head into Clojure – Part 5: Control statements

Ok, we can use base types know the difference between collections and sequences ( if you do be sure to tell me ! ) and we can write some basic functions and use map/reduce/filter to play around with collections.

Hopefully you have also upgraded from the basic Clojure REPL to Leiningen one, and are reaping the benefits of uber productivity

Now its time to get real and start writing some real functions, more than a single line and with ability to control flow through the function


;; if statement

(defn is_true? [x] (if (true? x) "yes" "no"))                   ;; Example of if statement   
              
(is_true? false)                                                ;; results in "no"


;; cond statements

(defn is_positive? [x]                                          ;; Define a function that gives a string value for a numbers positivity
(cond
  (> x 0) "positive"                                            
  (< x 0) "negative"
  :else   "zero" ))                                             ;; Optional default catch all others

(is_positive? 3)                                                ;; Results in "positive"

;; case statements

(defn number_str [x]
  (case x
     1 "One"
     2 "Two"
     3 "Three"
     4 "Four"
     5 "Five"
     "Too big"))

(number_str 1)                                                   ;; Results in "One"
(number_str 4)                                                   ;; Results in "Four"
(number_str 10)                                                  ;; Results in "Too big"

;; do statements

;; Do evaluates a sequence of expressions in order, the result of the expression is the value of the last
;; expression in the list
(def x 3)
(do
    (println "Starting")
    (+ x 1)
    (inc x)
    (println "Stopping")
    x )
;; Results in the following output, but why ?
Starting
Stopping
3
;; This is a classic example of immutable data, while 2 statements in the middle apply operations to the variable x
;; but these operations only return values, they do not change the value of x in the expressions
;; This is one of the key facets of functional programming


;; loop/recur

(loop [x 10]                                                     ;; Entry point 
  (when (> x 1)
    (println x)
    (recur (- x 2))))                                            ;; Recursive call into the call stack with updated 
                                                                 ;; parameters

;; List Comprehension

(for [x (range 100)] x)                                          ;; Create a list 0 to 99

(for [x (range 100)] (* x x))                                    ;; Create a list by iterating through each number
                                                                 ;; 0 - 99 and multiplying it by itself

(for [x (range 100)] (even? x))                                  ;; Create a list of booleans representing whether
                                                                 ;; each number between 0 and 99 is even or odd

(for [a (range 100)                                              ;; Nested loop that creates a list of vectors
      b (range 100 200)                                          ;; each vector is created from a nest loop
    [a b]                                                        ;; For each a 0 - 99, iterate through b 100-199
  )

(for [a (range 100)                                              ;; Nested loop that creates a list if vectors
      b (range 100 200)                                          ;; as above, but exits when a * b > 1000
      :while (< (* a b) 1000)] 
    [a b]
  )

Head into Clojure – Part 4: Leiningen – A better REPL than REPL

So far we have being using the default REPL ( Read-Evalulate-Print Loop ) for entering our Clojure code and seeing how it works.

We are now going to take a look at a much better REPL, one built into another tool called Leiningen. Leiningen is much bigger than an improved REPL, it is a complete project configuration and automation tool, much like Maven or Ant, which all Clojure developers come to rely on.

Head over to leiningen.org and follow the basic instructions for installation onto your platform. We’ll touch on the power of Leiningen in further parts, but for now we are only interested in the REPL

Once you have it installed, to get a new and improve REPL, enter

lein repl

This will then load a REPL which will look something like

REPL server started on port 63316 on host 127.0.0.1 - nrepl://127.0.0.1:63316
REPL-y 0.3.5, nREPL 0.2.6
Clojure 1.6.0
Java HotSpot(TM) 64-Bit Server VM 1.7.0_71-b14
Docs: (doc function-name-here)
(find-doc "part-of-name-here")
Source: (source function-name-here)
Javadoc: (javadoc java-object-or-class-here)
Exit: Control+D or (exit) or (quit)
Results: Stored in vars *1, *2, *3, an exception in *e

user=>

The key features we are interested in are

  • Parenthesis Matching. In the REPL enter a basic form such as (+ 2 2) as you enter the final ), you will see the cursor jump back and forth highlight the most relevant bracket. Useful when you have several nested parenthesis.
  • Auto Completion. If you cannot quite remember the name of the function or macro, start by typing as much of the name you do know and then press tag. REPL will list all names which match.
  • History. Use the up and down arrow to scroll through previous entries

Some other useful commands which help your use of REPL

  • CTRL+C. If you are half way through typing something and realise you don’t need it, rather than hit return and have REPL through an error trying to parse what you typed, use CTRL+C instead to abandon the current line.
  • CTRL+L. Once you’ve used REPL for some time you find yourself at the bottom of the screen and things start to look cluttered. CTRL+L will clear the current screen and leave you back at the top.

Head into Clojure – Part 3: Functions

Creating Functions

We have to use functions at some point, Clojure is after all a Functional programming language.


(def hello (fn [] "Hello World"))                    ;; Defines a function, no parameters
(hello)                                              ;; call a function

(defn hello2 [] "hello world")                       ;; Use a macro to define a function
(hello2)                                             ;; No difference in way to call the function

(defn hello-to [name] (println "Hello" name))        ;; Define a function with a parameter
(hello-to "Keith")                                   ;; Call a function

(defn hello3-to [name, age]                          ;; Define a function with multiple parameters
    (println "Hello" name "you are " age))
(hello2-to "keith" 21)                               ;; Call a function with multiple parameters

 (defn hello-to-some                                 ;; Define a function which has 3 polymorphic methods
    ([] (println "Hello to no one"))                 ;; No parameters
    ([x] (println "Hello to " x))                    ;; One parameter
    ([x y] (println "Hello to " x " and " y)))       ;; Two parameters
(hello-to-some)
(hello-to-some "keith")
(hello-to-some "keith" "cat")

Functions on Collections

Now we know how to creation functions, we can use this new knowledge to do some basic manipulation of collections


(defn squareit [x] (* x x))                          ;; Define a method to square a number
(squareit 3)                                         ;; Test it, should return 9
(map squareit [1 2 3 4 5])                           ;; Applies squareit to every item of the collection
                                                     ;; returning a new collection with new values
                                                     ;; Should return (1 4 9 16 25)
(map squareit '(1 2 3 4 5))                          ;; Same as above, this time against a list


(defn more-than-one-char [x] (> (count x) 1))        ;; Filter takes a function that returns a boolean result
                                                     ;; Called a predicate in Clojure land
                                                     ;; This filter returns true if the string is > 1 character
(filter more-than-one-char ["a" "ab" "abc"])         ;; Applies the filter to a string, should return ("ab" "abc")

;; More often than not, there is already a function that can be used. In fact in <a href="http://www.keithsterling.com/?p=518" title="Head into Clojure – Part 1: The Basics">Part 1</a> we saw lots of mathematical and
;; boolean functions +, -, *, /, mod, inc dec etc
 
(map inc [1 2 3])                                    ;; Increments each element of the collection by 1
(map dec [1 2 3])                                    ;; Decreases each element by 1  

(filter even? [1 2 3 4 5 6 7 8 9 10])                ;; Filters out all odd numbers, returning a collection of evens
(filter float? [1 2.0 3 4 5.0])                      ;; Creates a collection of only floats

;; A slightly more advance, but equally important function is reduce. This takes the first item in the list, and applies
;; the define function to it and the next item. The result is them applied to the 3rd item and on and on through to the end 
;; of the list. This is best explained with a basic example using the + function

(reduce + [5 8 14 21])                               ;; Here reduce takes 5 and applies + to it and 8, result 13
                                                     ;; 13 then forms the left hand side of the method call, 
                                                     ;; 14 on the right hand side, the result being 27
                                                     ;; 27 is then the left and 21 the right, result 48
(+ (+ (+ 5 8) 14) 21)                                ;; The equivalent if you wrote it out long hand
                                                     ;; but this would be impossible if you didn't know the length
                                                     ;; of the collection in the first place