1. 31
  1.  

  2. 6

    The paper for Rash, a shell scripting DSL for Racket lists a few libraries of interest:

    1. 1

      I’ve always been ambivalent about fish, zsh and other shells but I could see myself using rash as my system shell and turtle also looks incredibly useful for nix-shell scripts.

    2. 4

      Due to increased focus on automation of host management, and the prominent role that shell scripting plays in it – we are seeing more and more innovation in that area (and criticism of current shell scripting as inadequate, is growing).

      There are seem to be at least 4 approaches to the above:

      • assume that bash is a ‘low-level’ interpreter, that runs ‘everywhere’. Build an existing programming language on top of that interpreter. Example: https://github.com/chr15m/flk. (perhaps extends this to other shell script languages to hide the difference from the language user).

      • use existing programming language syntax construct (may be even leveraging a parser-combinator for a particular language), to wrap shell script invocations. I think Janet’s approach noted in the article, is of this sort. And all the other examples as listed by seschwar: https://lobste.rs/s/p6insb/dsl_for_shell_scripting#c_2yudqt

      • Use some form of declarative language that deals with: versioned configuration model, declarative execution model, and some form of conditional processing. Example of this Dhall ( https://dhall-lang.org/ ), and to a much lesser degree, Ansible.

      • Rewrite all of the underlying commands to be ‘chaining compatible’ through a uniformly modeled result returns (eg PowerShell)

      Not sure if there are more categories, but I think bash is not going to be as prominent as it was last 20-30 years.

      It would be interesting to see if any of the major Linux distros and BSDs adapt a uniform approach to minimizing prevalence of bash,sh, etc for host management automation. If they do, perhaps we will see a replacement emerging sooner rather than later.

      1. 4

        It could easily be turned into an R7RS library.

        1. 1

          Nice, I’m personally hoping for versions in other lisps as well as nim and rust :P.

        2. 2

          I can’t help but agree with all of this. I’m disappointed when languages:

          • have worse composability than the shell
          • have okay composability, but separate from the rest of the OS-as-an-ecosystem.

          I’ve been mulling over the idea in my head about an ML-style lang that can unify some of these ideas– seamlessly composing (non-pure) functions along with external programs.

          Heck, if you bend the definition of some of the operators enough, there could be a DSL that is almost if not 100% compatible with POSIX sh. Or, the language itself, even.

          1. 2

            The pipe syntax kind of drives me crazy, but this might just be common-lisp::loop all over again ;)

            (with [out (file/open "some/path" :wb)]
              (sh/$ find ,dir | sort | uniq | gzip > ,out))
            

            could have been something like:

            (with [out (file/open "some/path" :wb)]
              (sh/>> out
                (sh/pipe
                  (sh/$ find ,dir)
                  (sh/$ sort)
                  (sh/$ uniq)
                  (sh/$ gzip))))
            

            which is composable with something like (sorry, not familiar with janet yet):

            (with [out (file/open "some/path" :wb)]
              (sh/>> out
                (sh/pipe
                  (sh/$ find ,dir)
                  (lambda (fd)
                    (map println
                      (sort (readlines fd))))
                  (sh/$ uniq)
                  (sh/$ gzip))))
            
            1. 1

              Not a bad idea,though your lambda example could just as easily be done:

              (sh/$ ls | (fn [] ...) | uniq)
              

              Which I may add.

              Overall my idea was for a shorthand, not something longer than shell which is why I didn’t go this route.

            2. 2

              not a criticism of this article (which is completely valid), but generally: am i alone with the opinion that a “DSL” should be an own language (aka with-a-parser of some sort), not clever application of $languages idioms? e.g. troffs eqn is a DSL or the c preprocessor is a DSL, being de-coupled from the respective parent languages.

              1. 3

                I think the context matters. Here the goal was a library for a language, so it made sense this way to me.

                1. 1

                  It makes perfect sense to talk about a DSL that is a subset of another language rather than an independent language that has an interpreter only used for that language.

                  For example, Ruby is known for its ability to make DSLs, which have often been used in system administration (Puppet, Chef, Homebrew).

                  Edit: here’s a Python DSL for drawing system architecture diagrams I came across today.

                2. 1

                  find “$DIR” | sort | uniq | gzip > “$out”

                  Go and Python:

                  Excercise for the reader ;)

                  I find this example rather unconvincing. A large part of shell scripts is usually file and string processing. And while shell scripts need to invoke external programs to accomplish these tasks most regular programming languages don’t. The above pipeline can be easily implemented directly in Python. The resulting program will certainly be more verbose, but it will also be easier to maintain and be less prone to errors from various shell quirks and corner cases.

                  1. 3

                    I don’t think it can be implemented in python (easily) in a way that runs with multiple processors or handles hundreds of gigabytes of data like coreutils can.

                    I would love to see it though.