How to use scanf in OCaml - ocaml

I'm trying to make something like the following:
x = scanf(stdin);
But it has to be in OCaml, I've been reading but I can't seem to find a proper way to do this, what I'm doing is a card game and in the beginning I want to ask the user of the game, through the terminal, the amount of players that are going to play and that's why I need to scan from standard in. Thank you very much in advance.

For such a simple task, scanf is probably overkill. You might want to use read_int to get started.
# read_int ();;
17
- : int = 17
(The second line here is typed by the user, i.e., me.)

You don't have to specify stdin, do something like:
print_string "Enter number of players: ";
let p = scanf "%d" (fun x:int -> x) in
print_int p;
print_newline()

Related

Unusual order-of-execution problem with OCaml

I'm new to OCaml. I've written this very trivial program:
open Stdio
let getline =
match In_channel.input_line In_channel.stdin with
| Some x -> x
| None -> "No input"
;;
let () =
printf "What's your name? ";
printf "Hi, %s!" getline;;
and several variations thereof.
You get the idea. I ask for the user's name and print "Hi, [name]!".
It works but the output is in the wrong order. I build the project with dune, run the executable, don't get any prompt for the name, I type it in and then I get all at once "What's your name? Hi, [name]!".
Now, I know the basics of buffering in OCaml. In fact, I remember having the same problem when dabbling in OCaml a while back. I distinctly remember reading this:
The strange order of code execution in OCaml
and I'm almost certain that adding "%!" worked. I've even tried
Out_channel.flush stdout
between the two printf's, and it doesn't work. I've tried adding a "\n" in the first printf. And I've tried this in a couple of terminals.
I'm sure it's something really trivial, possibly just basic syntax.
You defined getline as a variable, not a function.
A function must always accept one parameter, although that parameter can be ():
open Stdio
let getline () =
match In_channel.input_line In_channel.stdin with
| Some x -> x
| None -> "No input"
;;
let () =
printf "What's your name? ";
printf "Hi, %s!" (getline ());;

Ocaml: Exception: End_of_file

I want to read a number but when i try to compile it it gives me Exception: End_of_file in the line read_int()
What am I doing wrong?
let k = read_int() ;;
let exercicio k=
Printf.printf "%d\n" k;
;;
If you want an online IDE which accept inputs, check : https://betterocaml.ml .
So far the best you will be able to find on internet. If you want a local install on windows check also https://github.com/gmattis/SimpleOCaml/.
The only issue with betterOCaml is that it doesn't handle infinite while loop, so be sure to save your file before running any programme with a while inside.

Create list from input using interact in Haskell

I'm starting out with Haskell and was looking into I/O mechanims. I read up on the interact function which takes a function of type String -> String as parameter. I tried to write a simple program that takes to numbers from stdin and creates a list and prints it line by line.
import Data.List
readIn = sort . map read . words
writeOut = unlines . map show
rangeList [n,m] = [n .. m]
main = interact (writeOut . rangeList . readIn)
For some reason it wont print the numbers. Could you help me out?
interact requires you to input an end-of-file (EOF) to stdin with Ctrl+D (or Ctrl+Z on Windows); when I type that combination, the output appears as required. This is necessary because, as the documentation for interact states, ‘the entire input from the standard input device is passed to [interact] as its argument’; due to this, you need to explicitly signal the place where stdin ends.
(By the way, I’m not even sure how you got your program to compile; GHC gives me lots of ‘ambiguous type’ errors when I try. I had to add type signatures to get it working, at which point I found the solution above to work.)

OCaml string length limitation when reading from stdin\file

As part of a Compiler Principles course I'm taking in my university, we're writing a compiler that's implemented in OCaml, which compiles Scheme code into CISC-like assembly (which is just C macros).
the basic operation of the compiler is such:
Read a *.scm file and convert it to an OCaml string.
Parse the string and perform various analyses.
Run a code generator on the AST output from the semantic analyzer, that outputs text into a *.c file.
Compile that file with GCC and run it in the terminal.
Well, all is good and well, except for this: I'm trying to read an input file, that's around 4000 lines long, and is basically one huge expressions that's a mix of Scheme if & and.
I'm executing the compiler via utop. When I try to read the input file, I immediately get a stack overflow error message. It is my initial guess that the file is just to large for OCaml to handle, but I wasn't able to find any documentation that would support this theory.
Any suggestions?
The maximum string length is given by Sys.max_string_length. For a 32-bit system, it's quite short: 16777211. For a 64-bit system, it's 144115188075855863.
Unless you're using a 32-bit system, and your 4000-line file is over 16MB, I don't think you're hitting the string length limit.
A stack overflow is not what you'd expect to see when a string is too long.
It's more likely that you have infinite recursion, or possibly just a very deeply nested computation.
Well, it turns out that the limitation was the amount of maximum ram the OCaml is configured to use.
I ran the following command in the terminal in order to increase the quota:
export OCAMLRUNPARAM="l=5555555555"
This worked like a charm - I managed to read and compile the input file almost instantaneously.
For reference purposes, this is the code that reads the file:
let file_to_string input_file =
let in_channel = open_in input_file in
let rec run () =
try
let ch = input_char in_channel in ch :: (run ())
with End_of_file ->
( close_in in_channel;
[] )
in list_to_string (run ());;
where list_to_string is:
let list_to_string s =
let rec loop s n =
match s with
| [] -> String.make n '?'
| car :: cdr ->
let result = loop cdr (n + 1) in
String.set result n car;
result
in
loop s 0;;
funny thing is - I wrote file_to_string in tail recursion. This prevented the stack overflow, but for some reason went into an infinite loop. Oh, well...

Haskell: odd difference between compiled vs interpreted functions which print concatenated infinite lists

I'm just exploring Haskell for fun, and to learn about the language. I thought the following behavior was interesting, and I can't find the reason why this happens.
This is an often quoted piece of Haskell code which keeps calculating pi until interrupted, slightly modified to give a concatenated list of chars instead of a list of integers:
main :: IO ()
main = do putStrLn pi'
pi' :: [Char]
pi' = concat . map show $ g(1,0,1,1,3,3) where
g(q,r,t,k,n,l) =
if 4*q+r-t<n*t
then n : g(10*q,10*(r-n*t),t,k,div(10*(3*q+r))t-10*n,l)
else g(q*k,(2*q+r)*l,t*l,k+1,div(q*(7*k+2)+r*l)(t*l),l+2)
If I run it from prelude, it starts concatenating a string resembling the digits of pi:
λ> putStrLn pi'
31415926535897932384626433832795028841971 ...etc
Works as expected, it instantly starts spewing out digits.
Now this is a piece of code I just quickly wrote which has the same structure. It's completely useless from a mathematical point of view, I was just messing around to find out how Haskell works. The operations are much simpler, but it does have the same type, and so does the sub function (except for the smaller tuple).
main :: IO ()
main = do putStrLn func
func :: [Char]
func = concat . map show $ h(1,2,1) where
h(a,b,c) =
if a <= 1000
then a : h((div a 1)+2*b,b,1)
else h(b,div (b-3) (-1),div a a)
Same type of result from prelude:
λ> putStrLn func
1591317212529333741454953576165697377818589 ...etc
Works as expected, although much faster than the pi function of course, because the calculations are less complex.
Now for the part which confuses me:
If I compile: ghc pi.hs, and run my program: ./pi, the output stays blank forever, until I send an interrupt signal. At that moment, the whole calculated string of pi is instantly displayed. It doesn't "stream" the output into stdout, like GHCI does. OK, I know they don't always behave in the same way.
But next I run: ghc func.hs, and run my program: ./func... and it immediately starts printing the list of characters.
Where does this difference come from? I thought it might be because my stupid useless little function is (eventually) repeating, so the compiler can "predict" the output better?
Or is there another fundamental difference between the way the functions work? Or am I doing something utterly stupid?
Solution / Answer
Provided by Thomas & Daniel below, I was:
Impatient. Large chunks eventually show up with the pi function, it's just a bit slow on my simple old coding machine.
Not handling buffering in any way.
So after rewriting the main function:
import System.IO
main :: IO ()
main = do hSetBuffering stdout NoBuffering
putStrLn pi'
It was fixed!
Provided by Thomas & Daniel in the comments, it turned out I was:
Impatient. Large chunks eventually show up with the pi function, it's just a bit slow on my simple old coding machine.
Not handling buffering in any way.
So after rewriting the main function:
import System.IO
main :: IO ()
main = do hSetBuffering stdout NoBuffering
putStrLn pi'
It was fixed!