Additional thunk for function

What is the purpose for GHC to allocate a thunk for some functions? Why Test.map is not a function, but updatable thunk, which should become equal to the function just after the first call? Here is the details:
% ghc -c test.hs -ddump-stg
==================== STG syntax: ==================== Test.map = \u [] let { map1_sdR = \r [f_sdN ds_sdI] case ds_sdI of wild_sdU { [] -> [] []; : x_sdM xs_sdQ -> let { sat_sdT = \u [] map1_sdR f_sdN xs_sdQ; } in let { sat_sdP = \u [] f_sdN x_sdM; } in : [sat_sdP sat_sdT]; }; } in map1_sdR; SRT(Test.map): []
% cat test.hs module Test where
map f [] = [] map f (x:xs) = f x : Test.map f xs
-- Thanks in advance Victor

Looks wrong! You don't say what version. Not happening with 6.6.1 or the 6.8 release candidate ghc-6.8.0.20070916 -c -ddump-stg T1.hs -O ==================== STG syntax: ==================== T1.map = \r [f_s6M ds_s6H] case ds_s6H of wild_s6S { [] -> [] []; : x_s6L xs_s6P -> let { sat_s6R = \u [] T1.map f_s6M xs_s6P; } in let { sat_s6O = \u [] f_s6M x_s6L; } in : [sat_s6O sat_s6R]; }; SRT(T1.map): [] bash-3.1$ ghc-6.6.1 -c -ddump-stg T1.hs -O ==================== STG syntax: ==================== T1.map = \r [f_sem ds_seh] case ds_seh of wild_ses { [] -> [] []; : x_sel xs_sep -> let { sat_ser = \u [] T1.map f_sem xs_sep; } in let { sat_seo = \u [] f_sem x_sel; } in : [sat_seo sat_ser]; }; SRT(T1.map): [] bash-3.1$ | -----Original Message----- | From: glasgow-haskell-users-bounces@haskell.org [mailto:glasgow-haskell-users-bounces@haskell.org] On | Behalf Of Victor Nazarov | Sent: 21 September 2007 12:05 | To: glasgow-haskell-users@haskell.org | Subject: Additional thunk for function | | What is the purpose for GHC to allocate a thunk for some functions? | Why Test.map is not a function, but updatable thunk, which should | become equal to the function just after the first call? Here is the | details: | | > % ghc -c test.hs -ddump-stg | > | > ==================== STG syntax: ==================== | > Test.map = | > \u [] | > let { | > map1_sdR = | > \r [f_sdN ds_sdI] | > case ds_sdI of wild_sdU { | > [] -> [] []; | > : x_sdM xs_sdQ -> | > let { sat_sdT = \u [] map1_sdR f_sdN xs_sdQ; } in | > let { sat_sdP = \u [] f_sdN x_sdM; } in : [sat_sdP sat_sdT]; | > }; | > } in map1_sdR; | > SRT(Test.map): [] | > | > | > % cat test.hs | > module Test where | > | > map f [] = [] | > map f (x:xs) = f x : Test.map f xs | | -- | Thanks in advance | Victor | _______________________________________________ | Glasgow-haskell-users mailing list | Glasgow-haskell-users@haskell.org | http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

Here is some more details: % ghc -c -ddump-stg T1.hs ==================== STG syntax: ==================== T1.map = \u [] let { map1_sdR = \r [f_sdN ds_sdI] case ds_sdI of wild_sdU { [] -> [] []; : x_sdM xs_sdQ -> let { sat_sdT = \u [] map1_sdR f_sdN xs_sdQ; } in let { sat_sdP = \u [] f_sdN x_sdM; } in : [sat_sdP sat_sdT]; }; } in map1_sdR; SRT(T1.map): [] % ghc -c -ddump-stg T1.hs -O ==================== STG syntax: ==================== T1.map = \r [f_sel ds_seg] case ds_seg of wild_ser { [] -> [] []; : x_sek xs_seo -> let { sat_seq = \u [] T1.map f_sel xs_seo; } in let { sat_sen = \u [] f_sel x_sek; } in : [sat_sen sat_seq]; }; SRT(T1.map): []

On 9/21/07, Victor Nazarov
Here is some more details:
% ghc -c -ddump-stg T1.hs
==================== STG syntax: ==================== T1.map = \u [] let { map1_sdR = \r [f_sdN ds_sdI] case ds_sdI of wild_sdU { [] -> [] []; : x_sdM xs_sdQ -> let { sat_sdT = \u [] map1_sdR f_sdN xs_sdQ; } in let { sat_sdP = \u [] f_sdN x_sdM; } in : [sat_sdP sat_sdT]; }; } in map1_sdR; SRT(T1.map): []
% ghc -c -ddump-stg T1.hs -O
==================== STG syntax: ==================== T1.map = \r [f_sel ds_seg] case ds_seg of wild_ser { [] -> [] []; : x_sek xs_seo -> let { sat_seq = \u [] T1.map f_sel xs_seo; } in let { sat_sen = \u [] f_sel x_sek; } in : [sat_sen sat_seq]; }; SRT(T1.map): []
Sure, it makes sense that the extra thunk would be allocated when optimization is disabled (if you don't pass in any optimization flags like -O, it's like saying "don't do any optimization"). Don't expect GHC to generate efficient code with optimization turned off :-) Cheers, Tim -- Tim Chevalier * catamorphism.org * Often in error, never in doubt "Other than to amuse himself, why should a man pretend to know where he's going or to understand what he sees?" -- William Least Heat Moon
participants (3)
-
Simon Peyton-Jones
-
Tim Chevalier
-
Victor Nazarov