New favorite tool 😍

  • Euro@programming.dev
    link
    fedilink
    arrow-up
    0
    ·
    edit-2
    3 months ago

    As someone who has done way too much shell scripting, the example on their website just looks bad if i’m being honest.

    I wrote a simple test script that compares the example output from this script to how i would write the same if statement but with pure bash.

    here’s the script:

    #!/bin/bash
    
    age=3
    
    [ "$(printf "%s < 18\n" "$age" | bc -l | sed '/\./ s/\.\{0,1\} 0\{1,\}$//')" != 0  ] && echo hi
    
    # (( "$age" < 18 )) && echo hi
    

    Comment out the line you dont want to test then run hyperfine ./script

    I found that using the amber version takes ~2ms per run while my version takes 800microseconds, meaning the amber version is about twice as slow.

    The reason the amber version is so slow is because: a) it uses 4 subshells, (3 for the pipes, and 1 for the $() syntax) b) it uses external programs (bc, sed) as opposed to using builtins (such as the (( )), [[ ]], or [ ] builtins)

    I decided to download amber and try out some programs myself.

    I wrote this simple amber program

    let x = [1, 2, 3, 4]
    echo x[0]
    

    it compiled to:

    __AMBER_ARRAY_0=(1 2 3 4);
    __0_x=("${__AMBER_ARRAY_0[@]}");
    echo "${__0_x[0]}"
    

    and i actually facepalmed because instead of directly accessing the first item, it first creates a new array then accesses the first item in that array, maybe there’s a reason for this, but i don’t know what that reason would be.

    I decided to modify this script a little into:

    __AMBER_ARRAY_0=($(seq 1 1000));
    __0_x=("${__AMBER_ARRAY_0[@]}");
    echo "${__0_x[0]}"
    

    so now we have 1000 items in our array, I bench marked this, and a version where it doesn’t create a new array. not creating a new array is 600ms faster (1.7ms for the amber version, 1.1ms for my version).

    I wrote another simple amber program that sums the items in a list

    let items = [1, 2, 3, 10]
    let x = 0
    loop i in items {
        x += i
    }
    
    echo x
    

    which compiles to

    __AMBER_ARRAY_0=(1 2 3 10);
    __0_items=("${__AMBER_ARRAY_0[@]}");
    __1_x=0;
    for i in "${__0_items[@]}"
    do
        __1_x=$(echo ${__1_x} '+' ${i} | bc -l | sed '/\./ s/\.\{0,1\}0\{1,\}$//')
    done;
    echo ${__1_x}
    

    This compiled version takes about 5.7ms to run, so i wrote my version

    arr=(1 2 3 10)
    x=0
    for i in "${arr[@]}"; do
        x=$((x+${arr[i]}))
    done
    printf "%s\n" "$x"
    

    This version takes about 900 microseconds to run, making the amber version about 5.7x slower.

    Amber does support 1 thing that bash doesn’t though (which is probably the cause for making all these slow versions of stuff), it supports float arithmetic, which is pretty cool. However if I’m being honest I rarely use float arithmetic in bash, and when i do i just call out to bc which is good enough. (and which is what amber does, but also for integers)

    I dont get the point of this language, in my opinion there are only a couple of reasons that bash should be chosen for something a) if you’re just gonna hack some short script together quickly. or b) something that uses lots of external programs, such as a build or install script.

    for the latter case, amber might be useful, but it will make your install/build script hard to read and slower.

    Lastly, I don’t think amber will make anything easier until they have a standard library of functions.

    The power of bash comes from the fact that it’s easy to pipe text from one text manipulation tool to another, the difficulty comes from learning how each of those individual tools works, and how to chain them together effectively. Until amber has a good standard library, with good data/text manipulation tools, amber doesn’t solve that.

    • jack@monero.town
      link
      fedilink
      arrow-up
      0
      ·
      edit-2
      3 months ago

      There is no sh shell. /bin/sh is just a symlink to bash or dash or zsh etc.

      But yes, the question is valid why it compiles specifically to bash and not something posix-compliant

        • jack@monero.town
          link
          fedilink
          arrow-up
          0
          ·
          edit-2
          3 months ago

          Yes, there was the bourne sh on Unix but I don’t see how that’s relevant here. We’re talking about operating systems in use. Please explain the downvotes

          • BatmanAoD@programming.dev
            link
            fedilink
            arrow-up
            0
            ·
            3 months ago

            It’s relevant because there are still platforms that don’t have actual Bash (e.g. containers using Busybox).

            sh is not just a symlink: when invoked using the symlink, the target binary must run in POSIX compliant mode. So it’s effectively a sub-dialect.

            Amber compiles to a language, not to a binary. So “why doesn’t it compile to sh” is a perfectly reasonable question, and refers to the POSIX shell dialect, not to the /bin/sh symlink itself.

  • yetAnotherUser@lemmy.ca
    link
    fedilink
    arrow-up
    0
    ·
    3 months ago

    I checked the docs, and I’m a bit confused with one thing. They show that you can capture the stdout of a command into a variabe, but they never show stderr being captured. How would that work?

    • syd@lemy.lolOP
      link
      fedilink
      arrow-up
      0
      ·
      3 months ago

      Like this: ‘’’ $mv file.txt dest.txt$ failed { echo “It seems that the file.txt does not exist” } ‘’’

      • yetAnotherUser@lemmy.ca
        link
        fedilink
        arrow-up
        0
        ·
        3 months ago

        Knowing if a command failed and capturing stderr (which contains stuff like error messages) are not the same thing.

  • ReluctantMuskrat@lemmy.world
    link
    fedilink
    arrow-up
    0
    ·
    3 months ago

    As a long-time bash, awk and sed scripter who knows he’ll probably get downvoted into oblivion for this my recommendation: learn PowerShell

    It’s open-source and completely cross-platform - I use it on Macs, Linux and Windows machines - and you don’t know what you’re missing until you try a fully objected-oriented scripting language and shell. No more parsing text, built-in support for scalars, arrays, hash maps/associative arrays, and more complex types like version numbers, IP addresses, synchronized dictionaries and basically anything available in .Net. Read and write csv, json and xml natively and simply. Built-in support for regular expressions throughout, web service calls, remote script execution, and parallel and asynchronous jobs and lots and lots of libraries for all kinds of things.

    Seriously, I know its popular and often-deserved to hate on Microsoft but PowerShell is a kick-ass, cross-platform, open-source, modern shell done right, even if it does have a dumb name imo. Once you start learning it you won’t want to go back to any other.

  • zygo_histo_morpheus@programming.dev
    link
    fedilink
    arrow-up
    0
    ·
    3 months ago

    Looking at the example

    Why does the generated bash look like that? Is this more safe somehow than a more straighforward bash if or does it just generate needlessly complicated bash?