[Haskell-cafe] OT: Paper on increasing entropy in software systems
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
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
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
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
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
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
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
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)
{- 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)
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)
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
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
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
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
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
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
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.
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?
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
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
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?
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?
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?
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?
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