Sep 30, 2010

Exceptions and a simple program

Exception handling in clojure

Clojure supports java based exceptions. There are two types of exceptions in clojure. One is clojure exceptions and the other is user defined exceptions. If you type as;
user=>(/ 1 0)
This is devide 1 by 0. So this will give an exception.
So, this is the way to catch the exceptions.
user=>(try (/ 1 0 ) (catch Exception e (prn "Cach the exception" ))(finally (prn "In finally...")))

Now it will handle the exception. But if you use a wrong type of exception it will not catch that and in the end of the try statment it will give the error.

Writing a simple clojure program.
Now we will try to write a clojure program to add remove and change things.

(alias 'set 'clojure.set)
This wiil make an alias to clojure.set. Now we can use "set" word when ever we need to write clojure.set/smoething.

(defstruct employee :name :id :role)
This will create a structore named employee.
(def employee-records (ref #{}))
The "ref" is to allow mutation of a storage with transactions.

(defn- update-role [n r recs]
(let [rec (set/select #(= (:name %) n) recs)
others (set/select #(not (= (:name %) n)) recs)]
(set/union (map #(set [(assoc % :role r)]) rec) others)))
In this set of codes, "defn-" defineds a private function. As previously sed here we use set/select behalf of clojure.set/select.

(defn- delete-by-name [n recs]
(set/select #(not (= (:name %) n)) recs))
Both of these functions update and delete will do the operation and create a
new set of data, becouse these sequences are immutable.
Now you can see some public functions which will not cantaining a "-" sign when definding it.

(defn update-employee-role [n r]
"update the role for employee named n to the new role r"
(dosync
(ref-set employee-records (update-role n r @employee-records))))

(defn delete-employee-by-name [n]
"delete employee with name n"
(dosync
(ref-set employee-records
(delete-by-name n @employee-records))))

(defn add-employee [e]
"add new employee e to employee-records"
(dosync (commute employee-records conj e)))
Now the code is completed. Save this as test.clj and in the clojure prompt you
can import that coding by,

(load-file "test.clj")
Then you can do add delete and change employee details. Here is some
coding to add some data initially. Then after that you can view what you enered.(add-employee (struct employee "Jack" 0 :Engineer))
(add-employee (struct employee "Jill" 1 :Finance))
(add-employee (struct-map employee :name "Hill" :id 2 :role :Stand))
@employee-records

Clojure program Exception handling in clojure

Sep 29, 2010

More about monad haskell

Monad Whitespace

We can recognise one or more spaces by importing monads librerys. We can try by
this coding.
readExpr input = case parse (spaces >> symbol) "lisp" input of
Left err -> "No match: " ++ show err
Right val -> "Found value"

Return values
We can convert return valuer of some inputs. To do this we need to defined a data type which can store any data type. So for do that;

data LispVal = Atom String
| List [LispVal]
| DottedList [LispVal] LispVal
| Number Integer
| String String
| Bool Bool

This defineds a set of data types that the LispVal can hold.
Atom is a letter or a symbol which can be a charactor number or a symbol.

Generic monad
We can write our own monad thing by this way.

Sep 28, 2010

More on monad haskell

Monad transformers
Monads transformers are also in a formata of monads. So we must make MaybeT m an instance of the Monad class.
instance Monad m => Monad (MaybeT m) where
return = MaybeT . return . Just

This will get the monads return and send it ot the monadts constructore. This thing can be wriiten as,
x >>=f= MaybeT $ do maybe_value <- runMaybeT x case maybe_value of Nothing -> return Nothing
Just value -> runMaybeT $ f value

List transformer
newtype ListT m a = ListT { runListT :: m [a] }

We can transform list also and to do that we need to crerate a datatype with a constructoore which takes an argument.

LiftM
This is a library which can transfer the non-monadic functions to monadic ones. The function is like this.
liftM :: Monad m => (a1 -> r) -> m a1 -> m r

Converting non-monadic:- myFn $ NonMonadic
Converting monadic :- myFn `liftM` monadic

Pasing monad
This is more powerful parser with monads like Maybe, list and sate. This will use parcer librery functions also. So first of all we must import relevent librery functions to our program.
import System
import Text.ParserCombinators.Parsec hiding (spaces)
Now we are going to use a parser librery function call oneOf
symbol :: Parser Char
symbol = oneOf "!$%&|*+-/:<=>?@^_~"

This will keep track of each charactor. Then we must make some arrangements to handle the errors too.
readExpr :: String -> String
readExpr input = case parse symbol "lisp" input of
Left err -> "No match: " ++ show err
Right val -> "Found value"

Now we can write the program.
main :: IO ()
main = do args <- getArgs
putStrLn (readExpr (args !! 0))

Now you can run this by doing
ghc -package parsec -o filename.hs

Clojure Basics

Run clojure.jar by,
java -jar clojure.jar
and it will prompt,
user=>
Clojure got three main numerical types. Integr, Float and Ratio.
To do 1 + 2 it is; (+ 1 2)
If you need to defind a function you can defid as,
The function you need to defind is a = 2 + 3
So you can write it as,
user=> (def a(+ 2 3))
Then it will give an output as
#'user/a
and prompt user=>
If you type "a" in that you will get the output of 2+3 as 5.

Number formats
user=> 10 decimal 10
010 octal 8
0xff hex 255
1.0e-2 double 0.01
1.0e2 double 100.0

And also clojure supports a radix based entry format, in a form of (radix)r(number)
(note : 1(Integer/toString 10)
"10"
user =>(Integer/toBinaryString 10)
"1010"

String to Integer
user=>(Integer/parseInt "B" 16)
11
user=>(Integer/parseInt "10" 16) ; 16r10
16
user=>(Integer/parseInt "101" 8) ; 8r101
65
User =>(Integer/parseInt "10101" 2)

Data Structures
Creating a stucture;
(defstruct employee :name :id)
Using the structures
(struct employee "Mr. X" 10)
We can make functions from these things and get values from them like;
(def e1(struct employee "Nimal" 324))
And if you type e1 it will give an output like
{:name "Nimal", :id 324}
Also you can get only a value you need by typing like;
(e1 :name)
This will print the name of e1.

We can use accessor function to get easy access of feilds. It is like this.
(def emp-name(accessor employee :name))
Now if you want to get the employee name of e1 you cann type as;
(emp-name e1)

Add or remove new fields to structures
We can only remove fields which are added by assoc, can't delete the fields which are defined by defstruct.
Adding
(def e1-new (assoc e1 :function "engineer"))
e1-new
It will give the output as;
{:name "Nimal", :id 324, :function "engineer"}
Removing
(def e1-rm (dissoc e1-new :function))
e1-rm

Sep 27, 2010

Starting clojure with Labrepl

Labrepl is an environment for exploring the Clojure language. It is a web base application.

Before downloading labrepl you must check if you got github, java and leiningen.
Then make a directory and download the labrepl repository into that directory. So for do that;


git clone git://github.com/relevance/labrepl.git

Change the directory into that and type;

lein deps to install all the dependent libraries. This will take some time.

Then run;
script/repl
This will launch the labrel.

Now you can goth http://localhost:8080 for the labs.

And press Ctrl+D to exit.