Clojure print function - clojure

Complete Clojure newbie here so I'm probably missing something fundamental about the way clojure works but I'm not understanding the way Clojure evaluates functions.
(defn get-output []
(print "Enter: Width <RTN> Height <RTN> Price <RTN> Shape <RTN>")
(print (calculate (read-string (read-line))))
I'm used to a language like Ruby or C where the first print function would be evaluated, printing the string to the terminal. Then the second print function would be evaluated, prompting the user for input.
However, what actually happens is that the terminal first prompts the user for input and prints "Enter: Width Height Price Shape " after. Finally the program outputs the return value from calculate.
Why are these print statements not executing as I expect?

The statements are executing in the order that you expect. The issue is that print doesn't flush the out buffer. You can either call (flush) after the first print statement or perhaps you want to call println

Related

How is Clojure's read-line used properly in a do statement?

I'm puzzled by the following behavior:
(do (println "Say hi.") (println (read-line)))
I would expect the message "Say hi." to appear in the console before the program blocks and waits for input. Instead the program blocks right away and only outputs "Say hi." after the user has responded. What's going on here and how is this program written properly?
If you look at the source of println you'll see it calls prn. When you look at the source of prn you'll see it flushes *out* on a newline when *flush-on-newline* is bound to true.
What is the value of *flush-on-newline* in your REPL?
This is probably a buffering issue. Try issuing a (flush) before the readline call.

Support for ANSI escape sequence cursor moving

I'm making a simple ASCII animation, and I need the ability to place the cursor at an arbitrary point in the console screen.
While searching, I found this blog that shows this can be achieved by doing:
(print (str (char 27) "[2J")) ; clear screen
(print (str (char 27) "[;H")) ; move cursor to the top left corner of the screen
, which uses ANSI escape sequences.
The first line works as expected, but unfortunately, I haven't been able to find a console that allows for the second line to move the cursor.
After looking up how ANSI escape sequences work, I wrote up this function to ease it's use:
(defn move-cursor-to [x y]
(print (str (char 27) "[" y ";" x "H")))
But when I run (move-cursor-to 10 10), the output is wrong in every "console" I've tried:
IntelliJ/Cursive's REPL ignores it outright; printing nothing.
IntelliJ's Terminal prints the escape character as a ?, and literally prints the rest (?[10;10H)
The Window's 10 command prompt prints something similar to IntelliJ's Terminal, except the ? it prints is inside a box.
Am I doing something wrong? Is there a way to get this to work in the standard Windows 10 command prompt?
I wrote this to fill in the blanks in the meantime:
(defn move-cursor-to [x y]
(let [r #(apply str (repeat % %2))]
(print (str (r y \newline)
(r x \space)))))
but this is a poor solution. It requires clearing the screen prior to use, which for anything beyond a simple animation is unacceptable.
There is an easier way!
There is a much easier way to do this. Have a look at
the clojure-lanterna library.
This library will allow you to address an arbitrary location on a screen. It can
either use a terminal emulator or it can create a swing based window.
Another advantage of using this library is that it also incorporates support for
a virtual window or virtual screen, which can make your output appear to be
much smoother and reduces potential flicker.
The library also has support for ANSI colour codes and a few other nice
features.
Cursive only implements a limited subset of ANSI commands. In particular, most of the caret movement commands don't work. Feel free to file an issue for this, but fixing it is likely to be low priority since it's quite tricky to do in a REPL output pane.

How do I interactively read the input text for this Emacs function?

I am new to Emacs functions. Today is my first attempt to create a function.
I know that count-matches will tell me how many times a regex appears in the rest of the buffer, but most of the time I need to count from the beginning of the buffer. So I tried this:
(defun count-matches-for-whole-buffer (text-to-count)
"Opens the ~/.emacs.d/init.el file"
(interactive "sText-to-count:")
(beginning-of-buffer)
(count-matches text-to-count))
I put this in ~/.emacs.d/init.el and then do "eval-buffer" on that buffer.
So now I have access to this function. And if I run it, it will ask me for text to search for.
But the function only gets as far as this line:
beginning-of-buffer
I never get the count. Why is that?
Two things.
You should use (goto-char (point-min)) instead of beginning-of-buffer.
count-matches will not display messages when called from lisp code unless you provide a parameter indicating so.
Try this code:
(defun count-matches-for-whole-buffer (text-to-count)
(interactive "sText-to-count:")
(count-matches text-to-count (point-min) (point-max) t))

Clojure REPL not printing prior to asking for input

I'm writing a generic function that asks for input from the user, validates it via a passed function, and displays a message if the input is bad.
The problem I'm facing is the message asking for input doesn't actually print until after the user has already given the input.
Since I'm using print instead of println, stream buffering is the obvious culprit, but even after flushing after printing, it still doesn't print at the right time. Here's the simplest example of the problem:
(defn- fprint [message]
(print message)
(flush))
(defn simple-interact []
(fprint "123")
(fprint (read-line))
(fprint "456"))
Using IntelliJ IDEA's REPL, running this causes a popup input prompt. If I enter abc into the prompt, it prints 123abc456 at once instead of in parts; 123 isn't printed until after I've already given the input.
I'm using print instead of println because the real function I'm writing displays a given message, and I don't want to force it to print a newline if the intial message is intended to be a prompt. For reference, here's the full function and helpers:
(defn- print-mesage? [message]
(and message (not= message "")))
(defn- fprint [message]
(print message)
(flush))
(defn- fprint? [message]
(if (print-mesage? message)
(fprint message)))
(defn restricted-ask-for-input
"Asks a user for input. Will repeatedly ask until their input is verified via validate-f.
The ask message is displayed once before input is first asked for.
The error message is displayed every time validation fails.
If either of the messages is empty, or falsey, they won't be printed.
The messages dont' have a newline added after them."
[ask-message error-message validate-f]
(fprint? ask-message)
(loop []
(let [in (read-line)]
(if (validate-f in)
in
(do
(fprint? error-message)
(recur))))))
I really need to be able to print prior to asking for input so the user knows what's being asked.
Any help here would be appreciated.
Just as a test after posting this I tried changing fprint to use println instead, and the behavior is the same.

Clojure: *out* vs System/out

I'm trying to translate a small console program I wrote in Java into Clojure, but I'm having a little trouble figuring out the difference between Clojure's standard *out* var and the object at System/out. I was under the impression that they were the same thing, but when during my testing they seem to be different.
In my program I prompt the user to enter a number, and I want the prompt and input text to be on the same line. In Java, I printed the prompt with System.out.print() and then a Scanner read the input.
The following was my first attempt at something similar in Clojure. Though the print function seems like it should fire before the read-line, it immediately blocks on input and prints everything after in a jumbled mess:
(defn inp1 []
(print "Enter your input: ")
(let [in (read-line)]
(println "Your input is: " in)))
The following was my next attempt, using *out*. It suffers from the same problem as the function above:
(defn inp2 []
(.print *out* "Enter input: ")
(let [i (read-line)]
(println "You entered: " i)))
On my third try, I finally got it to work by using System/out directly:
(defn inp3 []
(let [o System/out]
(.print o "Enter input: ")
(let [i (read-line)]
(println "You entered: " i))))
I'm glad I finally got it to work, but I'm deeply confused as to why the third one works the way I want when the first two don't. Why do the first two block immediately? Can anyone shed some light on this?
Per the docs:
*out* - A java.io.Writer object representing standard output for print operations.
Defaults to System/out, wrapped in an OutputStreamWriter
...so, you have a layer of wrapping. Looking at the docs for that layer (emphasis added):
Each invocation of a write() method causes the encoding converter to be invoked on the given character(s). The resulting bytes are accumulated in a buffer before being written to the underlying output stream. The size of this buffer may be specified, but by default it is large enough for most purposes. Note that the characters passed to the write() methods are not buffered.
...emphasis added. Since OutputStreamWriter buffers, you need to call .flush to force content to be written.