[Haskell-cafe] \_ - not equivalent to const $

2008-01-10 Thread Luke Palmer
In attempting to devise a variant of cycle which did not keep its
argument alive (for the purpose of cycle [1::Int..]), I came across
this peculiar behavior:

import Debug.Trace

cycle' :: (a - [b]) - [b]
cycle' xs = xs undefined ++ cycle' xs


 take 20 $ cycle' (const $ 1:2:3:4:trace x 5:[])
[1,2,3,4,x
5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5]

Nuts.  Oh, but wait:

 take 20 $ cycle' (\_ - 1:2:3:4:trace x 5:[])
[1,2,3,4,x
5,1,2,3,4,x
5,1,2,3,4,x
5,1,2,3,4,x
5]

Hey, it worked!

Can someone explain what the heck is going on here?

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


Re: [Haskell-cafe] \_ - not equivalent to const $

2008-01-10 Thread Felipe Lessa
On Jan 10, 2008 8:54 PM, Luke Palmer [EMAIL PROTECTED] wrote:
 Can someone explain what the heck is going on here?

AFAICT, nothing is wrong. You see, both returned the very same values.
What you saw was in fact the problem with unsafePerformIO and friends,
as they may be executed lots of times *or not*. The compiler is free
to behave in those two ways for the code with const or with the
lambda. But referential transparency wasn't broken at all =).

It seems const retained the value, while the lambda didn't. An
optimization might transform one into the other if the compiler sees
fit.

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


Re: [Haskell-cafe] \_ - not equivalent to const $

2008-01-10 Thread Luke Palmer
On Jan 10, 2008 11:11 PM, Felipe Lessa [EMAIL PROTECTED] wrote:
 On Jan 10, 2008 8:54 PM, Luke Palmer [EMAIL PROTECTED] wrote:
  Can someone explain what the heck is going on here?

 AFAICT, nothing is wrong. You see, both returned the very same values.
 What you saw was in fact the problem with unsafePerformIO and friends,
 as they may be executed lots of times *or not*. The compiler is free
 to behave in those two ways for the code with const or with the
 lambda. But referential transparency wasn't broken at all =).

Of course.  I'm trying to write a variant of cycle that will be efficient
with memory for my purposes, so the Haskell 98 standard, which says nothing
about memory usage, doesn't really interest me.  I'm more interested in
what is going on in ghc (6.8.1) in this case, if it has a simple explanation.
And of course am interested if there are any better ways to write such a
function.

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


Re: [Haskell-cafe] \_ - not equivalent to const $

2008-01-10 Thread Victor Nazarov
On Jan 11, 2008 2:11 AM, Felipe Lessa [EMAIL PROTECTED] wrote:
 On Jan 10, 2008 8:54 PM, Luke Palmer [EMAIL PROTECTED] wrote:
  Can someone explain what the heck is going on here?

 AFAICT, nothing is wrong. You see, both returned the very same values.
[snip]
 But referential transparency wasn't broken at all =).

Referential transparency wasn't broken, but I wonder what was the
compiler, and what were it's options.

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


Re: [Haskell-cafe] \_ - not equivalent to const $

2008-01-10 Thread Luke Palmer
On Jan 10, 2008 11:15 PM, Victor Nazarov [EMAIL PROTECTED] wrote:
 On Jan 11, 2008 2:11 AM, Felipe Lessa [EMAIL PROTECTED] wrote:
  On Jan 10, 2008 8:54 PM, Luke Palmer [EMAIL PROTECTED] wrote:
   Can someone explain what the heck is going on here?
 
  AFAICT, nothing is wrong. You see, both returned the very same values.
 [snip]
  But referential transparency wasn't broken at all =).
 
 Referential transparency wasn't broken, but I wonder what was the
 compiler, and what were it's options.

Ahh, it was ghc 6.8.1, without any optimization.  If I turn on optimization,
the behavior goes away, and they both behave like the const version.

Darn.

Luke

 --
 vir
 http://vir.comtv.ru/

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


Re: [Haskell-cafe] \_ - not equivalent to const $

2008-01-10 Thread Felipe Lessa
On Jan 10, 2008 9:20 PM, Luke Palmer [EMAIL PROTECTED] wrote:
 Ahh, it was ghc 6.8.1, without any optimization.  If I turn on optimization,
 the behavior goes away, and they both behave like the const version.

That was what I suggested on the last line of my previous e-mail. As
const is in Prelude, which probably was compiled with optimizations,
it would explain the difference.

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


Re: [Haskell-cafe] \_ - not equivalent to const $

2008-01-10 Thread Victor Nazarov
On Jan 11, 2008 2:28 AM, Felipe Lessa [EMAIL PROTECTED] wrote:
 On Jan 10, 2008 9:20 PM, Luke Palmer [EMAIL PROTECTED] wrote:
  Ahh, it was ghc 6.8.1, without any optimization.  If I turn on optimization,
  the behavior goes away, and they both behave like the const version.

 That was what I suggested on the last line of my previous e-mail. As
 const is in Prelude, which probably was compiled with optimizations,
 it would explain the difference.

Optimization of const doesn't affect this program behavior.

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


Re: [Haskell-cafe] \_ - not equivalent to const $

2008-01-10 Thread Benja Fallenstein
On Jan 10, 2008 11:54 PM, Luke Palmer [EMAIL PROTECTED] wrote:
 Can someone explain what the heck is going on here?

Evaluating (const EXPR) creates a closure object with a pointer to
'const' and a pointer to the EXPR thunk. Call this closure object C.
Evaluating (C undefined) calls 'const' with the EXPR and C thunks as
its arguments, which returns the EXPR thunk. The EXPR thunk is then
forced by your code. Evaluating (C undefined) again calls 'const' with
the EXPR and C pointers as its arguments again, which again returns
the *now forced* EXPR thunk.

I.e., evaluating (const EXPR) creates a closure with a pointer to a
single EXPR thunk, and then applying the same closure to some argument
multiple times uses that same EXPR thunk every time. An unoptimized
(\_ - EXPR) creates a new thunk each time the function is applied to
an argument.

Hope that helps with understanding what is going on?

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