OCaml recursively print to the toplevel - ocaml

I have written some code in OCaml which performs actions similar to the following
let rec main() =
DO STUFF...
let print_time() =
let time = Unix.localtime (Unix.time()) in
let hour = string_of_int (time.Unix.tm_hour) in
let minute = string_of_int (time.Unix.tim_min) in
print_string ("\n Time -- " ^ hour ^ ":" ^ minute)
in
Lwt.bind(Lwt_unix.sleep 30.)
(fun() -> (print_time(); main();)
;;
main();;
This code runs perfectly in the toplevel, however it seems that the times are being printed to a buffer and not immediately printed to the screen. All of the times in the buffer print to the screen at once when I give the toplevel another command.
How can I correct this issue so that the times are printed to the toplevel every time print_time() is called and not when I give the toplevel a command?
Example: If I run the program and then wait 2 minutes before I type something into the toplevel I get the following output. If I don't type anything into the toplevel then I only receive the first time message.
# #use "this_program";;
Time -- 12:03
# let x = 1;;
time -- 12:03
time -- 12:04
time -- 12:04
time -- 12:05
time -- 12:05
val x : int = 1
#
Also, this "loop" only works once (main() will not recursively call itself) in native compiled code, I have no idea how to correct that.

I would try adding flush stdout after your call to print_string.

Related

How to make the Promise lazy?

open System
open System.Threading
open Hopac
open Hopac.Infixes
let hello what = job {
for i=1 to 3 do
do! timeOut (TimeSpan.FromSeconds 1.0)
do printfn "%s" what
}
run <| job {
let! j1 = Promise.start (hello "Hello, from a job!")
do! timeOut (TimeSpan.FromSeconds 0.5)
let! j2 = Promise.start (hello "Hello, from another job!")
//do! Promise.read j1
//do! Promise.read j2
return ()
}
Console.ReadKey()
Hello, from a job!
Hello, from another job!
Hello, from a job!
Hello, from another job!
Hello, from a job!
Hello, from another job!
This is one of the examples from the Hopac documentation. From what I can see here, even if I do not explicitly call Promise.read j1 or Promise.read j2 the functions still get run. I am wondering if it is possible to defer doing the promised computation until they are actually run? Or should I be using lazy for the purpose of propagating lazy values?
Looking at the documentation, it does seem like Hopac's promises are supposed to be lazy, but I am not sure how this laziness is supposed to be manifested.
For a demonstration of laziness, consider the following example.
module HopacArith
open System
open Hopac
type S = S of int * Promise<S>
let rec arith i : Promise<S> = memo <| Job.delay(fun () ->
printfn "Hello"
S(i,arith (i+1)) |> Job.result
)
let rec loop k = job {
let! (S(i,_)) = k
let! (S(i,k)) = k
printfn "%i" i
Console.ReadKey()
return! loop k
}
loop (arith 0) |> run
Hello
0
Hello
1
Hello
2
Had the values not been memoized, every time the enter is pressed, there would be two Hellos printed per iteration. This behavior can be seen if memo <| is removed.
There are some further points worth making. The purpose of Promise.start is not specifically to get memoizing behavior for some job. Promise.start is similar to Job.start in that if you bind a value using let! or >>= for example, it won't block the workflow until work is done. However compared to Job.start, Promise.start does give an option to wait for the scheduled job to be finished by binding on the nested value. And unlike Job.start and similarly to regular .NET tasks, it is possible to extract the value from a concurrent job started using Promise.start.
Lastly, here is an interesting tidbit I've discovered while playing with promises. It turns out, a good way of turning a Job into an Alt is to turn it into an Promise first and then upcast it.
module HopacPromiseNonblocking
open System
open Hopac
open Hopac.Infixes
Alt.choose [
//Alt.always 1 ^=>. Alt.never () // blocks forever
memo (Alt.always 1 ^=>. Alt.never ()) :> _ Alt // does not block
Alt.always 1 >>=*. Alt.never () :> _ Alt // same as above, does not block
Alt.always 2
]
|> run
|> printfn "%i" // prints 2
Console.ReadKey()
Uncommenting that first case would cause the program to block forever, but if you memoize the expression first that it is possible to get what would be backtracking behavior had the regular alternatives been used.

OCaml special characters formatting?

I have the following ocaml code:
let rec c_write =
"printf(\" %d \");\n"
On calling this function in the interpreter, I expect to get the output
printf("%d"); followed by a new line, but instead I get
printf(\" %d \");\n
How can I get my expected output when I'm calling the function without using any other I/O functions?
The expression let rec c_write = "printf(\" %d \");\n" is not a function. It is a value of type string which is bound to a variable named c_write. So you're not using any I/O functions in your code.
When entered in the interactive toplevel, this value is printed by the interpreter evaluation loop for user convenience. The same as when a Python interpreter will print for you the value that you've just entered.
The representation, chosen by the OCaml toplevel interpreter, in general, has nothing to do with the representation which is used to store a value in a file or to print it. Moreover, in OCaml, there is no canonical representations.
If you want to write a function that prints a C printf statement then this is how it will look like in OCaml
let print_printf () =
print_endline {|printf("%d");|}
In the example above, I've used {||} to denote a sting literal instead of more common "", since in this literal there is no need to escape special characters and they are interpreted literally (i.e., the don't have any special meaning).
You can achieve the same result using the regular "" quotes for denoting it
let print_printf () =
print_endline "printf(\"%d\");"
Here is an example of the toplevel interaction using these definitions:
# let print_printf () =
print_endline {|printf("%d");|};;
val print_printf : unit -> unit = <fun>
# print_printf ();;
printf("%d");
- : unit = ()
# let print_printf () =
print_endline "printf(\"%d\");";;
val print_printf : unit -> unit = <fun>
# print_printf ();;
printf("%d");
- : unit = ()
If you will put this code in a file, compile, and execute and redirect into a C file it will be a well-formed C file (modulo the absence of the function body).
Since you are somehow using the toplevel printer for printing, and that you somehow needs a very specific format, you need to install a custom printer.
The following would work:
# #install_printer Format.pp_print_string;;
# " This \" is not escaped " ;;
- : string = This " is not escaped
However, it seems very likely that this is not really the problem that you are trying to solve.

SML/NJ - Print a list mid-execution

I wanted to utilize the print function inside an SML program for sort of debugging purposes to print integer list type data, inside the function and during execution, e.g. inside a let block. However, as I saw, print can only print string type data. I cannot wait for the result to return to print what I want, because the function I created branches during execution and creates many different lists, and I want to see what is the resulting list at the end of each branch.
Therefore, is there a way to print a list inside of a function, as I would print a string?
If it is an int list you can do something like this:
fun printIntList ints = app (fn i => print(Int.toString i ^" ")) ints;
Then printIntList [1,2,3] will print 1 2 3
You can do similar things for other types.
On edit: This is the best you can do with straight SML. SML/NJ has its own extensions including "access to compiler internals" and "user-customizable pretty printing" which sounds promising -- though I have little experience with their extensions to the standard library.
Simple function for turning a list of ints into a string:
fun intlistToString [] = ""
| intlistToString [x] = Int.toString x
| intlistToString (x::xs) = Int.toString x ^ ", " ^ intlistToString xs
Then you can use print (intlistToString myList) instead of print myList. It won't print the square brackets around the list, not without a little more code, but I'll leave that as an exercise because I'm lazy.

How to replay a list of event consistently

I have a file containing a list of event spaced with some time. Here is an example:
0, Hello World
0.5, Say Hi
2, Say Bye
I would like to be able to replay this sequence of events. The first column is the delta between the two consecutive events ( the first starts immendiately, the second happens 0.5s later, the third 2s later, ... )
How can i do that on Windows . Is there anything that can ensure that I am very accurate on the timing ? The idea is to be as close as what you would have listneing some music , you don't want your audio event to happen close to the right time but just on time .
This can be done easily by using the sleep function from the time module. The exact code should work like this:
import time
# Change data.txt to the name of your file
data_file = open("data.txt", "r")
# Get rid of blank lines (often the last line of the file)
vals = [i for i in data_file.read().split('\n') if i]
data_file.close()
for i in vals:
i = i.split(',')
i[1] = i[1][1:]
time.sleep(float(i[0]))
print i[1]
This is an imperfect algorithm, but it should give you an idea of how this can be done. We read the file, split it to a newline delimited list, then go through each comma delimited couplet sleeping for the number of seconds specified, and printing the specified string.
You're looking for time.sleep(...) in Python.
If you load that file as a list, and then print the values,
import time
with open("datafile.txt", "r") as infile:
lines = infile.read().split('\n')
for line in lines:
wait, response = line.split(',')
time.sleep(float(wait))
print response

Haskell: Scan Through a List and Apply A Different Function for Each Element

I need to scan through a document and accumulate the output of different functions for each string in the file. The function run on any given line of the file depends on what is in that line.
I could do this very inefficiently by making a complete pass through the file for every list I wanted to collect. Example pseudo-code:
at :: B.ByteString -> Maybe Atom
at line
| line == ATOM record = do stuff to return Just Atom
| otherwise = Nothing
ot :: B.ByteString -> Maybe Sheet
ot line
| line == SHEET record = do other stuff to return Just Sheet
| otherwise = Nothing
Then, I would map each of these functions over the entire list of lines in the file to get a complete list of Atoms and Sheets:
mapper :: [B.ByteString] -> IO ()
mapper lines = do
let atoms = mapMaybe at lines
let sheets = mapMaybe to lines
-- Do stuff with my atoms and sheets
However, this is inefficient because I am maping through the entire list of strings for every list I am trying to create. Instead, I want to map through the list of line strings only once, identify each line as I am moving through it, and then apply the appropriate function and store these values in different lists.
My C mentality wants to do this (pseudo code):
mapper' :: [B.ByteString] -> IO ()
mapper' lines = do
let atoms = []
let sheets = []
for line in lines:
| line == ATOM record = (atoms = atoms ++ at line)
| line == SHEET record = (sheets = sheets ++ ot line)
-- Now 'atoms' is a complete list of all the ATOM records
-- and 'sheets' is a complete list of all the SHEET records
What is the Haskell way of doing this? I simply can't get my functional-programming mindset to come up with a solution.
First of all, I think that the answers others have supplied will work at least 95% of the time. It's always good practice to code for the problem at hand by using appropriate data types (or tuples in some cases). However, sometimes you really don't know in advance what you're looking for in the list, and in these cases trying to enumerate all possibilities is difficult/time-consuming/error-prone. Or, you're writing multiple variants of the same sort of thing (manually inlining multiple folds into one) and you'd like to capture the abstraction.
Fortunately, there are a few techniques that can help.
The framework solution
(somewhat self-evangelizing)
First, the various "iteratee/enumerator" packages often provide functions to deal with this sort of problem. I'm most familiar with iteratee, which would let you do the following:
import Data.Iteratee as I
import Data.Iteratee.Char
import Data.Maybe
-- first, you'll need some way to process the Atoms/Sheets/etc. you're getting
-- if you want to just return them as a list, you can use the built-in
-- stream2list function
-- next, create stream transformers
-- given at :: B.ByteString -> Maybe Atom
-- create a stream transformer from ByteString lines to Atoms
atIter :: Enumeratee [B.ByteString] [Atom] m a
atIter = I.mapChunks (catMaybes . map at)
otIter :: Enumeratee [B.ByteString] [Sheet] m a
otIter = I.mapChunks (catMaybes . map ot)
-- finally, combine multiple processors into one
-- if you have more than one processor, you can use zip3, zip4, etc.
procFile :: Iteratee [B.ByteString] m ([Atom],[Sheet])
procFile = I.zip (atIter =$ stream2list) (otIter =$ stream2list)
-- and run it on some data
runner :: FilePath -> IO ([Atom],[Sheet])
runner filename = do
resultIter <- enumFile defaultBufSize filename $= enumLinesBS $ procFile
run resultIter
One benefit this gives you is extra composability. You can create transformers as you like, and just combine them with zip. You can even run the consumers in parallel if you like (although only if you're working in the IO monad, and probably not worth it unless the consumers do a lot of work) by changing to this:
import Data.Iteratee.Parallel
parProcFile = I.zip (parI $ atIter =$ stream2list) (parI $ otIter =$ stream2list)
The result of doing so isn't the same as a single for-loop - this will still perform multiple traversals of the data. However, the traversal pattern has changed. This will load a certain amount of data at once (defaultBufSize bytes) and traverse that chunk multiple times, storing partial results as necessary. After a chunk has been entirely consumed, the next chunk is loaded and the old one can be garbage collected.
Hopefully this will demonstrate the difference:
Data.List.zip:
x1 x2 x3 .. x_n
x1 x2 x3 .. x_n
Data.Iteratee.zip:
x1 x2 x3 x4 x_n-1 x_n
x1 x2 x3 x4 x_n-1 x_n
If you're doing enough work that parallelism makes sense this isn't a problem at all. Due to memory locality, the performance is much better than multiple traversals over the entire input as Data.List.zip would make.
The beautiful solution
If a single-traversal solution really does make the most sense, you might be interested in Max Rabkin's Beautiful Folding post, and Conal Elliott's followup work (this too). The essential idea is that you can create data structures to represent folds and zips, and combining these lets you create a new, combined fold/zip function that only needs one traversal. It's maybe a little advanced for a Haskell beginner, but since you're thinking about the problem you may find it interesting or useful. Max's post is probably the best starting point.
I show a solution for two types of line, but it is easily extended to five types of line by using a five-tuple instead of a two-tuple.
import Data.Monoid
eachLine :: B.ByteString -> ([Atom], [Sheet])
eachLine bs | isAnAtom bs = ([ {- calculate an Atom -} ], [])
| isASheet bs = ([], [ {- calculate a Sheet -} ])
| otherwise = error "eachLine"
allLines :: [B.ByteString] -> ([Atom], [Sheet])
allLines bss = mconcat (map eachLine bss)
The magic is done by mconcat from Data.Monoid (included with GHC).
(On a point of style: personally I would define a Line type, a parseLine :: B.ByteString -> Line function and write eachLine bs = case parseLine bs of .... But this is peripheral to your question.)
It is a good idea to introduce a new ADT, e.g. "Summary" instead of tuples.
Then, since you want to accumulate the values of Summary you came make it an istance of Data.Monoid. Then you classify each of your lines with the help of classifier functions (e.g. isAtom, isSheet, etc.) and concatenate them together using Monoid's mconcat function (as suggested by #dave4420).
Here is the code (it uses String instead of ByteString, but it is quite easy to change):
module Classifier where
import Data.List
import Data.Monoid
data Summary = Summary
{ atoms :: [String]
, sheets :: [String]
, digits :: [String]
} deriving (Show)
instance Monoid Summary where
mempty = Summary [] [] []
Summary as1 ss1 ds1 `mappend` Summary as2 ss2 ds2 =
Summary (as1 `mappend` as2)
(ss1 `mappend` ss2)
(ds1 `mappend` ds2)
classify :: [String] -> Summary
classify = mconcat . map classifyLine
classifyLine :: String -> Summary
classifyLine line
| isAtom line = Summary [line] [] [] -- or "mempty { atoms = [line] }"
| isSheet line = Summary [] [line] []
| isDigit line = Summary [] [] [line]
| otherwise = mempty -- or "error" if you need this
isAtom, isSheet, isDigit :: String -> Bool
isAtom = isPrefixOf "atom"
isSheet = isPrefixOf "sheet"
isDigit = isPrefixOf "digits"
input :: [String]
input = ["atom1", "sheet1", "sheet2", "digits1"]
test :: Summary
test = classify input
If you have only 2 alternatives, using Either might be a good idea. In that case combine your functions, map the list, and use lefts and rights to get the results:
import Data.Either
-- first sample function, returning String
f1 x = show $ x `div` 2
-- second sample function, returning Int
f2 x = 3*x+1
-- combined function returning Either String Int
hotpo x = if even x then Left (f1 x) else Right (f2 x)
xs = map hotpo [1..10]
-- [Right 4,Left "1",Right 10,Left "2",Right 16,Left "3",Right 22,Left "4",Right 28,Left "5"]
lefts xs
-- ["1","2","3","4","5"]
rights xs
-- [4,10,16,22,28]