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.
Related
I'm trying to implement Macro to expand Verilog Bus as Vim - Macro to expand verilog bus and this is really working good for one variable.
But I've got the problem because I want to implement multiple bus as the below
Source:
{test[13:10],thisistest[3:0],BUS[2:1]}
Result:
test[13]
test[12]
test[11]
test[10]
thisistest[3]
thisistest[2]
thisistest[1]
thisistest[0]
BUS[2]
BUS[1]
What I tried to do :
I made similar function as
fun! split()
let line = getline('.')
let result = []
let list = split(line, ",")
let length = len(list)
for i in length
call ExpandIt(list[length])
endfor
endf
fun! ExpandIt()
let pat = '^\(.*\)\[\(\d\+\):\(\d\+\)\]\s*$'
let line = getline('.')
let lnr = line('.')
if line !~ pat
return
endif
let exestr = substitute(line,pat,'range(\2,\3,-1)','g')
let text = substitute(line,pat,'\1','g')
exec 'let range='.exestr
let result = []
for i in range
call add(result, text.'['.i.']')
endfor
call append(lnr, result)
exec lnr'.d'
endf
nnoremap <F6> :call split()<cr>
Could you please let me know what am I supposed to do to go with right way?
Based on the obvious errors in your added split() function (the function name must be capitalized to avoid E128, you pass an argument to ExpandIt(), but it doesn't take any, length is not iterable by :for), you seem to have a limited understanding of Vimscript, and just try to "make it work" through brute-force attempts. Therefore it was good to ask here on Stack Overflow, but please be aware that just relying on helpful strangers to fix things for you is a lopsided approach, so please use this and future questions to slowly but steadily learn about Vim, to become a master of it yourself!
The following seems to do what you're asking for, by doing the following modifications:
fixing the obvious errors listed above
collecting the result List in Split() is the right idea, but the actual insertion (:call append()) and deletion of the original line has to be moved there as well, and ExpandIt() has to return the result
likewise, ExpandIt() needs to be passed the extracted element instead of directly getting the current line
the split() of the line into comma-separated elements needs to drop the surrounding { and }; substitute() can do this.
fun! Split()
let line = getline('.')
let result = []
for l in split(substitute(line, '[{}]', '', 'g'), ",")
let result += ExpandIt(l)
endfor
let lnr = line('.')
call append(lnr, result)
exec lnr'.d'
endf
fun! ExpandIt(line)
let pat = '^\(.*\)\[\(\d\+\):\(\d\+\)\]\s*$'
if a:line !~ pat
return
endif
let exestr = substitute(a:line,pat,'range(\2,\3,-1)','g')
let text = substitute(a:line,pat,'\1','g')
exec 'let range='.exestr
let result = []
for i in range
call add(result, text.'['.i.']')
endfor
return result
endf
nnoremap <F6> :call Split()<cr>
I have the following code (it's a test so it does nothing interesting)
let test k =
let rec aux = function
|0 -> 0
|z when z = 2 -> raise Exit
|_ -> aux (k-1)
in try let _ = aux k in true
with Exit -> false
At the end there is the use of the syntax : let _, to me it's just a syntax when you don't have an idea of a name you can use to define your function.
Yet if I do the following :
let test k =
let rec aux = function
|0 -> 0
|z when z = 2 -> raise Exit
|_ -> aux (k-1)
in try let b = aux k in true
with Exit -> false
I get a warning like : "variable b is unused", I don't understand why there is a difference between let _ and let b ?
For example I know that when dealing with unit type it's common to use the syntax : let (). Yet I don't have any warning when doing :
let b = print_int 2
even if I am not using :
let () = print_int 2
So what is particular with let _ ?
Thank you !
This is a convention, recognized by the compiler, to indicate that you're not going to use the result of a computation, e.g.,
let a = 5 + 6 in
()
will (or will not, depending on your warning settings) trigger the unused variable warning, since you clearly bound the result to a variable a, but not using it in the rest of your computation. In imperative languages it is quite common, to compute expressions for their side effects and ignore produced values if any. Since OCaml is a functional language, in which values are used to produce values, it usually an indicator of an error, when you forgot to use a bound variable.
Therefore, to explicitly tell the compiler that you're ignoring the value, you may start your variable with the underscore, e.g.,
let _unusued = 5 + 6 in
()
You can just use a wild pattern _ (which also starts with the underscore).
You have a warning with your second code because you define the variable b containing a value and you do not use it after.
The best use if you do not want to use the result of any expression is to discard its result using the 'let _ =' construct (it tells you want the expression to be evaluated, for potential side effects, but do not care to keep its result).
For the second part of your question, I think there are different rules related to the top loop, so the behaviours may not be comparable. In the first part, you define b inside a function and in the second part, you define b inside the top loop. In the top loop, you may define variables you will not use without getting a warning.
I think that what i mean is in the title. I have tried to search if it is possible to run bash script from ocaml like from java or from php but i could not find.
i know that we can use ocaml as a scripting language but it is not what i want
Ocaml as a scripting language
In other words
From the Ocaml documentation :
val command : string -> int
So if you want to call a script from Ocaml, do this :
let status = Sys.command "./myexecutable.sh" in
Printf.printf "status = %d\n" status
Feel free to do what you want with the exit code.
Just in case you are interested in collecting the output of the bash script,
let () =
(* Just using pstree as an example, you can pick something else *)
let ic = Unix.open_process_in "pstree" in
let all_input = ref [] in
try
while true do
all_input := input_line oc :: !all_input
done
with
End_of_file ->
(* Just an example, you can do something else here *)
close_in ic;
List.iter print_endline !all_input
I think what you are looking for is the Sys module (http://caml.inria.fr/pub/docs/manual-ocaml/libref/Sys.html).
Sys.command might be one way to do what you want.
If this is not enough, then you may want to take a look at what the Unix has to offer (http://caml.inria.fr/pub/docs/manual-ocaml/libref/Unix.html).
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.
I'm teaching myself OCaml and I sometimes need to create a function where I'm not really sure what the proper solution should be. Here's one that I'm a little confused about.
I need a function that will prompt the user for individual float values and return everything entered in a float list. I can create this function but I'm not sure if its the proper/best way to do it in Ocaml.
Here's my attempt.
let rec get_floats() =
match
(
try Some(read_float())
with
| float_of_string -> None
)
with
| None -> []
| Some s -> s :: get_floats();;
This code works buts I'm at a loss deciding if its a 'proper OCaml' solution. Note, to exit the function and return the float list just enter a non-integer value.
(I hope that) this is a simple peephole rewrite involving no thought whatsoever of the function in your question:
let rec get_floats() =
try
let f = read_float() in (* as suggested by Martin Jambon *)
f :: (get_floats())
with
| float_of_string -> []
The idea I tried to apply here is that you do not need to convert the success/failure of read_float into an option that you immediately match: just do what you have to do with the value read, and let the with handle the failure case.
Now that I think of it, I should point out that in both your question and my rewrite, float_of_string is a fresh variable. If you meant to match a specific exception, you failed at it: all exception constructors, like datatype constructors, are Capitalized. You might as well have written with _ -> instead of with float_of_string ->, and a recent version of OCaml with all warnings active should tell you that your function (or mine) binds a variable float_of_string without ever using it.
Thanks everyone for the help. This works.
let rec get_floats() =
try
let x = read_float() in
x :: get_floats()
with
| _ -> [];;
List.iter (fun x -> print_endline(string_of_float x)) (get_floats());;