It is an annoying behavior.  I'm not sure it is a bug.

If you wanted Clojure's printf to flush on every newline character it
issues, it would have to somehow scan through the output stream of
characters _after_ they have been formatted to see if there was a newline
character anywhere in there, and if so, call flush.  I'm not sure if that
would require reimplementing Java's formatting code or not, but if so that
is huge load of complexity to reimplement.  See more on Java's PrintWriter
class below.

If you back off from that and say that you only want the flush behavior if
the *format string* ends in a newline character, then that isn't really
flushing on every newline -- only for the special case of a newline at the
end of the format string.  Someone might still consider it annoying/a-bug
that if there was a newline in the middle of the format string, it did not
flush.

Methods to get the flushing behavior you want, assuming you do want it:

Explicit calls to (flush)

(println (format "stuff here" args here))

One that I haven't tried is to bind *out* to a Java PrintWriter class
constructed with automatic flushing enabled.  From the docs it appears that
this would enable auto-flushing after every write to it, not only when
newlines were printed.

    http://docs.oracle.com/javase/7/docs/api/java/io/PrintWriter.html

Andy


On Tue, Jun 24, 2014 at 12:34 AM, Seth Yuan <sethy...@gmail.com> wrote:

> Yeah, this is definitely an annoying bug.
>
>
> On Thursday, April 10, 2014 8:03:02 PM UTC+8, Kevin Ilchmann Jørgensen
> wrote:
>
>> nREPL server started on port 53667 on host 127.0.0.1
>> REPL-y 0.3.0
>> Clojure 1.5.1
>>     Docs: (doc function-name-here)
>>           (find-doc "part-of-name-here")
>>   Source: (source function-name-here)
>>  Javadoc: (javadoc java-object-or-class-here)
>>     Exit: Control+D or (exit) or (quit)
>>  Results: Stored in vars *1, *2, *3, an exception in *e
>>
>> *user=> (source println)*
>> (defn println
>>   "Same as print followed by (newline)"
>>   {:added "1.0"
>>    :static true}
>>   [& more]
>>     (binding [*print-readably* nil]
>>       (apply prn more)))
>> nil
>> *user=> (source prn)*
>> (defn prn
>>   "Same as pr followed by (newline). Observes *flush-on-newline*"
>>   {:added "1.0"
>>    :static true}
>>   [& more]
>>     (apply pr more)
>>     (newline)
>>     (when *flush-on-newline*
>>       (flush)))
>> nil
>> *user=> (source printf)*
>> (defn printf
>>   "Prints formatted output, as per format"
>>   {:added "1.0"
>>    :static true}
>>   [fmt & args]
>>   (print (apply format fmt args)))
>> nil
>> *user=> (source print)*
>> (defn print
>>   "Prints the object(s) to the output stream that is the current value
>>   of *out*.  print and println produce output for human consumption."
>>   {:added "1.0"
>>    :static true}
>>   [& more]
>>     (binding [*print-readably* nil]
>>       (apply pr more)))
>> nil
>> *user=> (source pr)*
>> (defn pr
>>   "Prints the object(s) to the output stream that is the current value
>>   of *out*.  Prints the object(s), separated by spaces if there is
>>   more than one.  By default, pr and prn print in a way that objects
>>   can be read by the reader"
>>   {:dynamic true
>>    :added "1.0"}
>>   ([] nil)
>>   ([x]
>>      (pr-on x *out*))
>>   ([x & more]
>>    (pr x)
>>    (. *out* (append \space))
>>    (if-let [nmore (next more)]
>>      (recur (first more) nmore)
>>      (apply pr more))))
>> nil
>> *user=> *flush-on-newline**
>> true
>> user=>
>>
>>
>> On Thu, Apr 10, 2014 at 1:50 PM, Cecil Westerhof <cldwes...@gmail.com>
>> wrote:
>>
>>> 2014-04-10 13:40 GMT+02:00 Di Xu <xud...@gmail.com>:
>>>
>>> there're three buffer mode in unix, line buffered, full buffered and no
>>>> buffered, if the output is terminal then it's default to line buffered.
>>>> That means it buffer the output until '\n' occurs, you can force output via
>>>> flush.
>>>>
>>>
>>> The printf format string is "%s: %s\n", so there is a newline, but it is
>>> not acted upon.
>>>
>>>
>>>
>>>> 2014-04-10 19:30 GMT+08:00 Cecil Westerhof <cldwes...@gmail.com>:
>>>>
>>>>> 2014-04-10 12:52 GMT+02:00 Kevin Ilchmann Jørgensen <kij...@gmail.com>
>>>>> :
>>>>>
>>>>> I believe this is how the terminal behave. You can force an
>>>>>> (clojure.core/flush)
>>>>>>
>>>>>
>>>>> But why does println not behave this way?
>>>>>
>>>>> I think I stick to println for the moment.
>>>>>
>>>>>
>>>>> On Thu, Apr 10, 2014 at 12:34 PM, Cecil Westerhof <cldwes...@gmail.com
>>>>>> > wrote:
>>>>>>
>>>>>>> I have the following simple program:
>>>>>>>     (def time-format (new java.text.SimpleDateFormat "hh:mm:ss"))
>>>>>>>
>>>>>>>     (defn now []
>>>>>>>       (new java.util.GregorianCalendar))
>>>>>>>
>>>>>>>     (defn give-message [message]
>>>>>>>       (printf
>>>>>>> "%s: %s\n" (. time-format format (. (now) getTime)) message))
>>>>>>>
>>>>>>>     (give-message "Start")
>>>>>>>     (doseq [i (range 1 100000001)]
>>>>>>>            (let [val (Math/sqrt i)
>>>>>>>                 diff (Math/abs (- (Math/pow val 2) (* val val)))]
>>>>>>>                 (when-not (< diff 1.5E-8)
>>>>>>>                   (println (format "Different for %d (%e)" i
>>>>>>> diff)))))
>>>>>>>     (give-message "Stop")
>>>>>>>
>>>>>>> It does what it should, but I have a little problem with it: the
>>>>>>> output of give-message is only showed after terminating the program. 
>>>>>>> Why is
>>>>>>> that?
>>>>>>>
>>>>>>> When changing give-message to:
>>>>>>>     (defn give-message [message]
>>>>>>>       (println (format "%s: %s" (. time-format format (. (now)
>>>>>>> getTime)) message)))
>>>>>>>
>>>>>>> the output is shown immediately.
>>>>>>>
>>>>>>
>>> --
>>> Cecil Westerhof
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To post to this group, send email to clo...@googlegroups.com
>>>
>>> Note that posts from new members are moderated - please be patient with
>>> your first post.
>>> To unsubscribe from this group, send email to
>>> clojure+u...@googlegroups.com
>>>
>>> For more options, visit this group at
>>> http://groups.google.com/group/clojure?hl=en
>>> ---
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to clojure+u...@googlegroups.com.
>>>
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>  --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to