
Dear Haskell implementors, How do you think, is the program (1) equivalent to (2) in the meaning of Haskell-98 ? (1) (\ x -> (if p x then foo (g x) else foo (h x)) where p ... g ... h ... foo ... ) (2) (\ x -> foo ((if p x then g x else h x) where p ... g ... h ... foo ... ) ) If it is equivalent, then does it make sense for a compiler to convert (1) to (2): to separate a common `factor' of the if-branches ? The reason for this may be, for example, that the result printing of (f x) is more `lazy' in (2) than in (1): the part of foo may print immediately and (g x) or (h x) may print long after. This is a difference in behavior, it does not effect the computation meaning. I have a large program which is easily written in the style of (1), (and in many places it sets `case' instead of `if'). Annoyingly, it prints out in a not a lazy manner. It can be rewritten in the form of (2), but with effort, and it will look less plain. So, maybe, this is a business of a compiler? Copy, please, the possible answer to mechvel@botik.ru ----------------- Serge Mechveliani mechvel@botik.ru

Serge,
How do you think, is the program (1) equivalent to (2) in the meaning of Haskell-98 ?
(1) (\ x -> (if p x then foo (g x) else foo (h x)) where p ... g ... h ... foo ... )
(2) (\ x -> foo ((if p x then g x else h x) where p ... g ... h ... foo ... ) )
Both examples are illegal -- there are no where-expressions in Haskell, only where-equations. Ignoring the local definition part, however, the answer is no. Lifting foo out of the branches of the conditional is only valid if foo is strict. Colin R

Hi! On Mon, Oct 11, 2004 at 02:19:45PM +0400, Serge D. Mechveliani wrote:
Dear Haskell implementors,
How do you think, is the program (1) equivalent to (2) in the meaning of Haskell-98 ?
(1) (\ x -> (if p x then foo (g x) else foo (h x)) where p ... g ... h ... foo ... )
(2) (\ x -> foo ((if p x then g x else h x) where p ... g ... h ... foo ... ) )
In general they are not, for exactly the reason you give:
The reason for this may be, for example, that the result printing of (f x) is more `lazy' in (2) than in (1): the part of foo may print immediately and (g x) or (h x) may print long after. This is a difference in behavior, it does not effect the computation meaning.
If p x == _|_ and foo _|_ /= _|_, then (1) does not equal (2).
I have a large program which is easily written in the style of (1), (and in many places it sets `case' instead of `if'). Annoyingly, it prints out in a not a lazy manner.
You get what you specify :-) Greetings, Carsten -- Carsten Schultz (2:38, 33:47), FB Mathematik, FU Berlin http://carsten.codimi.de/ PGP/GPG key on the pgp.net key servers, fingerprint on my home page.

On Mon, 11 Oct 2004, Serge D. Mechveliani wrote:
How do you think, is the program (1) equivalent to (2) in the meaning of Haskell-98 ?
Not at all. If foo is non-strict and p partial, (2) may yield a result where (1) would not. You identify the possibility yourself: (2) is lazier.
(1) (\ x -> (if p x then foo (g x) else foo (h x)) where p ... g ... h ... foo ... )
(2) (\ x -> foo ((if p x then g x else h x) where p ... g ... h ... foo ... ) )
If it is equivalent, then does it make sense for a compiler to convert (1) to (2): to separate a common `factor' of the if-branches ? The reason for this may be, for example, that the result printing of (f x) is more `lazy' in (2) than in (1): the part of foo may print immediately and (g x) or (h x) may print long after. This is a difference in behavior, it does not effect the computation meaning.
I have a large program which is easily written in the style of (1), (and in many places it sets `case' instead of `if'). Annoyingly, it prints out in a not a lazy manner. It can be rewritten in the form of (2), but with effort, and it will look less plain. So, maybe, this is a business of a compiler?
Jeremy.Gibbons@comlab.ox.ac.uk Oxford University Computing Laboratory, TEL: +44 1865 283508 Wolfson Building, Parks Road, FAX: +44 1865 273839 Oxford OX1 3QD, UK. URL: http://www.comlab.ox.ac.uk/oucl/people/jeremy.gibbons.html
participants (4)
-
Carsten Schultz
-
Colin Runciman
-
Jeremy Gibbons
-
Serge D. Mechveliani