Arc Forumnew | comments | leaders | submitlogin
2 points by waterhouse 5082 days ago | link | parent

Occasionally I have found the following method useful:

1. Have the Arc process running something like this:

  (while t
    (sleep .2)
    (awhen (car:errsafe:readfile "ARC_ORDERS")
      (pr "Input> ")
      write.it
      (prn)
      (rmfile "ARC_ORDERS")
      (write:eval it)
      (prn)))
2. When you want Arc to do something, write an Arc s-expression to the ARC_ORDERS file. (Note that you'll have to restart this pseudo-REPL if an error occurs; you could use something like 'on-err or 'after to make that happen.)

This might be a horrible hack, but it's awesome, and it presents a very easy interface--e.g. if you have a program that lets you bind keys to shell scripts, then you can have a shell script say, like, "echo '(do-this-stuff)' > ARC_ORDERS".

Obvious drawbacks: It's slow compared to, say, a function call from the Arc runtime (you wouldn't want to use this as your graphics backend), and if two or more programs try to use this interface, hell might ensue (though you could assign them their own individual ARC_ORDERS2 and so on files; you could even make the number be a process id if you wanted). But it'll work fine for certain applications, and you may find it useful.



2 points by shader 5082 days ago | link

This is so similar in concept to what I'm doing with named pipes that I figured I ought to share it now:

First of all, you can create a named pipe in a directory with the command "mkfifo name".

Then, I have a shell script in mzscheme (should probably update to Racket soon) for launching arc that sets up the long running process with normal output redirected to a log file and a second repl redirected to two named pipes "in" and "out". The important part is

  (parameterize ((current-output-port (open-output-file "out" 'update))
                 (current-input-port (open-input-file "in"))
                 (current-error-port (current-output-port)))
                (file-stream-buffer-mode (current-output-port) 'none)
                (tl))
which could be written either in arc or Racket. In arc, it would probably be:

  (w/stdin (infile "in")
    (w/stdout (outfile "out")
      ($:tl)))    ;whatever method you use to get to racket and call the repl
I'm not sure if that would work as well, since as far as I know there is no method in arc for setting the filestream buffer mode to 'none. If you have any issues, just use the racket version above.

Anyway, once you have the pipes set up, you can echo and cat them like any other file. The main difference being that they are treated exactly like a normal repl, and shouldn't have the overhead of sleeping and reading/erasing a file. I use a shell script to connect to them as a repl most of the time:

  #! /bin/bash
  
  bash -c "cat <out &
  cat >in"
Pretty simple, and it gets the job done.

-----