Search code examples
frege

Frege putStr flushing behavior is different from Haskell or Java


Suppose you prompt for user input with a combination of putStr and getLine:

main = do
    putStrLn "A line with line termination" -- printed correctly
    putStr   "A line without line termination, e.g. to prompt for input: " -- NOT printed
    line <-  getLine
    putStrLn ("You entered: " ++ line)

In contrast to Haskell, Frege does not print the 2nd line (which uses putStr rather than putStrLn). Is this behavior of a missing flush intended?

If Frege deviates from Haskell behavior, I would assume it to mimic Java's behavior instead. A conceptually similar example:

public static void main(String[] args) {
    System.out.println("A line with line termination");
    System.out.print("A line without line termination, e.g. to prompt for input: ");
    String line = new java.util.Scanner(System.in).nextLine();
    System.out.println("You entered: " + line);
}

This however behaves like the Haskell variant, i.e. System.out.print gets flushed immediately.

Thanks in advance for any feedback!

PS: The (mis?)behavior can be reproduced with the latest Eclipse-Plugin as well as IntelliJ/Gradle.


Solution

  • Your Java code uses System.out, which is a PrintStream. The Frege code uses a PrintWriter.

    These two classes work a bit differently with respect to flushing. From the docs of PrintWriter:

    Unlike the {@link PrintStream} class, if automatic flushing is enabled it will be done only when one of the println, printf, or format methods is invoked, ..

    So for your Frege code, you have to add a stdout.flush after the print to make it appear immediately.

    Feel free to file an issue with the request to align Frege with the Haskell behavior in this regard. (We could leave the print as is but make the putStr add the flush automatically.)