[Haskell]Компиляция и путешествие во времени.
От: Klapaucius  
Дата: 29.06.09 16:31
Оценка:
Простая интерактивная программа
module Main (main) where

import Control.Monad

foo a b = a + b

(=>>) = flip liftM

ask q = putStr q >> getLine =>> read

main = liftM2 foo (ask "a=") (ask "b=") >>= print

интерпретируется совершенно корректно (что совсем не удивительно)
>c:\ghc\ghc-6.10.3\bin\ghci.exe "D:\_projects\h\Problem.hs"
GHCi, version 6.10.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling Main             ( D:\_projects\h\Problem.hs, interpreted )
Ok, modules loaded: Main.
*Main> main
a=2
b=2
4
*Main>

но она же, будучи скомпилированной, отправляет события вывода строк в далекое будущее:
2
2
a=b=4

Как видите, сначала все считывания данных, а потом все выводы данных.
Но почему так происходит?
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re: [Haskell]Компиляция и путешествие во времени.
От: VoidEx  
Дата: 29.06.09 19:55
Оценка: 12 (1)
Здравствуйте, Klapaucius, Вы писали:

K>Простая интерактивная программа

K>
K>module Main (main) where

K>import Control.Monad

K>foo a b = a + b

K>(=>>) = flip liftM

K>ask q = putStr q >> getLine =>> read

K>main = liftM2 foo (ask "a=") (ask "b=") >>= print
K>

K>интерпретируется совершенно корректно (что совсем не удивительно)
K>
>>c:\ghc\ghc-6.10.3\bin\ghci.exe "D:\_projects\h\Problem.hs"
K>GHCi, version 6.10.3: http://www.haskell.org/ghc/  :? for help
K>Loading package ghc-prim ... linking ... done.
K>Loading package integer ... linking ... done.
K>Loading package base ... linking ... done.
K>[1 of 1] Compiling Main             ( D:\_projects\h\Problem.hs, interpreted )
K>Ok, modules loaded: Main.
K>*Main> main
K>a=2
K>b=2
K>4
K>*Main> 
K>

K>но она же, будучи скомпилированной, отправляет события вывода строк в далекое будущее:
K>
K>2
K>2
K>a=b=4
K>

K>Как видите, сначала все считывания данных, а потом все выводы данных.
K>Но почему так происходит?

hSetBuffering
Re: [Haskell]Компиляция и путешествие во времени.
От: geniepro http://geniepro.livejournal.com/
Дата: 30.06.09 05:42
Оценка: 12 (1)
Здравствуйте, Klapaucius, Вы писали:

K>Как видите, сначала все считывания данных, а потом все выводы данных.

K>Но почему так происходит?

Вот так:
module Main (main) where

import Control.Monad
import System.IO

foo a b = a + b

(=>>) = flip liftM

ask q = putStr q >> getLine =>> read

main = do
    hSetBuffering stdin  NoBuffering
    hSetBuffering stdout NoBuffering

    liftM2 foo (ask "a=") (ask "b=") >>= print
Re[2]: [Haskell]Компиляция и путешествие во времени.
От: Klapaucius  
Дата: 30.06.09 06:29
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>hSetBuffering


Нда. Почувствовал себя полным идиотом.
Но мне показалось довольно неожиданным, что высокоуровневый язык вот так сразу тыкает тебя носом в буфер stdout. За n лет программирования на C# я про буфер stdout ни разу не вспомнил.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[2]: [Haskell]Компиляция и путешествие во времени.
От: Klapaucius  
Дата: 30.06.09 06:29
Оценка: +1
Здравствуйте, geniepro, Вы писали:

G>
G>main = do
G>    hSetBuffering stdin  NoBuffering
G>    hSetBuffering stdout NoBuffering

G>    liftM2 foo (ask "a=") (ask "b=") >>= print
G>


Ну, я думаю, что ask должен гарантировать, что вопрос появляется раньше, чем ожидается ответ. Т.е. лучше сделать как-то так:
ask q = putStr q >> hFlush stdout >> getLine =>> read

верно?
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[3]: [Haskell]Компиляция и путешествие во времени.
От: geniepro http://geniepro.livejournal.com/
Дата: 30.06.09 09:04
Оценка:
Здравствуйте, Klapaucius, Вы писали:

K>Ну, я думаю, что ask должен гарантировать, что вопрос появляется раньше, чем ожидается ответ. Т.е. лучше сделать как-то так:

K>
K>ask q = putStr q >> hFlush stdout >> getLine =>> read
K>

K>верно?

Вообще хорошая мысль.
Re[4]: [Haskell]Компиляция и путешествие во времени.
От: Кодт Россия  
Дата: 30.06.09 13:23
Оценка:
Здравствуйте, geniepro, Вы писали:

K>>Ну, я думаю, что ask должен гарантировать, что вопрос появляется раньше, чем ожидается ответ. Т.е. лучше сделать как-то так:

K>>
K>>ask q = putStr q >> hFlush stdout >> getLine =>> read
K>>

K>>верно?

G>Вообще хорошая мысль.


Получается, что у скомпилированного хаскелла кривая консоль (в составе его рантайма)?
Если getLine введённые символы из stdin выводит эхом в stdout, то — по-человечески, эхо-вывод должен оказаться в буфере после того, что туда было накидано.
А если эхо живёт своей независимой жизнью... Ну, понятно, как это можно сделать, и даже понятно, почему. (Потому что консоль лежит ниже буферизованного ввода-вывода).
Но остаётся вопрос: какого чёрта?!
... << RSDN@Home 1.2.0 alpha 4 rev. 1207>>
Перекуём баги на фичи!
Re[5]: [Haskell]Компиляция и путешествие во времени.
От: geniepro http://geniepro.livejournal.com/
Дата: 01.07.09 05:55
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Получается, что у скомпилированного хаскелла кривая консоль (в составе его рантайма)?


Почему-то там буферизация ввода-вывода включена по умолчанию...
Вроде бы в линуксе тоже так.

К>Если getLine введённые символы из stdin выводит эхом в stdout, то — по-человечески, эхо-вывод должен оказаться в буфере после того, что туда было накидано.

К>А если эхо живёт своей независимой жизнью... Ну, понятно, как это можно сделать, и даже понятно, почему. (Потому что консоль лежит ниже буферизованного ввода-вывода).
К>Но остаётся вопрос: какого чёрта?!

Хороший вопрос, но не ко мне.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.