Differences between revisions 10 and 11
Revision 10 as of 2004-11-23 16:07:03
Size: 3433
Editor: 222
Comment:
Revision 11 as of 2004-12-11 11:50:30
Size: 5496
Editor: cache3-2
Comment: added python and haskell snippet
Deletions are marked like this. Additions are marked like this.
Line 61: Line 61:


== Using both Python & Haskell with ctypes (-; ==

Since, Python is the ultimate glue language, these Python vs. XLang should be replaced with Python "and" XLang.

First a test haskell program (mylib.hs):

{{{
module Mylib where

import CString

adder :: Int -> Int -> IO Int -- gratuitous use of IO
adder x y = return (x+y)

subtractor :: Int -> Int -> IO Int
subtractor x y = return (x - y)

fact :: Int -> Int
fact n =
    if n == 1 then 1 else (n * fact (n-1))

factorial :: Int -> IO Int
factorial n = return (fact n)


hello :: CString -> IO CString
hello w
 = do
   s <- peekCString w
   newCString (s ++ "World!")

mystring :: IO CString
mystring = newCString "hello world!"

foreign export stdcall adder :: Int -> Int -> IO Int
foreign export stdcall subtractor :: Int -> Int -> IO Int
foreign export stdcall factorial :: Int -> IO Int
foreign export stdcall hello :: CString -> IO CString
foreign export stdcall mystring :: IO CString
}}}

compile it as so by running this batch file (build.bat):
{{{
REM test making dll
ghc -c mylib.hs -fglasgow-exts
ghc -c dllMain.c
dlltool -A -z mylib.def mylib_stub.o --export-all-symbols
ghc --mk-dll -o mylib.dll mylib.o mylib_stub.o dllMain.o -optdll-def -optdll mylib.def

REM cleanup
rm mylib.o
rm mylib_stub.o
rm dllMain.o
rm mylib.hi
rm mylib_stub.c
rm mylib_stub.h
}}}

and then having installed ctypes, run the following python script (test_mylib.py) to test it:

{{{
#!python
from ctypes import *

lib = windll.mylib

api = {
    
# func name restype argtypes
    'adder' : (c_int, [c_int, c_int]),
    'subtractor': (c_int, [c_int, c_int]),
    'factorial' : (c_int, [c_int]),
    'hello' : (c_char_p, [c_char_p]),
    'mystring' : (c_char_p, []),
}
        

for func in api:
    f = getattr(lib, func)
    f.restype, f.argtypes = api[func]
    globals()[func] = f
    
print adder(1,2)
print subtractor(10,2)
print factorial(10)
print hello('hello')
print mystring()
}}}

Haskell

Haskell is a very modern functional language. It is used for some "real" projects (not just an experiment language) but is uncommon in industry. More information can be found at http://www.haskell.org/. (Please forgive or correct any errors here due to my not being very familiar with Haskell.)


Haskell and Python are a somewhat odd pair to compare, because they are so different in many ways. But what most users of both languages would agree they DO share is a certain elegance of design.

Functional vs Procedural:

Haskell is a lazy (evaluate by need), functional (no assignments or side-effects) language. It supports parametric polymorphism (ala C++ templates), and ad-hoc polymorphism through type classes (ala Java Interfaces). Python offers the programmer a profusion of styles, including procedural, functional, and object-oriented. Lazy programming can be accomplished using generators and itertools. Python has some support for a functional style of programming, but the profusion of side effects and the lack of tail recursion (elimination thereof), make it an awkward style to use in Python. Haskell supports procedural programming through monads (from category theory) which are also Haskell's interface to the world of side effects (e.g. graphics, file systems, sockets, etc.). However, imperative programming is neither Haskell's intention nor strength.

Compiled vs Interpreted:

Python's primary implementation is an interpreter. Haskell has a handful of implementations, including an interpreter (hugs) and some native-code compilers (ghc, nhc98). The biggest difference that this makes is in execution speed. When compiled, Haskell is surprisingly fast (surprising to those who think non-comercial languages are necessarily slowpokes), while nearly all Python programmers suggest that python is probably "fast enough", and that if it isn't, then the critical sections should be re-written in C/C++.

Static vs Dynamic Typing:

Both Haskell and Python have strong (not weak) typing... instances of a type can only be used as that type. But Haskell has static typing, while Python has dynamic typing. This means that in Haskell, the type of every expression and every variable is known at compile time (and strictly enforced), while in Python expressions and variables don't even HAVE a type (the objects they refer to have types, but that isn't known until runtime). Since typing is such a fundamental part of Haskell (it's part of what makes the language easy to reason about), this difference is a fundamental one. However, for those python users who shudder to think of typing "int i" before every variable use, take heart: Haskell is "static typing done right" because it has type inference. Usually, type declarations are optional because the compiler is smart enough to figure out the type for you.

There is also one similarity I feel compelled to point out:

List Comprehension Syntax:

Python's list comprehension syntax is taken (with trivial keyword/symbol modifications) directly from Haskell. The idea was just too good to pass up.

Significant Whitespace:

Both use indentation as syntax.

Learning Curve:

Haskell has a much steeper learning curve for programmers who are not used to functional programming.

Contributors: MichaelChermside

See also [LanguageComparisons].

Using both Python & Haskell with ctypes (-;

Since, Python is the ultimate glue language, these Python vs. XLang should be replaced with Python "and" XLang.

First a test haskell program (mylib.hs):

module Mylib where

import CString

adder :: Int -> Int -> IO Int -- gratuitous use of IO
adder x y = return (x+y)

subtractor :: Int -> Int -> IO Int
subtractor x  y = return (x - y)

fact :: Int -> Int
fact n = 
    if n == 1 then 1 else (n * fact (n-1))

factorial :: Int -> IO Int
factorial n = return (fact n)


hello :: CString -> IO CString
hello w 
 = do
   s <- peekCString w       
   newCString (s ++ "World!")

mystring :: IO CString
mystring = newCString "hello world!"

foreign export stdcall adder :: Int -> Int -> IO Int
foreign export stdcall subtractor :: Int -> Int -> IO Int
foreign export stdcall factorial :: Int -> IO Int
foreign export stdcall hello :: CString -> IO CString
foreign export stdcall mystring :: IO CString

compile it as so by running this batch file (build.bat):

REM test making dll
ghc -c mylib.hs -fglasgow-exts
ghc -c dllMain.c
dlltool -A -z mylib.def mylib_stub.o --export-all-symbols
ghc --mk-dll -o mylib.dll mylib.o mylib_stub.o dllMain.o -optdll-def -optdll mylib.def 

REM cleanup
rm mylib.o
rm mylib_stub.o
rm dllMain.o
rm mylib.hi
rm mylib_stub.c
rm mylib_stub.h

and then having installed ctypes, run the following python script (test_mylib.py) to test it:

   1 from ctypes import *
   2 
   3 lib = windll.mylib
   4 
   5 api = {
   6     
   7 #   func name     restype    argtypes
   8     'adder'     : (c_int,    [c_int, c_int]),
   9     'subtractor': (c_int,    [c_int, c_int]),
  10     'factorial' : (c_int,    [c_int]),
  11     'hello'     : (c_char_p, [c_char_p]),
  12     'mystring'  : (c_char_p, []),
  13 }
  14         
  15 
  16 for func in api:
  17     f = getattr(lib, func)
  18     f.restype, f.argtypes  = api[func]
  19     globals()[func] = f
  20     
  21 print adder(1,2)
  22 print subtractor(10,2)
  23 print factorial(10)
  24 print hello('hello')
  25 print mystring()

PythonVsHaskell (last edited 2012-03-08 05:01:08 by 5ac434a8)

Unable to edit the page? See the FrontPage for instructions.