[Haskell-cafe] OT: Paper on increasing entropy in software systems

2008-06-15 Thread Magnus Therning
This is wildly off topic, but since the Haskell community is a rather
academic one I thought there might be a good chance to find someone who
can point me in the right direction.

I was just listening to Brooks' talk at OOPSLA 2007 and in the QA part
at the end he mentions a paper on increasing entropy in software
systems.  He mentions the authors' names but I can't quite make it out
and Google hasn't been very helpful either.  He says the paper “must be
30 years old” and it sounds like he says it's by Les Bellati and Manny
Leimann (Lehmann?).  As I said, I can't quite make out the names, and
the names ring no bells for me.  Does anyone on the list know what paper
he's referring to?

/M

-- 
Magnus Therning (OpenPGP: 0xAB4DFBA4)
magnus@therning.org Jabber: magnus.therning@gmail.com
http://therning.org/magnus

What if I don't want to obey the laws? Do they throw me in jail with
the other bad monads?
 -- Daveman




signature.asc
Description: OpenPGP digital signature
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] ANN: Topkata

2008-06-15 Thread Christoph Bauer
Hi,

 There's a way to put something in the .cabal file about extra data files,
 and have it install them in a certain location that you can then find
 programmatically.  I forget the details, but I think it's pretty easy to set

 http://neilmitchell.blogspot.com/2008/02/adding-data-files-using-cabal.html

With this summary it was easy. I pushed an patch to
http://home.arcor.de/chr_bauer/topkata.

Christoph
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: working with Random.randoms

2008-06-15 Thread Robert Vollmert

Great reply!

One minor point: If real_programme is to be pure, you should use let:

On Jun 14, 2008, at 12:30, Jon Fairbairn wrote:

main :: IO()
  do gen - getStdGen
 the_list - real_programme gen

  let the_list = real_programme gen

 print the_list

You should be able to deduce from the fact that the first
argument of real_programme here is of type StdGen (not IO
anything) and its result type is [something] that
real_programme is pure, and gen has only one value
throughout.


Cheers
Robert

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: working with Random.randoms

2008-06-15 Thread Jon Fairbairn
Robert Vollmert [EMAIL PROTECTED] writes:

 Great reply!

Thanks.

 One minor point: If real_programme is to be pure, you should use let:

Whoops! I was thinking let but wrote the wrong thing. If
my email had been through a type-checker, it would have
spotted the mistake.

-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2008-04-26)

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] ANN: Topkata

2008-06-15 Thread Thomas Davie


On 15 Jun 2008, at 07:41, Deborah Goldsmith wrote:


On Jun 14, 2008, at 1:06 PM, Don Stewart wrote:

tom.davie:

In the mean time -- who knows enough to make ghc target ARM, and get
this to link against the iPhone libraries?  This would be quite a  
coup

if it could be made to run there!


I'd be interested. We should start a wiki page for Haskell on the
iphone..


It's an interesting idea, but I think it would need to be a cross- 
compiler. Does ghc support cross-compilation?


The most obvious place to start I guess would be using -fvia-C and the  
C cross compiler that apple supply.  I'll certainly be looking into  
this as soon as I get an iPhone (which unfortunately I need to wait  
for  3G one in Belgium).


Bob
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] OT: Paper on increasing entropy in software systems

2008-06-15 Thread Ketil Malde
Magnus Therning [EMAIL PROTECTED] writes:

 I was just listening to Brooks' talk at OOPSLA 2007 and in the QA part
 at the end he mentions a paper on increasing entropy in software
 systems.  He mentions the authors' names but I can't quite make it out
 and Google hasn't been very helpful either.  He says the paper “must be
 30 years old” and it sounds like he says it's by Les Bellati and Manny
 Leimann (Lehmann?).

Wikipedia's entry for Software entropy lists this:

  Lehman M.M. and Belady L. (1985). Program Evolution. Process of
  Software Change.

No link, though.

-k
-- 
If I haven't seen further, it is by standing in the footprints of giants
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] OT: Paper on increasing entropy in software systems

2008-06-15 Thread Matthew Brecknell
  I was just listening to Brooks' talk at OOPSLA 2007 and in the QA part
  at the end he mentions a paper on increasing entropy in software
  systems.  He mentions the authors' names but I can't quite make it out
  and Google hasn't been very helpful either.  He says the paper #8220;must 
  be
  30 years old#8221; and it sounds like he says it's by Les Bellati and Manny
  Leimann (Lehmann?).
 
 Wikipedia's entry for Software entropy lists this:
 
   Lehman M.M. and Belady L. (1985). Program Evolution. Process of
   Software Change.
 
 No link, though.

http://www.amazon.com/exec/obidos/ASIN/0124424406

Using the author names provided by Ketil, scholar.google.com also finds
this:

http://www.research.ibm.com/journal/sj/153/ibmsj1503E.pdf

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Documenting the impossible

2008-06-15 Thread Richard Kelsall

Andrew Coppin wrote:
Obviously there is no way in hell this code path can ever be executed. 


Ah, the number of times I've thought that and been wrong :)

From a simplistic perspective what I think you're asking for is
to have obscure occasions when your program goes wrong with random
consequences and doesn't give you an error message. This a programmer's
worst nightmare. I can think of several dimensions of bug difficulty

When the bug exhibits:
  Hard   : Infrequent at run-time.
  Medium : Frequent at run-time.
  Easy   : Compile-time.

Reproducible:
  Hard   : No obvious pattern or way to induce the error.
  Medium : A reasonably strong correlation with some precursor.
  Easy   : Happens every time you do a particular thing.

Error message:
  Hard   : No error message.
  Medium : Non-specific error message.
  Easy   : Error message that relates to an identifiable
   point in your program with relevant state information.

Error message location:
  Medium : Appears on the screen.
  Easy   : Shown on screen and recorded in a log file.

Where it happens:
  Hard   : Only on your user's machine or with their configuration.
  Easy   : On all machines.


By classifying error messages, for bugs which you have stated are
infrequent and difficult to reproduce, as not needing to be displayed
or logged you have pushed all these bugs into the seriously hard
category. By adding 'undefined' subsequent behaviour you have made
these bugs even more difficult. What we should be doing is pushing
every bug in the opposite direction - towards the easy end of all
the above dimensions.


Richard.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] (no subject)

2008-06-15 Thread Adrian Neumann

{- I downloaded the source and put my file in the same directory
   You may need to adjust the imports -}
module Main where
import Picture
import Draw -- change xWin to 1000 and yWin to 700 for this to work
import EnableGUI -- I use a Mac
import SOE hiding (Region)
import qualified SOE as G (Region)
import Data.List
import Random

-- lines are not Shapes unfortunately
linie = ((Shape $ Polygon [(-0.1,-0.01),(-0.1,0.01),(0.1,0.01), 
(0.1,-0.01)]), (-0.1,0), (0.1,0))


main = enableGUI  do
w - openWindow Lindenmayer System (xWin, yWin)
newStdGen
g - getStdGen
drawPic w (aufgabe2 g)
k - getKey w
if (k=='q') then do
closeWindow w
return () else do
clearWindow w
main

-- one big ugly line of code, not that interesting though
aufgabe2 g= dasBild where
r = rotateRegion (pi/2) $ Translate (-2.5,0) $ renderLSystem  
linie (lSystem 20 g)
dasBild = Region White r `Over` Region Black ( Translate  
(0,-1.8) $ Scale (1,0.3)$ Translate (0,-2.6) $ rotateRegion (pi/2+pi/ 
3) $ Translate (0,2.6) $ r) `Over` Region Green (Shape $ Polygon  
[(-5,-3.5),(-5,-1.5),(5,-1.5),(5,-3.5)]) `Over` Region Yellow  
(Translate (4,1.5) (Shape $ circle (0.5))) `Over`

Region Blue (Shape $ Rectangle 14 7)

-- start of the interesting part:
-- A - Axiom, the base shape we use for rendering later
--F - Forward
--Branch - what it says

data LSys = A LSys | F LSys | Branch StdGen [LSys] LSys | Done  
deriving Show


-- a Axiom is a region with two connector points
type Axiom = (Region, Vertex, Vertex)

-- this seems not to be used anymore?

scaleAxiom :: Float - Axiom - Axiom
scaleAxiom f (r,u,v) = (Scale (f,f) r, f .*. u, f .*. v)

-- just for testing purposes
testLSys = A (Branch (mkStdGen 5) [A (F ((Branch (mkStdGen 5) [A  
(Branch (mkStdGen 5) [A (F ((Branch (mkStdGen 5) [A (F Done), A (F  
Done)] Done))), A (F Done)] Done), A (F Done)] Done))), A (F Done)]  
Done)


-- a 2D rotation matrix
drehM :: Float - (Float, Float, Float, Float)
drehM w = (cos w, -sin w, sin w, cos w)

-- matrix vector multiplication
(.**.) :: (Float, Float, Float, Float) - Vertex - Vertex
(.**.) (a,b,c,d) (px,py) = (a*px+b*py, c* px+d*py)

-- other vector stuff
(.-.) (a,b) (c,d) = (a-c,b-d)
(.+.) (a,b) (c,d) = (a+c,b+d)
(.*.) l (c,d) = (c*l,d*l)
abs' (a,b) = (abs a, abs b)
betr (a,b) = sqrt (a*a+b*b)

-- SOE doesn't come with a way to rotate Regions, so I wrote my own
rotateRegion :: Float - Region - Region
rotateRegion f (Shape s) = Shape (rotateS f s)
rotateRegion f (Translate v r) = Translate ((drehM f).**.v)  
(rotateRegion f r)


-- the scaling part is not right I think. Everything seems to break  
if I try to incorporate scaling

-- into the rendering

rotateRegion f (Scale v r) = Scale ((betr v/ betr nv) .*. nv)  
(rotateRegion f r) where

x = ((drehM f).**. (fst v,0))
y = ((drehM f) .**. (0,snd v))
nv = (abs' x) .+. (abs' y)
rotateRegion f (Complement r) =Complement (rotateRegion f r)
rotateRegion f (Union r1 r2) = Union (rotateRegion f r1)  
(rotateRegion f r2)
rotateRegion f (Intersect r1 r2) = Intersect (rotateRegion f r1)  
(rotateRegion f r2)

rotateRegion f (Xor r1 r2) = Xor (rotateRegion f r1) (rotateRegion f r2)
rotateRegion _ s=s

rotateS f (Polygon pts) = Polygon (map ((drehM f) .**.) pts)
rotateS f x = x

-- nondeterministically generate a word in our LSys language
-- lots of copypaste here, any way to do this better?

lSystem :: Int - StdGen - LSys
lSystem n g = f n g (A undefined) where
f :: Int - StdGen - LSys - LSys
f 0 _ _ = Done
f (n+1) g (A _)
| choose = 1 = A (f n ng (F undefined))
| choose == 0 = A (f n ng (Branch ng [f n ng' (A undefined),  
f n ng'' (A undefined)] undefined)) where

(choose, ng) = randomR (0::Int,3::Int) g
(ng', ng'') = split ng
f (n+1) g (F _)
| choose = 1 = F (f n ng (F undefined))
| choose == 0 = F (f n ng (Branch ng [f n ng' (A undefined),  
f n ng'' (A undefined)] undefined)) where

(choose, ng) = randomR (0::Int,3::Int) g
(ng', ng'') = split ng
f (n+1) g (Branch h lSys _)
| choose = 1 = Branch h lSys  (f n ng (F undefined))
| choose == 0 = Branch h lSys (f n ng (Branch ng [f n ng' (A  
undefined), f n ng'' (A undefined)] undefined)) where

(choose, ng) = randomR (0::Int,5::Int) g
(ng', ng'') = split ng

-- recursivly render a LSys
renderLSystem :: Axiom - LSys - Region
renderLSystem _ Done = Empty
renderLSystem (r,u,v) (A lSys) = r `Union` renderLSystem (r,u,v) lSys
renderLSystem (r,u,v) (F lSys) = r'' `Union` renderLSystem (r'', u . 
+. o , v .+.o) lSys where

r'' =  Translate o   $  r
o = (v .-. u)
renderLSystem (r,u,v) (Branch g lSys rest) =
theBranches `Union` renderLSystem (r,u,v) rest where
theBranches = Translate o $ foldr Union Empty $
-- we need to rotate around the u-Connector, not around (0,0)
-- thus translation
map 

Re: [Haskell-cafe] Lindenmayer Systems, WAS: (no subject)

2008-06-15 Thread Adrian Neumann

I screwed up the email, sorry about that. What I wanted to say was:

Hello,

as homework I was assigned to design and draw an image using the  
SOE Graphics library [1]. In order to impress my classmates I decided  
to draw a bush-like thingy using a Lindenmayer-System. It turns out  
quite nice [2], and so I thought I might share my code with you. Of  
course criticism is very welcome.


Ok, here we go:



{- I downloaded the source and put my file in the same directory
   You may need to adjust the imports -}
module Main where
import Picture
import Draw -- change xWin to 1000 and yWin to 700 for this to work
import EnableGUI -- I use a Mac
import SOE hiding (Region)
import qualified SOE as G (Region)
import Data.List
import Random

-- lines are not Shapes unfortunately
linie = ((Shape $ Polygon [(-0.1,-0.01),(-0.1,0.01),(0.1,0.01), 
(0.1,-0.01)]), (-0.1,0), (0.1,0))


main = enableGUI  do
w - openWindow Lindenmayer System (xWin, yWin)
newStdGen
g - getStdGen
drawPic w (aufgabe2 g)
k - getKey w
if (k=='q') then do
closeWindow w
return () else do
clearWindow w
main

-- one big ugly line of code, not that interesting though
aufgabe2 g= dasBild where
r = rotateRegion (pi/2) $ Translate (-2.5,0) $ renderLSystem  
linie (lSystem 20 g)
dasBild = Region White r `Over` Region Black ( Translate  
(0,-1.8) $ Scale (1,0.3)$ Translate (0,-2.6) $ rotateRegion (pi/2 
+pi/3) $ Translate (0,2.6) $ r) `Over` Region Green (Shape $  
Polygon [(-5,-3.5),(-5,-1.5),(5,-1.5),(5,-3.5)]) `Over` Region  
Yellow (Translate (4,1.5) (Shape $ circle (0.5))) `Over`

Region Blue (Shape $ Rectangle 14 7)

-- start of the interesting part:
-- A - Axiom, the base shape we use for rendering later
--F - Forward
--Branch - what it says

data LSys = A LSys | F LSys | Branch StdGen [LSys] LSys | Done  
deriving Show


-- a Axiom is a region with two connector points
type Axiom = (Region, Vertex, Vertex)

-- this seems not to be used anymore?

scaleAxiom :: Float - Axiom - Axiom
scaleAxiom f (r,u,v) = (Scale (f,f) r, f .*. u, f .*. v)

-- just for testing purposes
testLSys = A (Branch (mkStdGen 5) [A (F ((Branch (mkStdGen 5) [A  
(Branch (mkStdGen 5) [A (F ((Branch (mkStdGen 5) [A (F Done), A (F  
Done)] Done))), A (F Done)] Done), A (F Done)] Done))), A (F Done)]  
Done)


-- a 2D rotation matrix
drehM :: Float - (Float, Float, Float, Float)
drehM w = (cos w, -sin w, sin w, cos w)

-- matrix vector multiplication
(.**.) :: (Float, Float, Float, Float) - Vertex - Vertex
(.**.) (a,b,c,d) (px,py) = (a*px+b*py, c* px+d*py)

-- other vector stuff
(.-.) (a,b) (c,d) = (a-c,b-d)
(.+.) (a,b) (c,d) = (a+c,b+d)
(.*.) l (c,d) = (c*l,d*l)
abs' (a,b) = (abs a, abs b)
betr (a,b) = sqrt (a*a+b*b)

-- SOE doesn't come with a way to rotate Regions, so I wrote my own
rotateRegion :: Float - Region - Region
rotateRegion f (Shape s) = Shape (rotateS f s)
rotateRegion f (Translate v r) = Translate ((drehM f).**.v)  
(rotateRegion f r)


-- the scaling part is not right I think. Everything seems to break  
if I try to incorporate scaling

-- into the rendering

rotateRegion f (Scale v r) = Scale ((betr v/ betr nv) .*. nv)  
(rotateRegion f r) where

x = ((drehM f).**. (fst v,0))
y = ((drehM f) .**. (0,snd v))
nv = (abs' x) .+. (abs' y)
rotateRegion f (Complement r) =Complement (rotateRegion f r)
rotateRegion f (Union r1 r2) = Union (rotateRegion f r1)  
(rotateRegion f r2)
rotateRegion f (Intersect r1 r2) = Intersect (rotateRegion f r1)  
(rotateRegion f r2)
rotateRegion f (Xor r1 r2) = Xor (rotateRegion f r1) (rotateRegion  
f r2)

rotateRegion _ s=s

rotateS f (Polygon pts) = Polygon (map ((drehM f) .**.) pts)
rotateS f x = x

-- nondeterministically generate a word in our LSys language
-- lots of copypaste here, any way to do this better?

lSystem :: Int - StdGen - LSys
lSystem n g = f n g (A undefined) where
f :: Int - StdGen - LSys - LSys
f 0 _ _ = Done
f (n+1) g (A _)
| choose = 1 = A (f n ng (F undefined))
| choose == 0 = A (f n ng (Branch ng [f n ng' (A  
undefined), f n ng'' (A undefined)] undefined)) where

(choose, ng) = randomR (0::Int,3::Int) g
(ng', ng'') = split ng
f (n+1) g (F _)
| choose = 1 = F (f n ng (F undefined))
| choose == 0 = F (f n ng (Branch ng [f n ng' (A  
undefined), f n ng'' (A undefined)] undefined)) where

(choose, ng) = randomR (0::Int,3::Int) g
(ng', ng'') = split ng
f (n+1) g (Branch h lSys _)
| choose = 1 = Branch h lSys  (f n ng (F undefined))
| choose == 0 = Branch h lSys (f n ng (Branch ng [f n  
ng' (A undefined), f n ng'' (A undefined)] undefined)) where

(choose, ng) = randomR (0::Int,5::Int) g
(ng', ng'') = split ng

-- recursivly render a LSys
renderLSystem :: Axiom - LSys - Region
renderLSystem _ Done = Empty
renderLSystem (r,u,v) (A lSys) = r `Union` renderLSystem (r,u,v) lSys

Re: [Haskell-cafe] Lindenmayer Systems, WAS: (no subject)

2008-06-15 Thread Gwern Branwen
On 2008.06.15 16:50:28 +0200, Adrian Neumann [EMAIL PROTECTED] scribbled 6.9K 
characters:
 I screwed up the email, sorry about that. What I wanted to say was:

 Hello,

 as homework I was assigned to design and draw an image using the SOE
 Graphics library [1]. In order to impress my classmates I decided to draw
 a bush-like thingy using a Lindenmayer-System. It turns out quite nice
 [2], and so I thought I might share my code with you. Of course criticism
 is very welcome.

 Ok, here we go:

 {- I downloaded the source and put my file in the same directory
You may need to adjust the imports -}
 module Main where
 import Picture
 import Draw -- change xWin to 1000 and yWin to 700 for this to work
 import EnableGUI -- I use a Mac
 import SOE hiding (Region)
 import qualified SOE as G (Region)
 import Data.List
 import Random

 -- lines are not Shapes unfortunately
 linie = ((Shape $ Polygon [(-0.1,-0.01),(-0.1,0.01),(0.1,0.01),
 (0.1,-0.01)]), (-0.1,0), (0.1,0))

 main = enableGUI  do
 w - openWindow Lindenmayer System (xWin, yWin)
 newStdGen
 g - getStdGen
 drawPic w (aufgabe2 g)
 k - getKey w
 if (k=='q') then do
 closeWindow w
 return () else do
 clearWindow w
 main

 -- one big ugly line of code, not that interesting though
 aufgabe2 g= dasBild where
 r = rotateRegion (pi/2) $ Translate (-2.5,0) $ renderLSystem linie
 (lSystem 20 g)
 dasBild = Region White r `Over` Region Black ( Translate (0,-1.8) $
 Scale (1,0.3)$ Translate (0,-2.6) $ rotateRegion (pi/2+pi/3) $
 Translate (0,2.6) $ r) `Over` Region Green (Shape $ Polygon
 [(-5,-3.5),(-5,-1.5),(5,-1.5),(5,-3.5)]) `Over` Region Yellow
 (Translate (4,1.5) (Shape $ circle (0.5))) `Over`
 Region Blue (Shape $ Rectangle 14 7)

 -- start of the interesting part:
 -- A - Axiom, the base shape we use for rendering later
 --F - Forward
 --Branch - what it says

 data LSys = A LSys | F LSys | Branch StdGen [LSys] LSys | Done
 deriving Show

 -- a Axiom is a region with two connector points
 type Axiom = (Region, Vertex, Vertex)

 -- this seems not to be used anymore?

 scaleAxiom :: Float - Axiom - Axiom
 scaleAxiom f (r,u,v) = (Scale (f,f) r, f .*. u, f .*. v)

 -- just for testing purposes
 testLSys = A (Branch (mkStdGen 5) [A (F ((Branch (mkStdGen 5) [A
 (Branch (mkStdGen 5) [A (F ((Branch (mkStdGen 5) [A (F Done), A (F
 Done)] Done))), A (F Done)] Done), A (F Done)] Done))), A (F Done)]
 Done)

 -- a 2D rotation matrix
 drehM :: Float - (Float, Float, Float, Float)
 drehM w = (cos w, -sin w, sin w, cos w)

 -- matrix vector multiplication
 (.**.) :: (Float, Float, Float, Float) - Vertex - Vertex
 (.**.) (a,b,c,d) (px,py) = (a*px+b*py, c* px+d*py)

 -- other vector stuff
 (.-.) (a,b) (c,d) = (a-c,b-d)
 (.+.) (a,b) (c,d) = (a+c,b+d)
 (.*.) l (c,d) = (c*l,d*l)
 abs' (a,b) = (abs a, abs b)
 betr (a,b) = sqrt (a*a+b*b)

 -- SOE doesn't come with a way to rotate Regions, so I wrote my own
 rotateRegion :: Float - Region - Region
 rotateRegion f (Shape s) = Shape (rotateS f s)
 rotateRegion f (Translate v r) = Translate ((drehM f).**.v)
 (rotateRegion f r)

 -- the scaling part is not right I think. Everything seems to break if
 I try to incorporate scaling
 -- into the rendering

 rotateRegion f (Scale v r) = Scale ((betr v/ betr nv) .*. nv)
 (rotateRegion f r) where
 x = ((drehM f).**. (fst v,0))
 y = ((drehM f) .**. (0,snd v))
 nv = (abs' x) .+. (abs' y)
 rotateRegion f (Complement r) =Complement (rotateRegion f r)
 rotateRegion f (Union r1 r2) = Union (rotateRegion f r1) (rotateRegion
 f r2)
 rotateRegion f (Intersect r1 r2) = Intersect (rotateRegion f r1)
 (rotateRegion f r2)
 rotateRegion f (Xor r1 r2) = Xor (rotateRegion f r1) (rotateRegion f
 r2)
 rotateRegion _ s=s

 rotateS f (Polygon pts) = Polygon (map ((drehM f) .**.) pts)
 rotateS f x = x

 -- nondeterministically generate a word in our LSys language
 -- lots of copypaste here, any way to do this better?

 lSystem :: Int - StdGen - LSys
 lSystem n g = f n g (A undefined) where
 f :: Int - StdGen - LSys - LSys
 f 0 _ _ = Done
 f (n+1) g (A _)
 | choose = 1 = A (f n ng (F undefined))
 | choose == 0 = A (f n ng (Branch ng [f n ng' (A undefined), f
 n ng'' (A undefined)] undefined)) where
 (choose, ng) = randomR (0::Int,3::Int) g
 (ng', ng'') = split ng
 f (n+1) g (F _)
 | choose = 1 = F (f n ng (F undefined))
 | choose == 0 = F (f n ng (Branch ng [f n ng' (A undefined), f
 n ng'' (A undefined)] undefined)) where
 (choose, ng) = randomR (0::Int,3::Int) g
 (ng', ng'') = split ng
 f (n+1) g (Branch h lSys _)
 | choose = 1 = Branch h lSys  (f n ng (F undefined))
 | choose == 0 = Branch h lSys (f n ng (Branch ng [f n ng' (A
 undefined), f n ng'' (A undefined)] undefined)) where
 (choose, ng) = randomR (0::Int,5::Int) g
 (ng', ng'') = split ng

 -- recursivly render a LSys

Re: [Haskell-cafe] Documenting the impossible

2008-06-15 Thread Andrew Coppin

Henning Thielemann wrote:
I think it is another instance of mixing up errors and exceptions (you 
know the haskellwiki pages ...)


Since an 'error' marks a programming error (which should never occur) 
it would not hurt the program if all 'error's are replaced by 
'undefined', an illegal memory access or any other misbehaviour. So 
'error' is exactly what you propose as IMPOSSIBLE pragma. A compiler 
option for replacing all 'error's by nops would do want you want.


OK, so suppose I write a module that contains a function that accepts a 
number parameter, and that parameter must be greater than 2. I have no 
control over what value users of the library pass to my function. 
Suppose some client calls my function with 1 as an argument - is that an 
error, or an exception?


On the other hand, suppose I write the same function, but now it's not 
exported. So the only code that can possibly call this function is my 
own code. So I can [theoretically] guarantee it will never be called 
with the wrong argument [assuming the code I write isn't defective].


As far as I can tell, there's no way of making this distinction in 
Haskell code. You'd use error in both cases - or if you're feeling 
brave, remove it in the second case and hope you're right. I'm just 
saying it would be nice to be able to keep it in the code for 
maintainability's sake, but not have the runtime penalty for it once 
you're sure your code is safe.


It looks like Don's assert thing might be able to do this. [I had no 
idea this existed by the way...]


Hmm, this gives me a new idea for a feature request - how about a 
function that evaluates to the source code line number it was called 
from? ;-)


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Documenting the impossible

2008-06-15 Thread Henning Thielemann


On Sun, 15 Jun 2008, Andrew Coppin wrote:


Henning Thielemann wrote:
I think it is another instance of mixing up errors and exceptions (you know 
the haskellwiki pages ...)


Since an 'error' marks a programming error (which should never occur) it 
would not hurt the program if all 'error's are replaced by 'undefined', an 
illegal memory access or any other misbehaviour. So 'error' is exactly what 
you propose as IMPOSSIBLE pragma. A compiler option for replacing all 
'error's by nops would do want you want.


OK, so suppose I write a module that contains a function that accepts a 
number parameter, and that parameter must be greater than 2. I have no 
control over what value users of the library pass to my function. Suppose 
some client calls my function with 1 as an argument - is that an error, or an 
exception?


It's an error, like 'head []' is an error. You must document the condition 
(argument  2), unfortunately Haskell's type system does not allow to 
state such conditiions conveniently, and then it's the caller's 
responsibility to ensure that the argument is greater than 2.
 I like to distinguish between two kinds of users. (Are there common names 
for them?) The (consumer) user communicates with your program via an 
interface you provide: A GUI, the command line, a network. The user may 
even not know, that the program is written in Haskell. Everything this 
user makes wrong is an exception. You cannot forbid the user to make 
something wrong. The other kind of users are programmers, who call 
functions of your library. This interface is especially fast but in order 
to get the efficiency you can expect some cooperation by the programmer. 
E.g. the programmer of your library must ensure that the argument is 
always greater than 2. Otherwise _he_ has done an _error_.
 However if he writes a program which lets the user enter the number in a 
GUI dialog which is then passed to your library, then he must check the 
number before forwarding it, because the user can do wrong things. If the 
user enters '1' this is an _exception_. If the programmer does not reject 
this input it is an error.


On the other hand, suppose I write the same function, but now it's not 
exported. So the only code that can possibly call this function is my own 
code. So I can [theoretically] guarantee it will never be called with the 
wrong argument [assuming the code I write isn't defective].


As far as I can tell, there's no way of making this distinction in Haskell 
code. You'd use error in both cases - or if you're feeling brave, remove it 
in the second case and hope you're right. I'm just saying it would be nice to 
be able to keep it in the code for maintainability's sake, but not have the 
runtime penalty for it once you're sure your code is safe.


In theory you could remove 'error' in both cases, because in theory 
neither you nor the library user makes mistakes. In practice you better 
leave the error, because both of you actually make mistakes.


It looks like Don's assert thing might be able to do this. [I had no idea 
this existed by the way...]


As far as I understand, 'assert' is a wrapper to 'error' which also 
determines the source code location without using the C preprocessor. Is 
this correct?


Hmm, this gives me a new idea for a feature request - how about a function 
that evaluates to the source code line number it was called from? ;-)


Would be also nice for a single stepper, which shows at which places in 
the source code things are currently evaluated.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Design your modules for qualified import

2008-06-15 Thread Henning Thielemann


On Sat, 14 Jun 2008, Isaac Dupree wrote:

yeah, we could come up with a syntax. one that gives privileged meaning to 
hierarchy.  If used according to design your modules for qualified import, 
it would still allow fairly easy use and looking up function uses.


import Graphics.UI.GTK (import qualified Button, import qualified Window)

then you get Button.f (because Graphics.UI.GTK wasn't imported qualified), 
Graphics.UI.GTK.Button.f, (not f or Graphics.UI.GTK.f because of qualified 
Button)  ... they're normal import statements inside.  What it saves is the 
duplication of Graphics.UI.GTK and Button as Button.  Not sure I like 
how long import qualified is, repeated there, but it seemed much less 
confusing than anything shorter.


import Data (import qualified Map, Map.Map)
or
import Data (import qualified Map, import Map(Map))
or a shortcut for that common pattern of importing a few things unqualified
import Data (import qualified Map and (Map))
aka. import qualified Data.Map as Map and (Map)
aka. import qualified Data.Map as Map (empty,singleton,...) and (Map)
or perhaps unqualifying rather than and

personally I would like it if we could also import (f as g) if we wanted to 
rename an f we were importing, to g in the module and re-exports, without 
having to be concerned about (for lowercase) monomorphism restriction, (for 
types) whether a synonym will work properly everywhere (not without 
extensions!), (for constructor, record fields, and classes) simple 
*impossibility*.  That wish is only related in that it's a related 
generalization, though.


nice
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] cabal-install failure

2008-06-15 Thread Duncan Coutts

On Sat, 2008-06-14 at 11:03 +0100, Claus Reinke wrote:
  http://hackage.haskell.org/trac/hackage/ticket/227
  
 One problem is that not all build-tools correspond to haskell
 packages. Some do some don't. We have a hard coded list of them
 at the moment (which can be extended in Setup.hs files) so we
 could extend that with what haskell package if any the tools
 correspond to. Any better suggestions to make it a tad more
 generic?
 
 That list seems to be in Distribution/Simple/Program.hs, in case 
 anyone else is looking for it. Encoded information includes: 
 dependency name, program name (if different from dependency),

Right, we have the common name of the program. We don't actually track
the actual name as it happens to be on any particular system except in
so far as we try to find the full path to the program when we configure
it.

The main point of the Program abstraction is about configuring and
running programs. As it happens some programs are provided by some
haskell packages (but not all, eg ld, ar, etc).

 option to get version info and code to extract it (with one apparently
 very special case being hsc2hs).

And ld.exe on windows (we find it in ghc's gcc-lib bin dir).

 Btw, most of the version extraction code looks like a regular 
 expression match - wouldn't that make the specification easier
 (and turn the comments into part of the spec)?

True, in most cases finding the name of the program involves running it
with some --version flag and matching some part of the output. However
that's not always the case. Some programs do silly things like produce
the version output on stderr instead of stdout. We figured the most
general thing was just a function

FilePath - IO (Maybe Version)

which is what we've got. I'm not sure what the advantage would be to
make it more declarative by making it into data rather than a extraction
function.

Also, the Cabal lib cannot depend on any regular expression library
because they are not part of the bootstrapping library set.

  If anyone has a godd suggestion I'm happy to hear it. Otherwise we can
  just add a Maybe Dependency to the Program type to indicate that some
  build tools have a corresponding haskell package.
 
 I'm not sure what you're suggesting there (currently even those
 tools that can be built with Cabal do not register with Cabal), but 
 here are my suggestions:

 1. Haskell tools should register with Cabal, whether built with it
 (such as Alex, Happy, ..) or not (such as GHC, ..). That 
 registration should include any build-relevant information
 (versions/variants, ..).
 
 2. When checking a build-tools dependency, Cabal checks
 (a) whether the tool is registered with Cabal

I'm not sure this helps. We want to know what to install when it's
missing. We can already tell if a program (not package) is available by
searching for it.

 (b) whether the tool is registered with the system installation manager

This is hard.

 (c) whether the tool can be found by other means (configure,
 built-in rules, ..)
 
 In other words, make tools look like packages (lifetime dependency
 management, not just build support), and make system packages look 
 like Cabal packages (Cabal as the interface to native managers), using 
 special treatment only if absolutely necessary. I thought those suggestions
 were clear from my earlier messages?-)

Sure, haskell executable tools built by haskell packages are really
packages.

So the problem currently is that build-tools refers to programs not
packages. One can list any known program in the build-tools field and
the list of programs is extensible in the Setup.hs script.

As they are used so far by current packages on hackage, they always
refer to haskell tools built by haskell packages (almost only used to
refer to alex, happy and c2hs) so perhaps we should just quietly
redefine the meaning on build-tools to be another kind of build-depends.
That is it specifies a haskell package.

If we have need to specify non-haskell build tools, perhaps we should do
that separately? eg some-other-kind-of-build-tools: perl = 5.8

Duncan

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Documenting the impossible

2008-06-15 Thread Achim Schneider
Andrew Coppin [EMAIL PROTECTED] wrote:

 I have a small idea. I'm curios if anybody else thinks it's a good
 idea...
 
 How about a {-# IMPOSSIBLE #-} pragma that documents the fact that a 
 particular point in the program *should* be unreachable?
 
I might support this in some way or the other _after_ we've got errors
that report source file and line number. Before that I will stay,
steadfast and stubborn, utterly ignorant of anything with less
importance.

Just use

assert s v = if debug then error s else v

in the mean time. -DHAVE_CONFIG_H ;)

-- 
(c) this sig last receiving data processing entity. Inspect headers for
past copyright information. All rights reserved. Unauthorised copying,
hiring, renting, public performance and/or broadcasting of this
signature prohibited. 

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Design your modules for qualified import

2008-06-15 Thread Duncan Coutts

On Sat, 2008-06-14 at 19:21 +0100, Sebastian Sylvan wrote:

 I think that if GTK did use this system (rather than append the module
 name to the function and export them flatly) a lot of people would
 resort to ugly hacks like putting the import statements in a file
 somewhere and using the C preprocessor to include it, yuck! (OTOH this
 may be just what's required to convince everyone that we need to
 improve the module system)...

Right. That's exactly why we've not done something like that. With 100+
modules in the Gtk package it's totally infeasible to do qualified
imports of them all.

If we get a proper way to export a non-flat namespace then Gtk2Hs will
certainly switch to using it. Using 'buttonBlah' is horrible but there
is currently nothing better.

There have been a few suggestions along these lines. Check the archives.
I'm not sure what is proposed for haskell', probably nothing since
nothing is currently implemented and we're only supposed to be
standardising existing practise.

Duncan

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Lazy IO.

2008-06-15 Thread Duncan Coutts

On Sat, 2008-06-14 at 18:18 +0200, Sebastiaan Visser wrote:
 Hi,
 
 I've got a question about lazy IO in Haskell. The most well known
 function to do lazy IO is the `hGetContents', which lazily reads all the
 contents from a handle and returns this as a regular [Char].
 
 The thing with hGetContents is that is puts the Handle in a semi-closed
 state, no one can use the handle anymore. This behaviour is
 understandable from the point of safety; it is not yet determined when
 the result of hGetContents will actually be computed, using the handle
 in the meantime is undesirable.
 
 The point is, I think I really have a situation in which I want to use
 the handle again `after' a call to hGetContents. I think I can best
 explain this using a code example.
 
readHttpMessage :: IO (Headers, Data.ByteString.Lazy.ByteString)
readHttpMessage = do
  myStream - accept http connection from client
  request - hGetContents myStream
  header - parseHttpHeader request
  bs - Data.ByteString.Lazy.hGetContents myStream
  return (header, body)

Can you get the contents as a bytestring, then unpack that to a String
for the purpose of parsing a prefix of the input as the headers. Since
unpacking to a String is lazy it means you should only end up using
String for the headers and not for the payload.

As others have pointed out it's not clear from the above how you
separate the headers and the body. Returning the length of the headers
might work and then drop that amount from the bytestring would give the
body as a bytestring.

Duncan

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] External query interface to HackageDB?

2008-06-15 Thread Duncan Coutts

On Sat, 2008-06-14 at 10:26 -0400, Dimitry Golubovsky wrote:
 Hi,
 
 Is there any way to query the latest version of a particular package
 stored on Hackage, that was successfully built?

It is certainly part of the plan. There is currently no convenient way
to get at the information. I've been working on the client side of
things, actually generating decent build reports. That step is now done
and it's included in cabal-install-0.5.0. The next step is letting
people upload build reports to hackage and collating the data and
extracting useful information from the data. Included in that would be
some way for external clients to get at the data and summaries both via
human readable info on the package page and something machine readable.

 I mean, not _how_ to do that (I have some ideas that I have to
 download directory listings, looking for failure logs, etc.), but is
 there any tool or interface already available that does similar
 things?

In the mean time, using the current system, you can get at stuff by
knowing what urls to look at. eg:

http://hackage.haskell.org/packages/archive/pureMD5/0.2.0/logs/failure/ghc-6.8

So most recent packages have a logs subdir and either a success or
failure dir with a log file for a particular version of ghc, which at
the moment is 6.6 or 6.8.

 Unfortunately, tarfiles provided on Hackage (like 00-index.tar.gz) do
 not help, e. g. BerkeleyDB failed to build in all three versions, yet
 its all cabal files are included in the tarball:

Yes, the archive is complete. We do not remove anything. In future we
may augment the index with extra meta-data on what works, what is
obsolete or what is recommended.


Duncan

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Memory profiling

2008-06-15 Thread Pieter Laeremans
Hi,

Which tools do you recommand for memory profiling   haskell programs
on a *nix system.
I'm using haskell to develop a CGI program/script.

The application has to be deployed on shared hosting infrastructure.
Since I would like to be a good citizen ,
I would need to meassure the maximum amount of memory allocated to the
program during execution.
The best I can do now is look at top but that 's not satisfactory.

thanks,

Pieter



-- 
Pieter Laeremans [EMAIL PROTECTED]
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Documenting the impossible

2008-06-15 Thread Evan Laforge
 Hmm, this gives me a new idea for a feature request - how about a function
 that evaluates to the source code line number it was called from? ;-)

Well, that wouldn't be a function, but one of the other -hcs (j? n?)
has srcloc_annotate which is a macro that does that.  It would be nice
if ghc had it.  Meanwhile, I use -pgmF to replace certain functions
with *_srcloc ones that pass a SrcLoc argument, and it works mostly
ok.  I don't know what other people do, but having file:line in logs
and test failures is pretty handy.

Only mostly because it replaces things in strings, because I can't
use cpp because it doesn't understand dots in identifiers, and can't
use Language.Haskell.Parser because it *also* doesn't understand dots
in identifiers, so it's Regex.subRegex (speaking of not being designed
for qualified import...) until I get around to doing it with parsec.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] How to do this in FP way?

2008-06-15 Thread Magicloud Magiclouds
Hello,
I am getting familiar with FP now, and I have a program design kind of
question.
Say I have something like this in C:
static int old;
int diff (int now) { /* this would be called once a second */
  int ret = now - old;
  old = now;
  return ret;
}
Because there is no variable in Haskell. So how to do this in a FP
way?

Thanks.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] How to do this in FP way?

2008-06-15 Thread Thomas M. DuBuisson
Magicloud Magiclouds wrote:
 Say I have something like this in C:
 static int old;
 int diff (int now) { /* this would be called once a second */
   int ret = now - old;
   old = now;
   return ret;
 }
 Because there is no variable in Haskell. So how to do this in a
 FP way?

So you have a global time count that is updated every second - I presume
for the rest of the process to use, avoiding syscalls due to expense.
Am I getting this right?

You can use mutable variables in Haskell, though some people will frown,
but it might fit your need.  See MVar, STM, or IO Refs.  At any rate, if
what you are doing needs to check the clock time then this code isn't
going to be pure.

Perhaps you just want something in particular to be triggered every
second then use control-timeout, event-list, or control-event.

Tom


signature.asc
Description: This is a digitally signed message part
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] How to do this in FP way?

2008-06-15 Thread sam lee
I can think of 2 ways.

 module Main where

 import Control.Monad.State

First, normal way:

 diff (now, old) = (now - old, now)

diff takes now and old and returns result (now - old) and modified old (now).
For example,
diff (diff (1,0))
== diff (1 - 0, 1)
== diff (1, 1)
== (1 - 1, 1)
== (0, 1)

I think people use the word threaded to describe what diff is doing:
the variable old is threaded through many calls to diff.

 testDiff = diff . diff . diff . diff . diff . diff $ (2, 1)

testDiff returns (2,1)

Second way is using monads:

 diff' now = do
 old - get
 put now
 return (now - old)


diff' uses State monad.
If you're not familiar with monads, State monad does similar to what
diff function does (it threads the variable old).
But, being a monadic action, diff' looks like imperative version
syntactically. It gives illusion of having global variable (old).


 testDiff' = do
 result - diff' 2
 result - diff' result
 result - diff' result
 result - diff' result
 result - diff' result
 result - diff' result
 return result

 runTestDiff' = runState testDiff' 1

runTestDiff' also returns (2,1)

2008/6/15 Magicloud Magiclouds [EMAIL PROTECTED]:
 Hello,
 I am getting familiar with FP now, and I have a program design kind of
 question.
 Say I have something like this in C:
 static int old;
 int diff (int now) { /* this would be called once a second */
   int ret = now - old;
   old = now;
   return ret;
 }
 Because there is no variable in Haskell. So how to do this in a FP
 way?

 Thanks.

 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: How to do this in FP way?

2008-06-15 Thread Achim Schneider
Magicloud Magiclouds [EMAIL PROTECTED] wrote:

 static int old;
 int diff (int now) { /* this would be called once a second */
   int ret = now - old;
   old = now;
   return ret;
 }

You do it with variables, of course. This is out of some GLUT code,
using IORef's:

idle :: State - IdleCallback
idle state = do
t0 - get $ t state
t1 - get elapsedTime
t state $= t1
let td = fromIntegral t1 - fromIntegral t0
fps state $= 1/td * 1000

angle' state $~! (+2)

(bpx, bpy) - get $ ballPos state
(bvx, bvy) - get $ ballVel state

ballPos state $= (bpx + bvx*td, bpy + bvy*td)   
postRedisplay Nothing

One half of all Haskell coders will tell you that mutable state isn't a
good starting point to learn Haskell, the other half will tell you the
same because they want to be cool kids, too. 

-- 
(c) this sig last receiving data processing entity. Inspect headers for
past copyright information. All rights reserved. Unauthorised copying,
hiring, renting, public performance and/or broadcasting of this
signature prohibited. 

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe