Re: [Haskell-cafe] Re: Comments on reading two ints off Bytestring

2007-12-26 Thread Benja Fallenstein
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

2007-12-26 Thread Neil Mitchell
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

2007-12-26 Thread Cristian Baboi
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

2007-12-26 Thread Jon Fairbairn
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

2007-12-26 Thread Peter Verswyvelen
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

2007-12-26 Thread Bjorn Buckwalter
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

2007-12-26 Thread Benja Fallenstein
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

2007-12-26 Thread Ryan Ingram
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?

2007-12-26 Thread Thomas Hartman
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?

2007-12-26 Thread Don Stewart
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

2007-12-26 Thread Jonathan Cast

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?

2007-12-26 Thread David Benbennick
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

2007-12-26 Thread Steve Lihn
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

2007-12-26 Thread Steve Lihn
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

2007-12-26 Thread Lutz Donnerhacke
* 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

2007-12-26 Thread Cristian Baboi

 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