Write CLI scripts in Elm (IO Monad)

This project is an attempt to simplify writing simple tools and CLI scripts in pure Elm by allowing you to write monadic IO programs instead of using Platform.worker, ports and The Elm Architecture.

I am curious if anyone finds this useful and would like to give some feedback on the ideas outlined in the readme or the API specified the package docs. At this point, this is mostly a proof of concept but it works.

32 Likes

Wow, didn’t know this was possible. From that perspective it’s already an eye opener.

Alas, doesn’t currently work on Mac OS. (Error log below). But this is fascinating idea. Anxious to try it out again later.

➜  elm npm install -g albertdahlin/elm-posix
npm ERR! code ENOENT
npm ERR! syscall open
npm ERR! path /Users/carlson/.npm/_cacache/tmp/git-clone-8c226782/package.json
npm ERR! errno -2
npm ERR! enoent ENOENT: no such file or directory, open '/Users/carlson/.npm/_cacache/tmp/git-clone-8c226782/package.json'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/carlson/.npm/_logs/2021-07-13T22_43_55_479Z-debug.log

This looks like a completely different issue, not related to Mac.

I haven’t published it to npm yet, that’s probably why you get that error. If you want to try it locally meanwhile, you can clone the repo and use

~/path-to-elm-posix/shell/elm-cli src/MyElmFile.elm

Maybe I should publish it even if it is not complete?

Tag it as alpha or beta:

Love it! Will use it for my next script. For readability and understandability it would be nice though if it could be prevented to have these <| \_ -> in there.

I have published this now to make it easier to test. See the readme for installation instructions.

You are referring in the examples?

Yes, indeed.

Yes, I got it to install today (Yay!). But now I get the below. (I copies your HelloUser example).

➜  posix elm-cli make src/HelloUser.elm dest/helloUser.js
-- TYPE MISMATCH - /var/folders/ml/vl09g4313rb1jd6y9zvcd6200000gn/T/elm-cli-2643.elm

The 1st argument to `program` is not what I expect:

20|     IO.program Cli.program recv send
                   ^^^^^^^^^^^
This `program` value is a:

    IO.PosixProgram

But `program` needs the 1st argument to be:

    IO.Process -> IO.IO ()

Sorry for that, I have updated some things before I published to npm to simplify the API. The examples in my repo also are updated, see this diff.

I tried both the HelloUser and the ReadFile examples. Worked perfectly. Bravo!! Am looking forward to studying your code to see how you did this.

Nice work :+1: . Would love to see this evolve into something bigger.

This is very cool!
I would have thought you need your own custom compiler to make this work :exploding_head:

Just out of curiosity … this is still javascript compiled by Elm, but it can run outside of the browser and perform some I/O operations?

This is really neat!

@Donn it looks like elm-cli node application acts as a little platform for running Process -> IO () elm functions. I think it’s taking the compiled elm code and then elm-cli sets up the ports to talk to node.

1 Like

Yes, that is correct. elm-cli basically does these steps:

  • Convert program : Process -> IO () to main : Program Flag Model Msg using Platform.worker with two ports, in and out
  • Compile using elm make
  • import the compiled Elm js file and start the Elm app
  • Attach ports to handle IO
5 Likes

I have started working on a new API for this package. The goal is to simplify and at the same time make it more extensible.

Here are some links if you want to check it out.

3 Likes

That was fast. Thanks.