Haskell Data Sequence Example Essay - Essay for you

Essay for you

Haskell Data Sequence Example Essay

Rating: 4.3/5.0 (17 Votes)

Category: Essay

Description

Differentiate Between Java Haskell And Scala English Language Essay

Differentiate Between Java Haskell And Scala English Language Essay

Published: 23rd March, 2015 Last Edited: 23rd March, 2015

This essay has been submitted by a student. This is not an example of the work written by our professional essay writers.

This project is a work done which enables us to find out which is best for todays fast educating universities in the undergraduate level .The project mainly describes about which programming language is apt for the under graduation student in the fast programming world. Here the differentiation is done between Java. Haskell and Scala programming languages, where java is a object-oriented language. Haskell is functional programming language and Scala is a combination of both object oriented and functional programming concepts. Here some topics are discussed which explains the differences between all the three programming languages. They are Errors, File Input-Output, Modular programming. Parallel programming, Database Connectivity, Tree sorting. Web Interface. The above contents are explained briefly with suitable examples for the clear understanding and the capacity of differentiating between all the listed languages. Making you to understand the differences between the languages and selecting one of them with the suitable information and selecting one particular language for the under graduate students is the main aim. Understanding the concepts with suitable examples with advantages and disadvantages is the development phase of this project and the evaluation phase of this project is done when the we drag a conclusion which programming language is apt for the undergraduate student. This project itself has educational benefits where we can get the brief knowledge of all the three programming languages.This project reaches the final destination when we pick a particular language for the under graduate student .

Introduction

The main aim of this project is to differentiate between java. Haskell and scala programming languages which encompasses all the information for errors, modular programming, web interface, file input-output, linked lists. Once the difference between the languages is done using the above contents is explained, the objective would be to a conclusion which programming language is best to teach in this programming world. The goal of this project is to enable universities to get the knowledge of Scala programming language which is new to the programming world and know which programming language is best for the undergraduate students. The main problem is that, there is no such project where we differentiate between three different programming languages and at the end of the project we select one of the three which is apt for the undergraduate students.

My main aim and objectives of the project would be to :

… Understand Java in the context of selected topics

Learn and understand java

Draw some examples the topics.

… Understand Haskell in the context of selected topics

Learn and understand Haskell

Draw some examples the topics.

… Understand Scala in the context of selected topics

Learn and understand Scala

Draw some examples the topics.

…. Differentiate between which programming language is best for the universities to educate undergraduate student in this present fast running programming world.

Background and literature review

Sun Microsystems developed a high-level programming language. OAK was the language from which java was originally called and it was designed for set-top boxes and handheld devices. In 1995 Oak was unsuccessful and it changed its name to java. Java is an object-oriented language which is similar to C++, and it was simplified to eliminate the language feature that may cause the common programming errors. Java is developed as a general purpose programming language which has number of features that makes the language well suited for use on world wide web.

Haskell is a general purpose purely functional programming language which is standardized. with strong static typing and non-strict semantics. Haskell is named after logician Haskell Curry and in Haskell ," a function is a first-class citizen" of the programming language. The first version of haskell was Haskell 1.0 and was defined in 1990, later in February 1999, Haskell 98 language standard was originally published. In early 2006 it is was named as Haskell prime. Here the process of defining a successor to the Haskell 98 standard is named as Haskell prime. Finally the latest version is Haskell 2010 which adds the foreign function interface (FFI) to Haskell. Here it allows binding to other programming language and it fixes some syntax issues and bans and so called " n-plus-k-patterns" are no longer allowed. Haskell does not have any side effects. Haskell has more than 2600 third party open source libraries and tools. Hugs ( Haskell User's Gofer System) is a byte code interpreter and it does fast compilation of programs and it has reasonable execution speed.

Scala is a general programming language that integrates features of object- oriented language and functional programming language which enables java and other programmers to be more productive. When we compare scala with a java application, the code size is reduced by a factor of two to three. Now a days, many existing companies which depend on java for the good running of business critical applications are turning towards scala to boost their development productivity, applications scalability and overall reliability. Many top-notch programmers and industry leaders have already been captivated by Scala. We know that Twitter is a social networking service. here the core message is moved from ruby to scala. This shows how scala programming language can reduce the code size and reaching its heights. In the same way we can change java and Haskell code to scala.

File IO states that Input/Output operations such as close, open, write, read and append all deals with standard disk or tape files. The term is used to refer to regular file operations in contrast to the low-level system I/O such as dealing with operating system tables of contents or virtual memory pages.The latter are closed, opened. written and read which are typically hidden from the user's view.

FILE IO in java

This code is designed to show how we can read a text file which is named as test.txt and shows its contents.

FILE I/O IN HASKELL

Haskell programs are mainly executed by evaluating the 'main' function.

GHCi is the interactive Haskell environment which is a bit different.As GHCi is an interactive

system it must execute the code sequentially, as wedefine each line.GHCi effectively executes the code

inside a do-block.

Operating on standard input/output is good for scripts. The basic operations of files are:

readFile. FilePath -> IO String

writeFile. FilePath -> String -> IO ()

'readFile' is the file that takes a file name as an argument, does some IO and returns the

contents of the file to the string.

'writeFile'is the file that takes a file name. a string and then it does some IO, before it returns the

First of all we have to implement a 'cp' programs on files, as:

s <- readFile f

output of this program is :

s <- readFile f

AS we are working with IO the code runs inside a do-block using the

IO monad.Using this means that we wish to use an imperative. sequential order

FILE IO IN SCALA

Using a language procedural type programming goes both the ways. The file IO is wrapped up in the 'Source.fromFile' method call which returns a 'Source' object that already populated with the file's contents. Then the getLines method is called which returns an iterable collection.

LINKED LISTS IN JAVA

A linked list is a data structure that consists of a sequence of data records, where for each record there is a field that contains a reference (i.e. a link) to the next record in the sequence. Nodes of a linked list contain two fields: an integer value and a link to the next node. Linked lists are among the simplest and most common data structures; which provide an easy implementation for several important including stacks, abstract data structures, queues, associative arrays, and symbolic expressions.

The benefit of a linked list over array is that, that the order that the data items are stored in memory or on disk may be different from the order of the linked items. For this reason, linked lists allow removal and insertion of nodes at any point in the list, with constant number of operations.

On the other hand, linked lists do not allow random access to the data, or any form of efficient indexing. Many basic operations like obtaining the last node of the list, or finding a node that contains a given datum, or locating the place where a new node should be inserted - may require scanning most of the list elements.

This example uses six methods of LinkedList class.

add(Object o): Appends the particular element to the end of this list and it returns a boolean value.

size(): Returns the number of elements in this list.

addFirst(Object o): At the beginning of this list the element is inserted.

addLast(Object o):At the last of this list the element is inserted .

add(int index,Object o): In the list the element is inserted at the specified position. It throws IndexOutOfBoundsException if index is out of the range.

remove(int index): Remove the element at the position in this list. It returns the element which was removed from the list. It throws IndexOutOfBoundsException if index is out of the range.

The code of the program is given below:

public class LinkedListDemo<

public static void main(String[] args)<

LinkedList link=new LinkedList();

System.out.println("The contents of array is" + link);

System.out.println("The size of an linkedlist is" + link.size());

System.out.println("The contents of array is" + link);

System.out.println("The size of an linkedlist is" + link.size());

System.out.println("The contents of array is" + link);

System.out.println("The size of an linkedlist is" + link.size());

System.out.println("The contents of array is" + link);

System.out.println("The size of an linkedlist is" + link.size());

System.out.println("The contents of array is" + link);

System.out.println("The size of an linkedlist is" + link.size());

System.out.println("The contents of array is" + link);

System.out.println("The size of an linkedlist is" + link.size());

Output of the program will be like this:

The contents of array is[a, b, 10]

The size of an linkedlist is3

The contents of array is[20, a, b, 10]

The size of an linkedlist is4

The contents of array is[20, a, b, 10, c]

The size of an linkedlist is5

The contents of array is[20, a, j, b, 10, c]

The size of an linkedlist is6

The contents of array is[20, t, a, j, b, 10, c]

The size of an linkedlist is7

The contents of array is[20, t, a, b, 10, c]

The size of an linkedlist is6

ADVANTAGES of linked lists:

The biggest advantage of linked lists is that they can be expanded in constant time without memory overhead.

For example when we make an array we must allocate memory for a certain number of elements. If we want to add more elements to the array than we allocated to create a new array and copy the old array into the new array. This can take lots of time. This can be prevented by allocating lots of space initially but then we might allocate more than we need wasting memory.

With a linked list we can start with space for just one element allocated. And add on new elements easily without the need to do any copying and reallocating.

Advantages of using linked lists are:

1.Memory utilization is very high in linked list i.e when user want another node then he will create and the nodes in the list are not contigous. So the memory is greatly utilized.

2.Deleting or inserting nodes from a linked list is very easy at any place of the linked list.

3.And data can be dis-similar types.All the nodes need not have the same type of data.

It does not allow to access randomly.

lINKED LISTS IN HASKELL

insert After a b (c:cs) | a == c = a. b. cs

| otherwise = c. insertAfter a b cs

insertAfter _ _ [] = error "Can't insert "

Here. in Haskell the kind of lists manipulation is called unidiomatic. Even though we can try this code for the single linked lists.

LINKED LISTS IN SCALA

def traverse1 [T] (xs. Seq [T] ). Unit = xs match

Case s if s.isEmpty => ()

def traverse2 [T] (xs. Seq[T]) = for ( x<- xs) Console.println (x)

Scala has a Seq ( for sequence ) trait that is more general than single -linked lists. Here the above examples are equivalent for SLL. The second would be faster for other types of sequence.

LINKED LISTS IN SCALA

Linked lists are mutably sequenced that consist of nodes which are linked with the next pointers which are supported by class linked lists. Most in languages null would be used as an empty linked list. That does not work for Scala collections, because in scala programming language even empty sequences must support all the sequence methods. In particular LinkedList.empty.isEmpty should return true and should not throw a NullPointerException. Empty linked lists are encoded in a special way: Their next field points back to the node itself. Like their immutable cousins, linked lists are best traversed sequentially. In addition to this linked lists make it easy to insert an element or linked list into another linked list. The example below shows how we can hold a piece of data and refer to the next code.

Class MyList( val head. Any, val tail. MyList)

def isEmpty= ( head == null && tail == null)

def length. Int = if (isEmpty) 0 else 1 + tail.length

override def toString. String = if (isEmpty) "" else head + " " +tail

MODULAR PROGRAMMING in java

Modular programming is a technique that increases the extent where software is composed from separate parts, called modules. Modular programming divides work for multiple programmers. Here software architect specifies data types and each programmer writes, debugs and tests one. Modules improve maintainability and separation of concerns by enforcing logical boundaries between components. Modular programming is used to break up a large program into manageable units, or to create code that can be easily re-used. A modular program consists of a main module and one or more auxiliary modules. Each module originates from a separate source code file. The main module is compiled as an EXE, and calls functions in the auxiliary modules. The auxiliary modules can be dynamically linked which means that they exist as separate executable files (DLLs) which are loaded when the main EXE is run; or they can be statically linked which mean that they are compiled as object files or static libraries (LIBs) that are combined with the main module into a single executable file.

The advantages of using modular programming:

ïƒ Makes the program run faster

ïƒ Makes the program run more clearer

ïƒ Reuse the code.

Modular programming defines a new classes in terms of old ones and keep all classes small. One of the example for modular programming is Cards. The main operation when we consider this example is that. that we have to first initialize, then we have to draw the front or back using graphics library and the finally we need to convert to string representation.

As we have discussed that modular programming reuses code in the same way the codes for cards and deck game can be reused to blackjack or poker games.

public class Card <

private int suit, rank;

private String front, back;

public Card(int card, String front, String back) <

this.rank = card % 13;

this.suit = card / 13;

Here. unit testing is done where each class can have its own main and for debugging it spends less overall time.

MODULAR PROGRAMMING IN HASKELL

The central concept in computing in modularity. John Hughes states in a topic in one of his paper that

"Languages which aim to improve productivity must support modular programming well. But new scope rules and mechanisms for separate compilation are not enough - modularity means more than modules. Our ability to decompose a problem into parts depends directly on our ability to glue solutions together. To assist modular programming, a language must provide good glue.

Functional programming languages provide two new kinds of glue - higher-order functions and lazy evaluation."

Modular programming in scala

Here is the example which explain how modular programming is done using scala programming language.

// In file modules/Food.scala

abstract class Food(val name: String) <

override def toString = name

// In file modules/Recipe.scala

val name: String,

val ingredients: List[Food],

val instructions: String

override def toString = name

// In file modules/Foods.scala

object Apple extends Food("Apple")

object Orange extends Food("Orange")

object Cream extends Food("Cream")

object Sugar extends Food("Sugar")

object FruitSalad extends Recipe(

List(Apple, Orange, Cream, Sugar),

"Stir it all together."

// In file modules/Ex1.scala

def allFoods = List(Apple, Orange, Cream, Sugar)

def foodNamed(name: String): Option[Food] =

def allRecipes: List[Recipe] = List(FruitSalad)

def recipesUsing(food: Food) =

scala> val apple = SimpleDatabase.foodNamed("Apple").get

apple: Food = Apple

res0: List[Recipe] = List(fruit salad)

// In file modules/Ex2.scala

def allFoods = List(Apple, Orange, Cream, Sugar)

def foodNamed(name: String): Option[Food] =

def allRecipes: List[Recipe] = List(FruitSalad)

case class FoodCategory(name: String, foods: List[Food])

private var categories = List(

FoodCategory("fruits", List(Apple, Orange)),

FoodCategory("misc", List(Cream, Sugar)))

def allCategories = categories

def recipesUsing(food: Food) =

def displayCategory(category: SimpleDatabase.FoodCategory) <

27.3 Abstraction

Abstraction is the process of taking away or removing characterteristics.In the process of abstraction. the programmer tries to entity is named in such a manner that they will make a sense and that it will have all relevant aspects included .

In scala we have different types of abstraction :

Value abstracting over value

Value abstracting over type

Type abstracting over type

// In file modules/Ex5.scala

abstract class Browser <

val database: Database

def recipesUsing(food: Food) =

def displayCategory(category: database.FoodCategory) <

// In file modules/Ex3.scala

abstract class Database <

def allFoods: List[Food]

def allRecipes: List[Recipe]

def foodNamed(name: String) =

allFoods.find(f => f.name == name)

case class FoodCategory(name: String, foods: List[Food])

def allCategories: List[FoodCategory]

// In file modules/Ex4.scala

object SimpleDatabase extends Database <

def allFoods = List(Apple, Orange, Cream, Sugar)

def allRecipes: List[Recipe] = List(FruitSalad)

private var categories = List(

FoodCategory("fruits", List(Apple, Orange)),

FoodCategory("misc", List(Cream, Sugar)))

def allCategories = categories

// In file modules/SimpleBrowser.scala

object SimpleBrowser extends Browser <

val database = SimpleDatabase

scala> val apple = SimpleDatabase.foodNamed("Apple").get

apple: Food = Apple

res1: List[Recipe] = List(fruit salad)

// In file modules/StudentDatabase.scala

object StudentDatabase extends Database <

object FrozenFood extends Food("FrozenFood")

object HeatItUp extends Recipe(

"heat it up",

"Microwave the 'food' for 10 minutes.")

def allFoods = List(FrozenFood)

def allRecipes = List(HeatItUp)

def allCategories = List(

object StudentBrowser extends Browser <

val database = StudentDatabase

27.4 Splitting modules into traits

Here the modules which are written above have been splitted in traits. Traits are used to define object types by specifying the signature of the supported methods.Traits may not have the constructors. As java allows. scala also allows traits to be partially implemented i.e it is possible to define implementation for some methods.

// In file modules/FoodCategories.scala

case class FoodCategory(name: String, foods: List[Food])

def allCategories: List[FoodCategory]

// In file modules/Ex5.scala

abstract class Database extends FoodCategories <

def allFoods: List[Food]

def allRecipes: List[Recipe]

def foodNamed(name: String) =

allFoods.find(f => f.name == name)

// In file modules/SimpleDatabase.scala

object SimpleDatabase extends Database

with SimpleFoods with SimpleRecipes

// In file modules/SimpleFoods.scala

object Pear extends Food("Pear")

def allFoods = List(Apple, Pear)

def allCategories = Nil

trait SimpleRecipes < // Does not compile

object FruitSalad extends Recipe(

List(Apple, Pear), // Uh oh

"Mix it all together."

object browser extends Browser <

val database: db.type = db

An Error is defined as a mistake or a wrong action which is attributable to bad judgment .Errors can be occured due to many bad programming skills.Errors are

nothing but bugs or also known as programming errors often occured while learning a new programming language.

There are many types of errors which has its own method of detection and repair. Basic types of errors are :

Syntax errors - These errors are caught by javac compiler occured in grammar and punctution like mismatched quotes, missed commas or any type of case sensitive issues.

if (i > j // Error, unbalanced parentheses/

max = i // Error, missing semicolon

Runtime errors- These errors are shown during the program exection. Division by zero is a common example which is caught by static testing.

// A happy message is written to the screen!

public static void main(String[] args) <

//Write the message to the terminal window

System.out.println("Hi I am very happy!");

Here the above small piece of code have been saved as a file called " HappyMessage.java"

Here we can notice that the class name is "Happymessage" and the file is saved as "HappyMessage.java"

There will not be any problem with the compilation but there is a runtime error because when we run HappyMessage there is no filename called HappyMessage.class.

The error that is shown is

Exception in thread "main" java.lang.NoClassDefFoundError: HappyMessage (wrong name: HappyMessage)

Logic Errors - these are the basic errors in te programmer's algorithms or procedural errors. When incorrect results occur the diagnosis is to be done and the

solution requires mapping out the flow for test cases.

An example for logic errors is a wrong scoping of a variable and to come out of this error dynamic testing is required .

Incorrect operator precedence errors - This is a type of mathematical grouping errors.This error can be avoided with brackets which forces the grouping explicitly.

Threading error - this type of error occurs when multiple threads are programmed. Common issues that occur in this type of error are acccess, deadlock ,

syncronization and this type of errors are very difficult to trace out.

ERRORS IN HASKELL

A collection of error messages and the code which produced them ; the entry message for the error message that is provoked can hopefully help us

to diagnose a particular problem.Error shows some code fragments, in red, followed by the error message they provoke, in blue, and an explanation of the source of the problem.

Some examples of hugs errors are:

ERROR: Improperly terminated character constant

The problem here is the use of the wrong sort of quotes. To turn a function, which is written before its arguments, into an operator, which is written between

its arguments, we need to enclose it in backquotes.

2) data BTree a = EmptyBTree | Node a (BTree a) (BTree a)

card. BTree a -> Integer

card EmptyBTree = 0

card (Node x) lt rt = (height lt) + (height rt) + 1

ERROR: Equations give different arities for "card"

Incorrect bracketing causes the problem here. It looks as though card is a one argument function (arity 1) from the first equation in the definition, and as though

it's a three argument function from the second. The misplaced closing bracket is the culprit, and a correct version of the code says

card (Node x lt rt) = (height lt) + (height rt) + 1

> maxFour. Int -> Int -> Int -> Int -> Int

> | a >= b && a >= c && a >= d = a

> | b >= c && b >= d = b

> | otherwise = d

ERROR "test.lhs" (line 3): Undefined variable "a"

The definition of maxFour has its variables missing. The 2nd line should read maxFour a b c d.

3) > f. Int -> [Int] -> [Int]

ERROR "test.lhs" (line 4): Syntax error in expression (unexpected `>', possibly due to bad layout)

The problem here is not so much bad layout as a missing closing parenthesis!

> type Fred = Int

ERROR "test.lhs" (line 2): Syntax error in input (unexpected keyword "type")

This problem happens because of the indentation of line 2 is incorrect; it should be indented to the same level as the first line.

> type Fred = Int

ERROR "test.lhs" (line 2): Syntax error in input (unexpected keyword "type")

This problem happens because of the indentation of line 2 is incorrect; it should be indented to the same level as the first line.

ERROR "test.lhs" (line 1): Undefined constructor function "Fun"

The syntax of the language dictates that names for functions and other defined values begin with a small letter. Names beginning with capitals are reserved for

constructors and for the types and the type classes. Here the use of a capital letter in Fun is seen to be the use of a constructor which is not defined.

> type Fun = Int

ERROR "test.lhs" (line 2): Syntax error in input (unexpected keyword "type")

The main problem is that, here type definitions are not allowed in where clauses.

ERROR "test.lhs" (line 1): Repeated variable "x" in pattern

Errors in scala

Btrieve error is the error that we can find in scala programming language.When we have a Btrieve error appears in Scala, two Btrieve error codes occur. Error code 1, is the code which tell us what the Scala was trying to do when the error is occurred ( write to a file, read from a file, open a file e.t.c.). This type of error code is of little concern. Error code 2 is a Btrieve-specific error code, where we can find the explanation in the Btrieve manual. Below,I have tried to give you some other examples concerning different kinds of error code 2.

Error code 1 Error code Explanation

Authors like Martin Odersky, Lex Spoon. Bill Venners strong beleive that Scala is best when compared with other programming language but David R. Maclver in his blog regarding " Why not Scala " does not completely agree completely with the other authors decision. He states that Scala is not a functional programming language but it pretends to be so and it has adequate support for functional programming. David R. Maclver lists the problems and says that :

Its pattern matching is cumbersome.

Annoying distinction between methods and functions.

The handling of multiple arguments is annoying and it doesnot have the pleasant feature of Haskellthat every function has a single argument.

The type inference is embarrassingly weak i.e the recursive methods will not have the return type inferred.

A tree sort is an algorithm which builds a binary search tree from the keys to be sorted, and then they traverses the tree so that the key would come out in sorted order. Sorting the elements of a stream from a file is the typical use of tree sorting. The act of loading the input into data structure is sorting it but in other sorts we would have to load the elements to a temporary data structure.

A binary search tree (BST), can also be called as ordered or sorted binary tree, is a node-based binary tree data structure which has the below properties:

The left subtree of a node contains only the nodes with keys less than node's key.

The right subtree of a node contains only the nodes with keys greater than node's key.

Both the left and right subtrees should also be a binary search trees.

The information shown by each node is a record rather than single data element. For sequencing purposes, the nodes are compared according to their keys rather than any part of the associated records.

The main advantage of binary trees over other data structures is that, that the related sorting algorithms and search algorithms such as in-order traversal is be very efficient.

Binary search trees are said to be fundamental data structure which are used to construct more abstract data structures such as the sets, multisets, and associative arrays.

Tree Sorting in java

Here in below example we can observe the iterative approach to inserting into a binary tree

public static void insert(Node root, int data) <

root = new TreeNode(data, null, null);

while (root != null) <

Tree sorting in Haskell

Here in this example code the binary search in done using Haskell programming language.

data Tree a = Leaf | Node (Tree a) a (Tree a)

insert. Ord a => a -> Tree a -> Tree a

insert x Leaf = Node Leaf x Leaf

insert x (Node t y t') | x <= y = Node (insert x t) y t'

insert x (Node t y t') | x > y = Node t y (insert x t')

flatten. Tree a -> [a]

flatten (Node t x t') = flatten t ++ [x] ++ flatten t'

treesort. Ord a => [a] -> [a]

treesort = flatten. foldr insert Leaf

Tree sorting in SCala

/** Quick sort, imperative style */

/** Nested methods can use and even update everything

* visible in their scope (including local variables or

* arguments of enclosing methods).

def sort(a: Array[Int]) <

def swap(i: Int, j: Int) <

val t = a(i); a(i) = a(j); a(j) = t

The term client/server describes one of the possible relationship between the two software applications in which the client makes a service request from the server. The client/server relationship can apply for two programs running on single computer or two programs running over a network. The client/server model provides a convenient way to interconnect the programs that are distributed efficiently across different locations, in the case of a network. Computer transactions using this client/server model are very common and it is likely we are involved with such a transactions almost daily.

For example, to check our e-mail from the computer, a client program on the computer forwards our request to a server program at our Internet Service Provider (ISP). Once the server program has retrieved our e-mail, it forwards them to a client on our computer, which then allows us to read the e-mail.

The client/server model has become one of the central ideas of the network computing. Most business applications being written today use the client/server model. A distinction used to be made between client/server applications and internet-based applications. However, that distinction is being blurred such that even internet-based applications are beginning to make use of the client/server model.

Using SQL Server (or Oracle) and Visual Basic,we can built complex and highly-scalable client/server based systems for a well-known international companies.

A network architecture in which each computer or process on network is either a client or a server. Servers are more powerful computers or processes dedicated to manage disk drives (file servers), printers (print servers), or network traffic (network servers ). Clients are PCs or workstations on which the users run applications. Clients rely on the servers for resources, such as devices, files and even processing power.

Another type of network architecture is known as a peer-to-peer architecture because each node has an equivalent responsibilities. Both client/server and peer-to-peer architectures are widely used, and each has unique disadvantages and advantages.

Client-server architectures are sometimes also called two-tier architectures.

CLIENT/SERVER in java

For testing this application we need to start the server side application. Each time we run the client application it will send a message "Hello There. " and in return the server reply with a message "Hi. ".

096.public class ClientSocketExample <

097.    public static void main(String[] args) <

098.        try <

099.            //

100.            // Create a connection to the server socket on the server application

101.            //

102.            InetAddress host = InetAddress.getLocalHost();

103.            Socket socket = new Socket(host.getHostName(), 7777);

105.            //

106.            // Send a message to the client application

107.            //

108.            ObjectOutputStream oos1 = new ObjectOutputStream(socket.getOutputStream());

109.            oos1.writeObject("Hello There. ");

111.            //

112.            // Read and display the response message sent by server application

113.            //

114.            ObjectInputStream ois1 = new ObjectInputStream(socket.getInputStream());

115.            String message = (String) ois1.readObject();

116.            System.out.println("Message: " + message);

118.            ois1.close();

119.            oos1.close();

120.        > catch (UnknownHostException e) <

121.            e.printStackTrace();

122.        > catch (IOException e) <

123.            e.printStackTrace();

124.        > catch (ClassNotFoundException e) <

125.            e.printStackTrace();

126.        >

Client/server in haskell

A simple TCP server which accepts multiple clients and echos input text back to all those connected. It uses threads to manage the multiple handling. and the Software Transactional Memory to pass the messages.

This text is a literate Haskell, and has been tested with ghc 6.6 on Linux/x86. Type annotations are included for the didactic purposes.

> module Main where > import Prelude hiding (catch)

Module Network is the simple networking library, presenting the Handle-based interface.

> import Network (listenOn, accept, sClose, Socket, > withSocketsDo, PortID(..)) > import System.IO > import System.Environment (getArgs) > import Control.Exception (finally, catch) > import Control.Concurrent > import Control.Concurrent.STM > import Control.Monad (forM, filterM, liftM, when)

A simple main is to parse a port number from the command line, and fire up the server socket.

> main = withSocketsDo $ do > [portStr] <- getArgs > let port = fromIntegral (read portStr. Int) > servSock <- listenOn $ PortNumber port > putStrLn $ "listening on: " ++ show port > start servSock `finally` sClose servSock

> start servSock = do > acceptChan <- atomically newTChan > forkIO $ acceptLoop servSock acceptChan > mainLoop servSock acceptChan []

acceptLoop manages the server socket, accepting the connections, starting client threads, and forwarding the relevant information about them over the channel so that the main loop can multiplex it all together.

> type Client = (TChan String, Handle) > > acceptLoop. Socket -> TChan Client -> IO () > acceptLoop servSock chan = do > (cHandle, host, port) <- accept servSock > cChan <- atomically newTChan > cTID <- forkIO $ clientLoop cHandle cChan > atomically $ writeTChan chan (cChan, cHandle) > acceptLoop servSock chan

As before, each client gets a loop which reads from handle and pumps the data right into a channel. However, this time, exception handling is done per-thread; if the client disconnects we just want the thread to die silently. A more clever implementation might have the more structured channel which allows it to indicate when client disconnects.

> clientLoop. Handle -> TChan String -> IO () > clientLoop handle chan = > listenLoop (hGetLine handle) chan > `catch` (const $ return ()) > `finally` hClose handle > listenLoop. IO a -> TChan a -> IO () > listenLoop act chan = > sequence_ (repeat (act >>= atomically. writeTChan chan))

STM conveniently allows the composition of actions which can make custom tailoring of the library code a snap. Here, we have added an additional action to check the status of acceptChan along with all the clients. The acceptChan has a different type than any of client channels, so I separate it from the others using an Either data type for the simplicity. `fmap` here acts very much like (.), the functional composition operator.

> mainLoop. Socket -> TChan Client -> [Client] -> IO () > mainLoop servSock acceptChan clients = do > r <- atomically $ (Left `fmap` readTChan acceptChan) > `orElse` > (Right `fmap` tselect clients) > case r of > Left (ch,h) -> do > putStrLn "new client" > mainLoop servSock acceptChan $ (ch,h):clients > Right (line,_) -> do > putStrLn $ "data: " ++ line

In addition to sending the data out to every client, this loop catches any errors from writing to handles and excludes that the client from the list.

> clients' <- forM clients $ > \(ch,h) -> do > hPutStrLn h line > hFlush h > return [(ch,h)] > `catch` const (hClose h >> return []) > let dropped = length $ filter null clients' > when (dropped > 0) $ > putStrLn ("clients lost: " ++ show dropped) > mainLoop servSock acceptChan $ concat clients'

tselect is a function which multiplexes any number of TChans. This will return a data from whichever TChan it can read, along with the "key" value that can be supplied in a pair. This takes advantage of the STM combinators orElse and retry by applying them to the list of actions constructed around a TChans.

> tselect. [(TChan a, t)] -> STM (a, t) > tselect = foldl orElse retry >. map (\(ch, ty) -> (flip (,) ty) `fmap` readTChan ch)

This code demonstrates a basic TCP server as well as more generally applicable function tselect. It serves as an example of the strength and simplicity of the Software Transactional Memory model, and of network IO in the Haskell.

Client/server in scala

abstract class Server <

 case class Helper(kind: String)

 val helper: Helper

object simpleServer extends Server <

Other articles