Stream: beginners

Topic: Processing output in a CLI tool


view this post on Zulip Ostar (Aug 25 2024 at 05:19):

Hi folks,

I want to write a CLI tool, something I'd normally write in Bash.

Here is a simple example of what I'd do in Bash (I don't want to write a Git CLI too but I use it as an example since we all have Git installed):

if out=$(git init foobar); then
    if [[ ${out} =~ ^Initialized\ empty\ Git\ repository\ in\ (.+)$ ]]; then
        echo "ok: absolute path of a new empty repo is: ${BASH_REMATCH[1]}"
    elif [[ ${out} =~ ^Reinitialized\ existing\ Git\ repository\ in\ (.+)$ ]]; then
        echo "ok: absolute path of a reinitialized repo is: ${BASH_REMATCH[1]}"
    else
        echo "error: unexpected out: ${out}"
    fi
else
    echo error
fi

Obviously, I can come up with more complicated examples with multiple matching groups, etc.

As far as I can see, Roc doesn't have Regex matching. Could you please tell me how you'd do that?

Thank you!

view this post on Zulip Brendan Hansknecht (Aug 25 2024 at 05:34):

We've talked about having a syntax for simple string matching like this, but it doesn't exist today sadly.

In this specific case, I would probably split by spaces and then use list pattern matching.

when Str.split out " " is
    ["Initialized", "empty", "Git", "repository", "in", dir] ->
        Stdout.line! "ok: absolute path of a new empty repo is: $(dir)"
    ["Reinitialized", "empty", "Git", "repository", "in", dir] ->
        Stdout.line! "ok: absolute path of a reinitialized repo is: $(dir)"
    _ ->
        Stdout.line! "error: unexpected out: $(out)"

view this post on Zulip Brendan Hansknecht (Aug 25 2024 at 05:35):

There are also some parser combinator libraries that people have written, but I tend to essentially always roll my own direct parsing code for things like this.

view this post on Zulip Ostar (Aug 25 2024 at 16:58):

Thank you!

The Str.split out is a good option for example like this. The only change I'd make is to move the pattern matching into a separate (pure, not Task, easy to test) function.

I've never used parser combinators (just looking on Wikipedia now), could you please point me to a Roc parser combinator library?

Is Regex on a road map? Or maybe has anybody tried to write Regex matcher in Roc as a library?

view this post on Zulip Brendan Hansknecht (Aug 25 2024 at 17:44):

The only change I'd make is to move the pattern matching into a separate (pure, not Task, easy to test) function.

Sure, that can be done. Depends if you are working on a quick script or something large that you want more testable.

could you please point me to a Roc parser combinator library?

I think this: https://github.com/lukewilliamboswell/roc-parser

Is Regex on a road map?

No. I don't expect Regex to ever be in the roc standard library.

Or maybe has anybody tried to write Regex matcher in Roc as a library?

Not that I know of. Generally people are pushed towards parser combinators or manual parsers. They are generally consider a lot safer and cleaner than regex even if they are more lines of code. That said, someone totally could implement regex support in a package or platform.

view this post on Zulip Ostar (Aug 26 2024 at 07:47):

No. I don't expect Regex to ever be in the roc standard library.

Generally people are pushed towards parser combinators or manual parsers.

Thank you. That's good to know, so I should look for other options.

I think this: https://github.com/lukewilliamboswell/roc-parser

That's great, thank you!

view this post on Zulip Notification Bot (Aug 27 2024 at 18:41):

47 messages were moved from this topic to #beginners > number ranges without heap allocations by Richard Feldman.


Last updated: Jul 06 2025 at 12:14 UTC