caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] [Question] Loading .ml in memory to interact with them.
@ 2017-03-23  9:37 paul.lachat
  2017-03-23 13:02 ` Sébastien Hinderer
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: paul.lachat @ 2017-03-23  9:37 UTC (permalink / raw)
  To: caml-list

[-- Attachment #1: Type: text/plain, Size: 1623 bytes --]

Hello, 

I need to find a way to put Ocaml program in memory so I could interact with the program 
(call function, get result, find information about the variables, ...) without always reading the file. 

That what append when we use the directive #use "file.ml";; in the interactive shell (the toplevel, when you type the command ocaml in a shell). 

The instruction need to come from a Matlab function. So, I was thinking to create a process who run the ocaml command, 
redirect his standard input in a named pipe, redirect his standard output in another named pipe, so I could send instructions and received responses. 

But when I send the first instruction (ex : #use "file.ml";;\n), the ocaml process send back the response and stop. 

____ 

file.ml : 
let x = 10;; 

____ 

"#use "file.ml";;\n" 
Matlab -- /tmp/pipe_in --> ocaml 

"val x : int = 10" 
Matlab <-- /tmp/pipe_out -- ocaml 
then ocaml stop... 

___ 


So I would like to know if you think it's a good solution and if it is, do someone know how could I make it work ? 

_ 

I've tried another solution. I use Unix.fork() and launch, in the son process, the ocaml command then 
I send instructions from the father process to the son process with anonym pipe (Unix.pipe()). 

But here I have trouble with blocking read, I send an instruction, read the answer but even if I've read all char of the answer, it's wait to read 
more but there is no more to read... 

I have tried to use Unix.set_nonblock() and catch EAGAIN, but then I don't get anything at all in the buffer given to Unix.read(). 

If someone could help, I would be grateful ! 
Lachat Paul 


[-- Attachment #2: Type: text/html, Size: 3602 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Caml-list] [Question] Loading .ml in memory to interact with them.
  2017-03-23  9:37 [Caml-list] [Question] Loading .ml in memory to interact with them paul.lachat
@ 2017-03-23 13:02 ` Sébastien Hinderer
  2017-03-23 13:26   ` paul.lachat
  2017-03-23 14:24 ` Evgeny Roubinchtein
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 10+ messages in thread
From: Sébastien Hinderer @ 2017-03-23 13:02 UTC (permalink / raw)
  To: caml-list

Dear Paul,

paul.lachat@edu.univ-fcomte.fr (2017/03/23 10:37 +0100):
> Hello, 
> 
> I need to find a way to put Ocaml program in memory so I could interact with the program 
> (call function, get result, find information about the variables, ...) without always reading the file. 
> 
> That what append when we use the directive #use "file.ml";; in the interactive shell (the toplevel, when you type the command ocaml in a shell). 
> 
> The instruction need to come from a Matlab function. So, I was thinking to create a process who run the ocaml command, 
> redirect his standard input in a named pipe, redirect his standard output in another named pipe, so I could send instructions and received responses. 
> 
> But when I send the first instruction (ex : #use "file.ml";;\n), the
> ocaml process send back the response and stop.

What do you mean by "stops"? Do you mean that it exits? That it does not
respond to further commands?

Does this happen when you run the process that calls the toplevel inside
of mathlab, or did you try all this outside of the mathlab context?

Sébastien.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Caml-list] [Question] Loading .ml in memory to interact with them.
  2017-03-23 13:02 ` Sébastien Hinderer
@ 2017-03-23 13:26   ` paul.lachat
  2017-03-23 13:41     ` Sébastien Hinderer
  0 siblings, 1 reply; 10+ messages in thread
From: paul.lachat @ 2017-03-23 13:26 UTC (permalink / raw)
  To: Sébastien Hinderer; +Cc: caml-list

> What do you mean by "stops"? Do you mean that it exits?

The toplevel exit without error.

> Does this happen when you run the process that calls the toplevel inside
> of mathlab, or did you try all this outside of the mathlab context?

I've run the process outside of Matlab.

I launch the toplevel in one shell : "ocaml < /tmp/pipe_in > /tmp/pipe_out"

In another shell : "printf "let x = 10;;\n" > /tmp/pipe_in"
                   then
                   "cat /tmp/pipe_out"

And after the cat command, the toplevel stop.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Caml-list] [Question] Loading .ml in memory to interact with them.
  2017-03-23 13:26   ` paul.lachat
@ 2017-03-23 13:41     ` Sébastien Hinderer
  2017-03-23 13:57       ` paul.lachat
  0 siblings, 1 reply; 10+ messages in thread
From: Sébastien Hinderer @ 2017-03-23 13:41 UTC (permalink / raw)
  To: caml-list

paul.lachat@edu.univ-fcomte.fr (2017/03/23 14:26 +0100):
> I've run the process outside of Matlab.
> 
> I launch the toplevel in one shell : "ocaml < /tmp/pipe_in > /tmp/pipe_out"
> 
> In another shell : "printf "let x = 10;;\n" > /tmp/pipe_in"
>                    then
>                    "cat /tmp/pipe_out"
> 
> And after the cat command, the toplevel stop.

I suspect it is because the toplevel's standard input gets an EOF.
Perhaps you could use a cat << EOF to write to it?
And also use tail -f to follow the toplevel's output as it gets updated?

hth,

Sébastien.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Caml-list] [Question] Loading .ml in memory to interact with them.
  2017-03-23 13:41     ` Sébastien Hinderer
@ 2017-03-23 13:57       ` paul.lachat
  0 siblings, 0 replies; 10+ messages in thread
From: paul.lachat @ 2017-03-23 13:57 UTC (permalink / raw)
  To: Sébastien Hinderer; +Cc: caml-list

I've tried :

In one shell :
ocaml < /tmp/pipe_in > /tmp/pipe_out

In another shell :

tail -f /tmp/pipe_out &

cat << EOF > /tmp/pipe_in
heredoc> 1+1;;
heredoc> let x = 10;;
heredoc> let y = 15;;
heredoc> x;;
heredoc> y;;
heredoc> EOF

(feedback of tail)

        OCaml version 4.03.0                                                 

# - : int = 2
# val x : int = 10
# val y : int = 15
# - : int = 10
# - : int = 15
# 

____

But that's not what I want.
I want to be able to have this kind of logic :

1- Launch the ocaml toplevel.

2- The toplevel wait an instruction.

3- Send one instruction.

4- Get the result of the instruction.

5- Go back to 2- until we send "#quit;;".

I know that when you type ctrl-d in the toplevel it stop.
And that ctrl-d is the end-of-file 'keystroke'.

But I would like, if possible, to have a persistant tolevel process running.
So when I load a file via the #use ".ml";; directive, I can after that, and at any time,
call function of the .ml and get the result display by the toplevel.

It would be better than always re-read the file to get the result of a function (for example).

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Caml-list] [Question] Loading .ml in memory to interact with them.
  2017-03-23  9:37 [Caml-list] [Question] Loading .ml in memory to interact with them paul.lachat
  2017-03-23 13:02 ` Sébastien Hinderer
@ 2017-03-23 14:24 ` Evgeny Roubinchtein
  2017-03-23 15:09 ` François Bobot
  2017-03-24  9:04 ` Kim Nguyễn
  3 siblings, 0 replies; 10+ messages in thread
From: Evgeny Roubinchtein @ 2017-03-23 14:24 UTC (permalink / raw)
  To: paul.lachat; +Cc: caml-list

[-- Attachment #1: Type: text/plain, Size: 3788 bytes --]

Just to be clear: does this need to work on Windows, or only on Unix-like
systems?  If it only needs to work under Unix, then your problem sounds to
me like a standard inter-process communication problem with the usual
solutions being to use a combination of pipe(), dup2(), and select() system
calls, and with the alternative solution being to use a pseudo-terminal.
Chapter 5 of "Unix System Programming in OCaml"
https://ocaml.github.io/ocamlunix/pipes.html should give you some guidance
on implementing the former solution.  If you want to use pseudo-terminals,
I don't know of a freely-available tutorial-style reference off the top of
my head.  "Advanced Programming in the Unix Environment" by late Richard
Stevens has had a chapter dedicated to pseudo-terminals since the first
edition of the book: perhaps your local library has a copy.  Failing that,
you could read Linux man page for pty(7), and follow the links to forkpty
and friends.  For example, you could start here:
http://man7.org/linux/man-pages/man7/pty.7.html.

The fact that you want to do all of this from Matlab is an extra challenge,
but I don't think it's an insurmountable challenge.  Even if Matlab doesn't
have the functions you need "out of the box", it is possible to extend
Matlab with C code, so you could implement a C function to initialize the
external process, and another function to send to the external process and
receive results.  The following is probably a good starting point for
learning how to extend Matlab with C/C++:
https://www.mathworks.com/help/matlab/call-mex-files-1.html.  I don't know
off the top of my head if Matlab already comes with sufficiently flexible
functionality for communicating with an external process: you could try
searching the documentation and/or engaging Mathworks technical support
(assuming your license comes with technical support) and/or asking on
Mathworks forums.

-- 
Best of luck
Zhenya

On Thu, Mar 23, 2017 at 5:37 AM, <paul.lachat@edu.univ-fcomte.fr> wrote:

> Hello,
>
> I need to find a way to put Ocaml program in memory so I could interact
> with the program
> (call function, get result, find information about the variables, ...)
> without always reading the file.
>
> That what append when we use the directive #use "file.ml";; in the
> interactive shell (the toplevel, when you type the command ocaml in a
> shell).
>
> The instruction need to come from a Matlab function. So, I was thinking to
> create a process who run the ocaml command,
> redirect his standard input in a named pipe, redirect his standard output
> in another named pipe, so I could send instructions and received responses.
>
> But when I send the first instruction (ex : #use "file.ml";;\n), the
> ocaml process send back the response and stop.
>
> ____
>
> file.ml :
> let x = 10;;
>
> ____
>
>                    "#use "file.ml";;\n"
> Matlab --   /tmp/pipe_in  -->   ocaml
>
>                    "val x : int = 10"
> Matlab <-- /tmp/pipe_out --    ocaml
>                                                   then ocaml stop...
>
> ___
>
>
> So I would like to know if you think it's a good solution and if it is, do
> someone know how could I make it work ?
>
> _
>
> I've tried another solution. I use Unix.fork() and launch, in the son
> process, the ocaml command then
> I send instructions from the father process to the son process with anonym
> pipe (Unix.pipe()).
>
> But here I have trouble with blocking read, I send an instruction, read
> the answer but even if I've read all char of the answer, it's wait to read
> more but there is no more to read...
>
> I have tried to use Unix.set_nonblock() and catch EAGAIN, but then I don't
> get anything at all in the buffer given to Unix.read().
>
> If someone could help, I would be grateful !
> Lachat Paul
>
>

[-- Attachment #2: Type: text/html, Size: 5373 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Caml-list] [Question] Loading .ml in memory to interact with them.
  2017-03-23  9:37 [Caml-list] [Question] Loading .ml in memory to interact with them paul.lachat
  2017-03-23 13:02 ` Sébastien Hinderer
  2017-03-23 14:24 ` Evgeny Roubinchtein
@ 2017-03-23 15:09 ` François Bobot
       [not found]   ` <CAGYXaSbcqNWcXe1MLm_YyS28N7ji3td=L_jFVv35=50oSxaUDQ@mail.gmail.com>
  2017-03-24  9:04 ` Kim Nguyễn
  3 siblings, 1 reply; 10+ messages in thread
From: François Bobot @ 2017-03-23 15:09 UTC (permalink / raw)
  To: caml-list

Le 23/03/2017 à 10:37, paul.lachat@edu.univ-fcomte.fr a écrit :
> I need to find a way to put Ocaml program in memory so I could interact with the program
> (call function, get result, find information about the variables, ...) without always reading the file.
>
> That what append when we use the directive #use "file.ml";; in the interactive shell (the toplevel,
> when you type the command ocaml in a shell).
>
> The instruction need to come from a Matlab function. So, I was thinking to create a process who run
> the ocaml command,
> redirect his standard input in a named pipe, redirect his standard output in another named pipe, so
> I could send instructions and received responses.

You can also try to embed the ocaml interpreter inside the Matlab process directly. The ocaml 
compilers libs gives an easy way to control the interpreter: call function, get result, find 
information about the variables, ... . I imagine you could connect it t matlab with a C-binding.

Best,

-- 
François

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Caml-list] [Question] Loading .ml in memory to interact with them.
       [not found]   ` <CAGYXaSbcqNWcXe1MLm_YyS28N7ji3td=L_jFVv35=50oSxaUDQ@mail.gmail.com>
@ 2017-03-23 15:50     ` François Bobot
  0 siblings, 0 replies; 10+ messages in thread
From: François Bobot @ 2017-03-23 15:50 UTC (permalink / raw)
  To: Evgeny Roubinchtein; +Cc: OCaml Mailing List

Le 23/03/2017 à 16:32, Evgeny Roubinchtein a écrit :
> (Nitpick warning)
> Does OCaml have an interpreter? I thought it compiles OCaml code to either byte code or native code,
> and then byte code gets executed by the byte code interpreter.  However, if one wishes to write
> OCaml code, then the byte code interpreter, in and of itself, is not enough.
>

Yes indeed I wanted to say, to embed the OCaml interactive toplevel.

-- 
François


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Caml-list] [Question] Loading .ml in memory to interact with them.
  2017-03-23  9:37 [Caml-list] [Question] Loading .ml in memory to interact with them paul.lachat
                   ` (2 preceding siblings ...)
  2017-03-23 15:09 ` François Bobot
@ 2017-03-24  9:04 ` Kim Nguyễn
  3 siblings, 0 replies; 10+ messages in thread
From: Kim Nguyễn @ 2017-03-24  9:04 UTC (permalink / raw)
  To: paul.lachat; +Cc: caml-list

On Thu, Mar 23, 2017 at 10:37 AM,  <paul.lachat@edu.univ-fcomte.fr> wrote:
> Hello,
>
>
> But when I send the first instruction (ex : #use "file.ml";;\n), the ocaml
> process send back the response and stop.
>

The problem here is that echo (or printf) closes the pipe_in fifo,
hence sending EOF to the ocaml toplevel. You need to force the fifo to
somehow remain open.

tail -f /tmp/pipe_in | ocaml > /tmp/pipe_out

in another terminal, echo to /tmp/pipe_in, and tail -f /tmp/pipe_out
to see the result.

Or a small ocaml program that open_out /tmp/pipe_in and copies its
standard input without closing /tmp/pipe_in (but flushing it
explicitely to be sure each line is sent as soon as possible) :

let () =
  let oc = open_out "/tmp/pipe_in" in
  while true do
    let s = read_line () in
    output_string oc s;
    output_char oc '\n';
    flush oc
  done

(catch exceptions where appropriate !).



Hope this helps,

-- 
Kim

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Caml-list] [Question] Loading .ml in memory to interact with them.
@ 2017-03-24 14:43 Oleg
  0 siblings, 0 replies; 10+ messages in thread
From: Oleg @ 2017-03-24 14:43 UTC (permalink / raw)
  To: paul.lachat, caml-list, Kim.Nguyen


> The problem here is that echo (or printf) closes the pipe_in fifo,
> hence sending EOF to the ocaml toplevel. You need to force the fifo to
> somehow remain open.

Eons ago, back in the last century, I wrote a simple tool for that task
        http://okmij.org/ftp/Communications.html#sh-agents
to script almost anything from really anything. I used it to drive
Mathematica (on a remote machine) from Emacs and database CLI tools.

(I just realized it has been 20 years...)

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2017-03-24 14:42 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-23  9:37 [Caml-list] [Question] Loading .ml in memory to interact with them paul.lachat
2017-03-23 13:02 ` Sébastien Hinderer
2017-03-23 13:26   ` paul.lachat
2017-03-23 13:41     ` Sébastien Hinderer
2017-03-23 13:57       ` paul.lachat
2017-03-23 14:24 ` Evgeny Roubinchtein
2017-03-23 15:09 ` François Bobot
     [not found]   ` <CAGYXaSbcqNWcXe1MLm_YyS28N7ji3td=L_jFVv35=50oSxaUDQ@mail.gmail.com>
2017-03-23 15:50     ` François Bobot
2017-03-24  9:04 ` Kim Nguyễn
2017-03-24 14:43 Oleg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).