Re: [Haskell-cafe] Re: Comments on reading two ints off Bytestring
On Dec 23, 2007 1:44 PM, Isaac Dupree [EMAIL PROTECTED] wrote: parseHeader3 :: BS.ByteString - Maybe (Int, Int) parseHeader3 bs = do (x, rest) - BS.readInt $ BS.dropWhile (not . isDigit) bs (y, _) - BS.readInt $ BS.dropWhile (not . isDigit) rest return (x, y) But that version still itches! :-) This is what it sounds like to me: parseHeader :: BS.ByteString - Maybe (Int,Int) parseHeader = evalStateT $ liftM2 (,) parseInt parseInt where parseInt = StateT $ BS.readInt . BS.dropWhile (not . isDigit) - Benja ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: CAF's in Haskell
Hi Are CAF's specified in the Haskell report? I couldn't find them mentioned. CAF is a term of art. If you define fred = 2 + 2 that's a CAF. I should have been more precise with my question. Given the code: fred = 2 + 2 bob = fred + fred In a Haskell implementation fred would be evaluated once to 4, then used twice. The 2+2 would only happen once (ignore defaulting and overloaded numerics for now). Is this sharing mandated by the standard? (I don't think so) Is there some paper that describes why this is desirable, and gives any detail? If not, why do all Haskell compilers support them? How could they not? I'm not sure I understand your question. Do all Haskell compilers support the sharing. Thanks Neil ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] CAF's in Haskell
On Wed, 26 Dec 2007 17:16:22 +0200, Neil Mitchell [EMAIL PROTECTED] wrote: Hi, Are CAF's specified in the Haskell report? I couldn't find them mentioned. If not, why do all Haskell compilers support them? Is there some paper which persuaded everyone they were a good idea, or some reference I could look up? I found this in the wiki http://www.haskell.org/haskellwiki/Constant_applicative_form ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: CAF's in Haskell
Neil Mitchell [EMAIL PROTECTED] writes: Hi, Are CAF's specified in the Haskell report? I couldn't find them mentioned. CAF is a term of art. If you define fred = 2 + 2 that's a CAF. If not, why do all Haskell compilers support them? How could they not? I'm not sure I understand your question. -- Jón Fairbairn [EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] Re: CAF's in Haskell
Well I certainly hope the standard defines that both fred and bob will only be evaluated once, because my programs depend on that :) Peter Neil wrote: fred = 2 + 2 bob = fred + fred In a Haskell implementation fred would be evaluated once to 4, then used twice. The 2+2 would only happen once (ignore defaulting and overloaded numerics for now). Is this sharing mandated by the standard? (I don't think so) Is there some paper that describes why this is desirable, and gives any detail? Do all Haskell compilers support the sharing? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: DSL question -- was: New slogan for haskell.org
Steve Lihn stevelihn at gmail.com writes: I do come aross a question while reading the DSL page on Wikipedia. http://en.wikipedia.org/wiki/Domain-specific_programming_language In the Disadvantage section (near the end), there is an item -- hard or impossible to debug. Can anybody explain why or what it means? And how does it apply to Haskell? I think I can give a good example of how this can apply to EMBEDDED DSLs. My library Dimensional (http://dimensional.googlecode.com) defines what someone referred to as a EDSL for working with physical units. The library leverages the Haskell type checker to provide static checking of physical dimensions. Without doing this I don't know how I could make such checking static. The downside of this is that while you will be informed at compile time if you physical calculations are incorrect the error message itself is rarely useful. Here is an example with lines numbered: 1 import Numeric.Units.Dimensional.Prelude 2 import qualified Prelude 3 4 -- The angular velocity of Earth's rotation (Soop p. 7). 5 phi = 360.985647 *~ (degree / day) 6 7 -- The gravitational parameter of Earth. 8 mu = 3.98600448003e14 *~ (meter ^ pos3 / second ^ pos2) 9 10 -- The ideal geostationary radius and velocity. 11 r_GEO = cbrt (mu / phi ^ pos2) 12 v_GEO = phi * r_GEO 13 14 -- Something obviously wrong. 15 dont_try_this_at_home = v_GEO + mu Obviously we shouldn't be adding a velocity to a gravitational parameter on line 15 and the compiler will catch this. However, this is the error message from GHCi (6.6.1): DSLTest.hs:1:0: Couldn't match expected type `Numeric.NumType.Neg n' against inferred type `Numeric.NumType.Zero' When using functional dependencies to combine Numeric.NumType.Sub a Numeric.NumType.Zero a, arising from the instance declaration at Defined in Numeric.NumType Numeric.NumType.Sub Numeric.NumType.Zero Numeric.NumType.Zero (Numeric.NumType.Neg n), arising from use of `/' at DSLTest.hs:11:14-28 I think you will agree that this isn't very helpful in pin-pointing the problem. The compiler is pointing at the definition of 'r_GEO' which is twice removed from the actual offender. Stuff like this can make EDSLs difficult to debug. (In this particular example adding type signatures to all definitions will allow the compiler to pin-point the error to line 15, although the error message remains cryptic.) Hope that helps, Bjorn ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: CAF's in Haskell
Hi Neil, On Dec 26, 2007 7:16 PM, Neil Mitchell [EMAIL PROTECTED] wrote: Given the code: fred = 2 + 2 bob = fred + fred In a Haskell implementation fred would be evaluated once to 4, then used twice. The 2+2 would only happen once (ignore defaulting and overloaded numerics for now). Is this sharing mandated by the standard? (I don't think so) Is there some paper that describes why this is desirable, and gives any detail? I think if the report does not mandate it, it's for the same reason that Haskell-the-language is non-strict, not lazy-- it thinks that it's the compiler's business to decide things like this. (After all, there are situations where it might be better to evaluate Fred twice, and the compiler might recognize some of them.) But the Haskell design certainly anticipates that this is what compilers will normally do: the point of the dreaded monomorphism restriction is to make sure that 'fred' doesn't accidentally become (Num a = a), which would make it infeasible to evaluate it only once (because you would have to store the value for every instance of Num). It's a lot like you can expect Haskell implementations to be lazy, not call-by-name. (I don't know when this behavior originated.) - Benja ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Printing and Referential transparency excuse
On 12/26/07, Cristian Baboi [EMAIL PROTECTED] wrote: The reason I want to build functions of type String - (a - b) is because I want to see how far I can get with functions are first class citizens in Haskell. I thought that if I read the function from an external source, there is no way the compiler could know what I'll read. I want to see if I can build a Haskell function at runtime, not a data structure that I can interpret. Those two questions are intimately related, though. Consider the following simple program: {-# LANGUAGE GADTs #-} module Compile where data Term a where App :: Term (a - b) - Term a - Term b Prim :: a - Term a Implementation of lambda-abstractions is left as an exercise for the reader. compile :: Term a - a compile (Prim x) = x compile (App x y) = compile x $ compile y While compile looks like an interpreter (and it is), there is no reason why a has to be a concrete data type; it could be a function type, as demonstrated here: uncompiled_func :: Term (Int - Int) uncompiled_func = App (Prim (+)) (Prim 1) compiled_func :: Int - Int compiled_func = compile uncompiled_func The first time you evaluate compiled_func, you'll run the compiler which will create a function for you. Consider the lazy evaluation order of this program: result :: Int result = compiled_func 3 + compiled_func 4 I'll use let to represent sharing and plus# to represent the primitive operation of adding two numbers which (+) is defined in terms of. That is, (+) = \x y - plus# x y result = compiled_func 3 + compiled_func 4 = (\x y - plus# x y) (compiled_func 3) (compiled_func 4) = plus# (compiled_func 3) (compiled_func 4) = let compiled_func = compile uncompiled_func in plus# (compiled_func 3) (compiled_func 4) (evaluating compiled_func) compile (App (Prim (+)) (Prim 1)) = compile (Prim (+)) (compile (Prim 1)) = (+) (compile (Prim 1)) = (\x y - plus# x y) (compile (Prim 1)) = (\y - plus# (compile (Prim 1)) y) which is WHNF = let compiled_func = (\y - plus# (compile (Prim 1)) y) in plus# (compiled_func 3) (compiled_func 4) = let inner = (compile (Prim 1)); compiled_func = \y - plus# inner y in plus# (compiled_func 3) (compiled_func 4) = let inner = (compile (Prim 1)) in plus# (plus# inner 3) ((\y - plus# inner y) 4) = let inner = 1 in plus# (plus# inner 3) ((\y - plus# inner y) 4) = plus# 4 ((\y - plus# 1 y) 4) = plus# 4 (plus# 1 4) = plus# 4 5 = 9 Note that compile only gets run once on each subexpression; the end result is that you end up with a regular Haskell function which does no interpretation at all! All that remains is creation of something of type Term a from an untyped representation. Oleg's done the work here and you can see a full implementation in this message: http://www.haskell.org/pipermail/haskell-cafe/2007-October/032591.html -- ryan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Why does this blow the stack?
The (extremely enlightening) discussion so far has focused on the inconsistent (arguably buggy) behavior of [a,b..c] enumeration sugar. I think it's worth pointing out that the code could also be made to run by making the drop function strict. I got to thinking, in a strictness debugging scenario like this, it seems like you can get the behavior you want by making things strict at various levels. You can make the inner level (enumeration sugar) stricter, or you can leave the enumeration stuff lazy and make the drop stricter. Maybe I didn't express that very well, so here's code: (I would argue that this discussion could be the basis of a strictness kata exercise, following up from a cafe post I made a while ago.) {-# LANGUAGE BangPatterns #-} import Data.List import Testing import Test.QuickCheck import Test.QuickCheck.Batch tDrop = ( head . drop n ) ( edi1 1 2 ) tStrictDrop = ( head . strictDrop n ) ( edi1 1 2 ) n = 10^6 --edi: enum delta integer -- stack overflow on 10^6 el list if use drop -- ok with strictDrop edi1 start next = start : edi1 next (next + delta) where delta = next - start -- ok (no overflow) for drop, of course also okay for strictDrop edi2 !start next = start : edi2 next (next + delta) where delta = next - start ediWithMax start next bound = takeWhile p $ edi start next where p i | delta 0 = i = bound | delta 0 = i = bound | otherwise = i = bound delta = next - start edi = edi1 strictDrop _ [] = [] strictDrop n l | n = 0 = l strictDrop n (!x:xs) | n0 = strictDrop (n-1) xs pStrictDropSameAsDrop n xs = drop n xs == strictDrop n xs where types = (n::Int,xs::[Integer]) pEdi1 start next max = abs(next-start) 0 == -- otherwise hits bottom because of eg [0,0..0] ediWithMax start next max == [start,next..max] where types = (start :: Integer, next :: Integer, max :: Integer) pEdi2 start next max = ( take 1000 $ ediWithMax start next max ) == ( take 1000 $ [start,next..max] ) where types = (start :: Integer, next :: Integer, max :: Integer) t2 = runTests edi testOptions [run pEdi1, run pEdi2, run pStrictDropSameAsDrop] where testOptions = TestOptions { no_of_tests = 100 -- number of tests to run , length_of_tests = 1 -- 1 second max per check -- where a check == n tests , debug_tests = False -- True = debugging info } 2007/12/21, Justin Bailey [EMAIL PROTECTED]: Given this function: dropTest n = head . drop n $ [1..] I get a stack overflow when n is greater than ~ 550,000 . Is that inevitable behavior for large n? Is there a better way to do it? Justin ___ 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
Re: [Haskell-cafe] Why does this blow the stack?
dbenbenn: Since it's possible to support laziness for Integer (while still avoiding any stack overflow), I think it makes sense to do so. What if you have some big complicated program like the following: x = some big slow computation y = [x..] lots of code z = length $ take 10 y Why bother computing x if you don't have to? And as an added benefit, if you keep laziness, you don't have to worry about possibly breaking any programs that depend on the current lazy behavior. Laziness would NOT make sense for Int, since Int is bounded. You can't tell how long [(x::Int) ..] is without evaluating x. On 12/22/07, Don Stewart [EMAIL PROTECTED] wrote: People shouldn't be writing code that depends on this! One of the main features of Haskell is that it's lazy. I don't think it's wrong to write code that depends on laziness. Depending on laziness if fine, but depending on undefined strictness semantics for particular types is more fragile. Whether Int or Bool or whatever type has a strict or lazy accumulator in enumFromTo is entirely unspecified -- you can't look up the report to check. -- Don ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: CAF's in Haskell
On 26 Dec 2007, at 12:30 PM, Peter Verswyvelen wrote: Well I certainly hope the standard defines that both fred and bob will only be evaluated once, because my programs depend on that :) If your programs depend on lazy evaluation, they can't be Haskell 98. Any complete reduction method is sound for Haskell 98. If you're using an extension (such as unsafePerformIO) that isn't Haskell 98, check your compiler documentation --- although you'll find that there is no guarantee that a CAF is evaluated only once (and in fact small CAFs may not be). jcc ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Why does this blow the stack?
On 12/26/07, Don Stewart [EMAIL PROTECTED] wrote: Depending on laziness if fine, but depending on undefined strictness semantics for particular types is more fragile. Whether Int or Bool or whatever type has a strict or lazy accumulator in enumFromTo is entirely unspecified -- you can't look up the report to check. Right, I understand that. But is there any reason not to keep the Integer version of [a..] lazy, given that we can fix the stack overflow problem without introducing strictness? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Comments on reading two ints off Bytestring
Just curious -- how can this be done in Arrows instead of Manad/T? Or can it? On Dec 26, 2007 6:42 AM, Benja Fallenstein [EMAIL PROTECTED] wrote: On Dec 23, 2007 1:44 PM, Isaac Dupree [EMAIL PROTECTED] wrote: parseHeader3 :: BS.ByteString - Maybe (Int, Int) parseHeader3 bs = do (x, rest) - BS.readInt $ BS.dropWhile (not . isDigit) bs (y, _) - BS.readInt $ BS.dropWhile (not . isDigit) rest return (x, y) But that version still itches! :-) This is what it sounds like to me: parseHeader :: BS.ByteString - Maybe (Int,Int) parseHeader = evalStateT $ liftM2 (,) parseInt parseInt where parseInt = StateT $ BS.readInt . BS.dropWhile (not . isDigit) - Benja ___ 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
Re: [Haskell-cafe] Re: DSL question -- was: New slogan for haskell.org
arising from use of `/' at DSLTest.hs:11:14-28 Thanks for the example. I am particularly amazed GHC is complaining at '/', not '+'. The type mismatch occurs (is reported) at much lower level. It would be nice if there is a way to bump it up a couple levels... On Dec 26, 2007 12:56 PM, Bjorn Buckwalter [EMAIL PROTECTED] wrote: Steve Lihn stevelihn at gmail.com writes: I do come aross a question while reading the DSL page on Wikipedia. http://en.wikipedia.org/wiki/Domain-specific_programming_language In the Disadvantage section (near the end), there is an item -- hard or impossible to debug. Can anybody explain why or what it means? And how does it apply to Haskell? I think I can give a good example of how this can apply to EMBEDDED DSLs. My library Dimensional (http://dimensional.googlecode.com) defines what someone referred to as a EDSL for working with physical units. The library leverages the Haskell type checker to provide static checking of physical dimensions. Without doing this I don't know how I could make such checking static. The downside of this is that while you will be informed at compile time if you physical calculations are incorrect the error message itself is rarely useful. Here is an example with lines numbered: 1 import Numeric.Units.Dimensional.Prelude 2 import qualified Prelude 3 4 -- The angular velocity of Earth's rotation (Soop p. 7). 5 phi = 360.985647 *~ (degree / day) 6 7 -- The gravitational parameter of Earth. 8 mu = 3.98600448003e14 *~ (meter ^ pos3 / second ^ pos2) 9 10 -- The ideal geostationary radius and velocity. 11 r_GEO = cbrt (mu / phi ^ pos2) 12 v_GEO = phi * r_GEO 13 14 -- Something obviously wrong. 15 dont_try_this_at_home = v_GEO + mu Obviously we shouldn't be adding a velocity to a gravitational parameter on line 15 and the compiler will catch this. However, this is the error message from GHCi (6.6.1): DSLTest.hs:1:0: Couldn't match expected type `Numeric.NumType.Neg n' against inferred type `Numeric.NumType.Zero' When using functional dependencies to combine Numeric.NumType.Sub a Numeric.NumType.Zero a, arising from the instance declaration at Defined in Numeric.NumType Numeric.NumType.Sub Numeric.NumType.Zero Numeric.NumType.Zero (Numeric.NumType.Neg n), arising from use of `/' at DSLTest.hs:11:14-28 I think you will agree that this isn't very helpful in pin-pointing the problem. The compiler is pointing at the definition of 'r_GEO' which is twice removed from the actual offender. Stuff like this can make EDSLs difficult to debug. (In this particular example adding type signatures to all definitions will allow the compiler to pin-point the error to line 15, although the error message remains cryptic.) Hope that helps, Bjorn ___ 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
Re: [Haskell-cafe] Re: DSL question -- was: New slogan for haskell.org
* Steve Lihn wrote: Thanks for the example. I am particularly amazed GHC is complaining at '/', not '+'. The type mismatch occurs (is reported) at much lower level. It would be nice if there is a way to bump it up a couple levels... Add type signatures for mu and dont_try_this. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Wikipedia on first-class object
http://en.wikipedia.org/wiki/First-class_object The term was coined by Christopher Strachey in the context of “functions as first-class citizens” in the mid-1960's.[1] Depending on the language, this can imply: 1. being expressible as an anonymous literal value 2. being storable in variables 3. being storable in data structures 4. having an intrinsic identity (independent of any given name) 5. being comparable for equality with other entities 6. being passable as a parameter to a procedure/function 7. being returnable as the result of a procedure/function 8. being constructable at runtime 9. being printable 10. being readable 11. being transmissible among distributed processes 12. being storable outside running processes I'll guess that 5,9,12 does not apply to Haskell functions. Information from NOD32 This message was checked by NOD32 Antivirus System for Linux Mail Servers. part000.txt - is OK http://www.eset.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe