Pros and Cons of Different Languages

Sage
Posts: 1,403
Joined: 2005.07
Post: #31
Blacktiger Wrote:I like beautiful code.

Any examples?

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
Member
Posts: 254
Joined: 2005.10
Post: #32
An example of some nice Haskell. This was my final project for my senior elective at KU. Haskell is still not my favorite language, but it does show that you can write good code in any paradigm. If you want to run it you will need GHC. The test functions at the bottom work, but I was having a problem with the old database entries not being removed. I was going to fix it but my professor told me that it was fine and to enjoy graduation. I may go back later to fix it, but I haven't had the motivation yet. Wink

Code:
{-# OPTIONS -fglasgow-exts                #-}
{-# OPTIONS -fallow-undecidable-instances #-}
{-# OPTIONS -fno-monomorphism-restriction #-}

{- Define the Company data structure. -}
data Company = C [Dept]              deriving (Eq, Show)
data Dept = D Name Manager [SubUnit] deriving (Eq, Show)
data SubUnit = EU Empl | DU Dept     deriving (Eq, Show)
data Empl = E Person Salary          deriving (Eq, Show)
data Person = P Name Address         deriving (Eq, Show)
data Salary = S Float                deriving (Eq, Show)
type Manager = Empl
type Name = String
type Address = String

{- Define the State Monad -}
data State s o = State (s->(s,o))
instance Monad (State (Return Company)) where
    return o = (State (\s->(s,o)))
    (State st0) >>= op =
        State $ \s0 -> let
                        (s1, o) = (st0 s0)
                        (State st1) = (op o)
                        in (st1 s1)
get = State(\s->(s, s))
put s = State(\s->(s, ()))
modify f = State $ \s->(f s, ())
runState (State f) s0 = (f s0)
db (state, output) = state
result (state, output) = output

{- Define Exception Throwing -}
data Return e = Return e | Exception String deriving Eq
instance (Show e)=>Show (Return e) where
    show (Return value) = show value
    show (Exception error) = show error
instance Monad Return where
    return a = Return a
    (Return a) >>= f = f a
    (Exception a) >>= f = Exception a
printStr (Return c) = putStr c

{-
    (findDept name company) - Locate a department with name in company.
    (findEmpl name department) - Locate an employee in a department.
    (addDept department company) - Add a department in a company.
    (addEmpl employee department) - Add an employee in a department.
-}
class Database t where
    findDept::String->t->Return Dept
    findDept n d = Exception "Attempted to find department in the wrong structure!"
    findEmpl::String->t->Return Empl
    findEmpl n e = Exception "Attempted to find employee in the wrong structure!"
    addDept ::Dept->t->Return t
    addDept d c = Exception "Unable to add department to non-company structure!"
    addEmpl ::Empl->t->Return Dept
    addEmpl e d = Exception "Unable to add employee to non-department structure!"
    toXml::t->Return String
    toXml c = Return (xml c "")
    xml::t->String->String

instance Database Company where
    findDept name (C ds) = findDept name ds
    findEmpl name (C ds) = findEmpl name ds
    addDept department (C ds) = Return (C (department:ds))
    xml (C ds) indent = "<company>\n"++(xml ds ("   "))++indent++"</company>"
instance Database Dept where
    findDept name (D dept m subunits) = if name == dept
                                        then Return (D name m subunits)
                                        else findDept name subunits
    findEmpl name (D _ manager subunits) = case (findEmpl name manager) of
                                            Exception m -> (findEmpl name subunits)
                                            Return value -> Return value
    addDept dept (D n m subunits) = Return (D n m ((DU dept):subunits))
    addEmpl empl (D n m subunits) = Return (D n m ((EU empl):subunits))
    xml (D n m sus) indent = indent++"<department name=\""++n++"\" >\n"++
                                (xml m (indent++"   "))++"\n"++(xml sus (indent++"    "))++
                                indent++"</department>"
instance Database SubUnit where
    findDept name (DU dept) = findDept name dept
    findDept name (EU dept) = Exception "Looking for Dept in Empl!"
    findEmpl name (DU empl) = Exception "Looking for Empl in Dept!"
    findEmpl name (EU empl) = findEmpl name empl
    xml (DU dept) indent = indent++"<subunit type=\"department\">\n"++
                                (xml dept (indent++"    "))++
                                "\n"++indent++"</subunit>"
    xml (EU empl) indent = indent++"<subunit type=\"employee\">\n"++
                                (xml empl (indent++"    "))++
                                "\n"++indent++"</subunit>"
instance Database Empl where
    findEmpl name (E (P ename a) s) = if name == ename
                                        then Return (E (P ename a) s)
                                        else Exception (name++" was not found")
    xml (E p s) indent = indent++"<employee "++(xml p indent)++(xml s indent)++"/>"
instance Database Person where
    xml (P n a) indent = "name=\""++n++"\" address=\""++a++"\" "
instance Database Salary where
    xml (S a) indent = "salary=\""++(show a)++"\" "
instance (Database d)=>Database [d] where
    findDept name (d:ds) = case (findDept name d) of
                            (Exception m) -> (findDept name ds)
                            (Return value) -> Return value
    findDept name [] = Exception (name++" was not found.")
    findEmpl name (d:ds) = case (findEmpl name d) of
                            Exception m -> (findEmpl name ds)
                            Return value -> Return value
    findEmpl name [] = Exception (name++" was not found.")
    xml (d:ds) indent = (xml d indent)++"\n"++(xml ds indent)
    xml [] indent = ""


-- Extra Operations
removeDeptD::String->Dept->(Return Dept)
removeDeptD dept (D n m subunits) = Return (D n m (removeDeptDR dept subunits))
removeDeptDR dept ((DU (D name m s)):ds) = if name == dept
                                            then ds
                                            else ((DU (D name m s)):(removeDeptDR dept ds))
removeDeptC::String->Company->(Return Company)
removeDeptC dept (C ds) = Return (C (removeDeptCR dept ds))
removeDeptCR n ((D name m s):ds) = if name == n
                                    then ds
                                    else (D name m s):ds

{- Recursive Bindings for Search and Insert Operations -}
searchDeptC::[String]->Return Company->Return Dept
searchDeptC (d:ds) c = searchDeptD ds (c >>= (findDept d))
searchDeptD (d:ds) r = searchDeptD ds (r >>= (findDept d))
searchDeptD [] r = r

searchEmplC::[String]->Return Company->Return Empl
searchEmplC (d:ds) c = searchEmplD ds (c >>= (findDept d))
searchEmplD (d:ds) r = if ds == []
                        then r >>= (findEmpl d)
                        else searchEmplD ds (r >>= (findDept d))

insertDeptC::[String]->Dept->Return Company->Return Company
insertDeptC _  _ (Exception e) = Exception e
insertDeptC [] d r = r >>= (addDept d)
insertDeptC (d:ds) new r = case insertDeptD ds new (r >>= (findDept d)) of
                                    (Return dept) -> r >>= (removeDeptC d) >>= (addDept dept)
                                    (Exception e) -> Exception e
insertDeptD::[String]->Dept->Return Dept->Return Dept
insertDeptD (d:ds) new r = case insertDeptD ds new (r >>= findDept d) of
                            (Return dept) -> r >>= (removeDeptD d) >>= (addDept dept)
                            (Exception e) -> Exception e
insertDeptD [] new r = r >>= addDept new

insertEmplC::[String]->Empl->Return Company->Return Company
insertEmplC _ _ (Exception e) = Exception e
insertEmplC (d:ds) e r = case insertEmplD ds e (r >>= (findDept d)) of
                                        (Return dept) -> r >>= (removeDeptC d) >>= (addDept dept)
                                        (Exception e) -> Exception e
insertEmplD (d:ds) e r = case insertEmplD ds e (r >>= findDept d) of
                            (Return dept) -> r >>= (removeDeptD d) >>= (addDept dept)
                            (Exception e) -> Exception e
insertEmplD [] e (Return (D n m sus)) = (Return (D n m ((EU e):sus)))

-- A Company for testing.
myCompany  = C myDepts
myDepts    = [research, management]
research   = D "Research"        george [EU joe, EU dan]
management = D "Management"      bob    [DU personnel]
personnel  = D "Personnel"       alex   [DU hresources]
hresources = D "Human Resources" jane   [EU kathy]
alex       = E (P "Alex" "2 No Life Lane")       (S 15.3)
bob        = E (P "BOB" "They're Everywhere!")   (S 20.5)
dan        = E (P "Dan" "20 Second Best Street") (S 30.6)
george     = E (P "George" "1 Main Street")      (S 10.1)
jane       = E (P "Jane" "10 Plane Street")      (S 5.2)
joe        = E (P "Joe" "12 Blue Street")        (S 28.3)
mike       = E (P "Mike" "101 Cool Lane")        (S 10.8)
kathy      = E (P "Kathy" "12 Dark Drive")       (S 8.2)

-- Test the addDept Function
testAD = addDept research (C [])
testAE = addEmpl alex management
testS = (searchDeptC ["Personnel", "Human Resources"] (Return myCompany))

{-
    Parts 3->7
    Note that a department must have a manager and the manager must be created
    this implementation is missing the seperation a real database would have.
-}
dotest = do {
               database <- get;
               database2 <- modify (insertDeptC [] (D "Research" george []));
               database3 <- modify (insertDeptC [] (D "Management" bob []));
               database5 <- modify (insertEmplC ["Research"] joe);
               database6 <- modify (insertEmplC ["Research"] dan);
               database6 <- modify (insertEmplC ["Research"] alex);
               return (searchDeptC ["Research"] database)
            }
runtest = (result (runState dotest (Return (C []))))
runtest1 = printStr ((db (runState dotest (Return (C[])))) >>= toXml)
dotest3 = do {
                database <- get;
                database2 <- modify (insertDeptC [] (D "Research" george []));
                database3 <- modify (insertDeptC [] (D "Management" bob []));
                database4 <- modify (insertDeptC ["Management"] (D "Personnel" alex []));
                database5 <- modify (insertDeptC ["Management", "Personnel"] (D "Human Resources" jane []));
                database5 <- modify (insertEmplC ["Research"] joe);
                database6 <- modify (insertEmplC ["Research"] dan);
                database7 <- modify (insertEmplC ["Management", "Personnel", "Human Resources"] kathy);
                return "Done"
             }
test3 = runState dotest3 (Return (C []))
company = db (runState dotest3 (Return (C [])))
dotest4 = do {
                database <- get;
                case (searchEmplC ["Management", "Personnel", "Human Resources", "Kathy"] database) of
                    (Return (E (P name _) _)) -> return (name++" was found.")
                    (Exception e) -> return e
             }
test4 = result (runState dotest4 company)
dotest5 = do {
                database <- get;
                case (searchEmplC ["Management", "Personnel", "Human Resources", "Alex"] database) of
                    (Return (E (P name _) _)) -> return (name++" was found.")
                    (Exception e) -> return e
             }
test5 = result (runState dotest5 company)
dotest6 = do {
                database <- get;
                result <- let (Return (E (P n a) s)) = (searchEmplC ["Management", "Personnel", "Human Resources", "Kathy"] database)
                in modify (insertEmplC ["Management", "Personnel", "Human Resources"] (E (P "Coolio" a) s));
                return result
             }
test6 = db (runState dotest6 company)
test7 = printStr (company >>= toXml)
Quote this message in a reply
Member
Posts: 312
Joined: 2006.10
Post: #33
That some of the hardest code to read if you don't know Haskel (or similar languages). I can't make any sense of it Rasp
Quote this message in a reply
Moderator
Posts: 592
Joined: 2002.12
Post: #34
bronxbomber92 Wrote:That some of the hardest code to read if you don't know Haskel (or similar languages). I can't make any sense of it Rasp

Having never seen any Haskel code before I would not say it is hard to work out what is going on. No harder than looking at any other unknown language. Or maybe I just have years of experience reading code in various languages not written by myself.
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #35
There's a lot I don't like about this code like syntactically its very compacted which makes it harder to read that normal haskell, also you are generating structured output (XML) in a non structured way (raw string concatenation) which to me seems like missing the point. all in all theres a lot of mention of data types Monads and instances which aren't at the heart of the problem you are trying to solve..

My favorite haskell code this definition of the Y combinator
Code:
y f = f (y f)

It highlights that haskell is lazy and its the most intuitive definition of how I (at least) would explain it.

I guess we look for different things and I can see why you don't like lisp (programming structurally)

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
Member
Posts: 254
Joined: 2005.10
Post: #36
unknown Wrote:all in all theres a lot of mention of data types Monads and instances which aren't at the heart of the problem you are trying to solve..

Well that code was for our final monad project, so there are a fair amount of unnecessary concepts there, but I think the use of the code is fairly straightforward otherwise. And of course, "beauty is in the eye of the beholder".

I thought of another project that I did, this one just for fun. I wrote an xhtml helper script for PHP that is somewhat similar to the perl html stuff. This is what using it looks like.

Code:
<?php include_once('xhtml.php');

$page = new xhtml("My Test Page");
$page->body->contents[] = xhtml::p("A sample paragraph.");
$page->body->contents[] = xhtml::h1("A sample header.");
$page->body->contents[] = xhtml::h2("Colored Text!", array('color'=>'blue'));
print $page;

?>

It only looks great if you already know PHP I think, just because I used the append operator built-in to PHP. I also used static class methods, and it just so happens that the call for them looks like scope resolution.
Quote this message in a reply
Moderator
Posts: 370
Joined: 2006.08
Post: #37
I must say that that php script is rather clean and 'beautiful'...especially compared to most of the ones I write Rasp
-wyrmmage

Worlds at War (Current Project) - http://www.awkward-games.com/forum/
Quote this message in a reply
Member
Posts: 567
Joined: 2004.07
Post: #38
PHP's syntax makes me feel like I'm swearing all the time because of the unnecessary dollar signs. Also, the class system is poorly implemented and awkward to use. Overall, the language feels like it has the speed of an interpreted language and the programming of a low-level language: the worst of both worlds.

If you want a clean, beautiful language, try lisp (or its variants), ruby, or ARM assembly. Hell, even brainfuck is better.

It's not magic, it's Ruby.
Quote this message in a reply
Moderator
Posts: 770
Joined: 2003.04
Member
Posts: 254
Joined: 2005.10
Post: #40
PHP5's object oriented features more closely resemble c++, and that makes it easy for a lot of programmers to learn it quickly. I do have to say that I like the idea of 'magic methods' but I don't think PHP uses them to the fullest. For example, I'd like to be able to define a magic method to replicate the normal $obj->var syntax but override the behavior. It seems to me like these should be used for allowing the programmer to override certain language features.
Quote this message in a reply
richard
Unregistered
 
Post: #41
I've been programming games in Python for years now. I don't understand all those comments at the start of the thread about Python's inconsistency. The language creator has always held a very tight leash on changes to the language such that it's always felt like any new feature fits in well with the rest of the language...


Anyhoo - the next Python Game Programming Challenge will start in a month. A perfect time to get your hands dirty Smile
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Best/Fastest - What do the pros use? carmine 6 3,847 Jun 6, 2008 11:51 AM
Last Post: arekkusu
  High and Low Level Languages FlamingHairball 22 9,997 Jan 8, 2008 10:23 PM
Last Post: PowerMacX
  What languages do you need for a MMORPG? Lost22 12 5,626 Nov 20, 2007 01:07 AM
Last Post: Lost22
  Re-introduction of low level languages? Duane 4 3,149 Oct 30, 2007 03:10 AM
Last Post: OneSadCookie
  Some questions on languages from a new guy (...beginners) ProfessorApe 20 7,804 Jan 24, 2007 03:10 PM
Last Post: leRiCl