• nested ternary discovery

    From Mike Sanders@porkchop@invalid.foo to comp.lang.awk on Thu Oct 9 11:27:09 2025
    From Newsgroup: comp.lang.awk

    Just discovered this, pretty nifty!

    nested ternary example:

    sound = "moo"

    mammal = (sound =="bark") ? "dog" :
    (sound =="meow") ? "cat" :
    (sound =="moo") ? "cow" :
    mammal # keep original if no match

    and for comparison the equivalent if/else block:

    sound = "moo"

    if (sound == "bark") {
    mammal = "dog"
    } else if (sound == "meow") {
    mammal = "cat"
    } else if (sound == "moo") {
    mammal = "cow"
    } else {
    mammal = mammal # keep original if no match
    }

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.lang.awk on Thu Oct 9 17:09:13 2025
    From Newsgroup: comp.lang.awk

    On 09.10.2025 13:27, Mike Sanders wrote:
    Just discovered this, pretty nifty!

    nested ternary example:

    (Let's call it "cascaded". Nested conditionals would in the general
    case - where you'd have another level of conditionals between the
    '?' and ':' - look even more complex and be much less readable, in
    both variants, conditional statements and conditional expressions.)


    sound = "moo"

    mammal = (sound =="bark") ? "dog" :
    (sound =="meow") ? "cat" :
    (sound =="moo") ? "cow" :
    mammal # keep original if no match

    Hmm.. - what specifically are you astonished about? The conditional
    expression per se, or that cascading is not explicitly forbidden?

    That should be standard in all the "C"-like languages' with ternary
    conditional expressions.


    and for comparison the equivalent if/else block:

    sound = "moo"

    if (sound == "bark") {
    mammal = "dog"
    } else if (sound == "meow") {
    mammal = "cat"
    } else if (sound == "moo") {
    mammal = "cow"
    } else {
    mammal = mammal # keep original if no match
    }


    "Ternaries" (conditional expressions) are certainly very useful!
    And they can increase readability (per se, and in cascaded form).

    But I'm not sure what the goal of your comparison was; if it's the
    terse expression then you should rather compare the ternary with
    the statement construct without the spurious braces and 'else' part

    if (sound == "bark")
    mammal = "dog"
    else if (sound == "meow")
    mammal = "cat"
    else if (sound == "moo")
    mammal = "cow"

    and note that the statement-cascades need no final else block where
    the nested ternary expression needs one to be complete.

    For "comparison" in Awk there should probably also be shown the
    awk-ish variant

    sound == "bark" { mammal = "dog" }
    sound == "meow" { mammal = "cat" }
    sound == "moo" { mammal = "cow" }

    Or, not exactly the same but often you compare against fields, here
    an example illustrated for $0

    /^bark$/ { mammal = "dog" }
    /^meow$/ { mammal = "cat" }
    /^moo$/ { mammal = "cow" }

    (Whether you want to use 'next' in the latter cases depends on the
    actual conditions in your application cases.)

    And if you're using GNU Awk there's the 'switch' statement available
    to not repeat the variable you compare against

    switch (sound) {
    case "bark": mammal = "dog"; break
    ...
    }

    I think "for comparison" all these options one has should be shown;
    all have their own pros and cons.

    (In case your astonishment is per se from the ternary already, note
    also that "C"/Awk's way isn't that "nifty" if compared to some other
    languages' conditional expressions.[*])

    (That got longer than intended, but for a "comparison" necessary.)

    Janis

    [*] Compare that to Algol 68. There's no difference whether you have conditionals in "statement" or "expression" constructs, and you can
    also have it on both sides of assignments, and you can choose between
    the abbreviated or verbose form.

    IF sound = "bark" THEN mammal := "dog"
    ELIF sound = "meow" THEN mammal := "cat"
    ELIF sound = "moo" THEN mammal := "cow"
    FI

    mammal := IF sound = "bark" THEN "dog"
    ELIF sound = "meow" THEN "cat"
    ELIF sound = "moo" THEN "cow"
    ELSE mammal
    FI

    ( sound = "bark" | mammal := "dog" |:
    sound = "meow" | mammal := "cat" |:
    sound = "moo" | mammal := "cow" )

    mammal := ( sound = "bark" | "dog" |:
    sound = "meow" | "cat" |:
    sound = "moo" | "cow" | mammal )

    The expression variants need a final 'else' only if you want to keep
    the previous variable contents if nothing matches. Otherwise, as is
    often the case (if you want it empty) you'd of course simply write

    mammal := ( sound = "bark" | "dog" |:
    sound = "meow" | "cat" |:
    sound = "moo" | "cow" )


    And one example for conditionals on the left hand side

    ( amount < 0 | losses | gains ) +:= amount

    and this is also possible in the syntactical variant with 'IF'.

    For "nested" forms - note the distinction from "cascaded" on top
    of the post - you can also use both syntactical variants mixed
    for better readability; e.g. write the outer levels with 'IF' and
    inner levels with parenthesis. For example

    IF ... THEN
    ( ... | ... |: ... | ... )
    ELIF ... THEN
    ( ... | ... |: ... |: ... | ... )
    ELSE
    ( ... | ... | ... )
    FI

    (and compare that to a pure 'IF' based or a pure parenthesis based
    use).

    That's all "pretty nifty", isn't it? :-)

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Kaz Kylheku@643-408-1753@kylheku.com to comp.lang.awk on Thu Oct 9 16:59:11 2025
    From Newsgroup: comp.lang.awk

    On 2025-10-09, Mike Sanders <porkchop@invalid.foo> wrote:
    Just discovered this, pretty nifty!

    nested ternary example:

    sound = "moo"

    mammal = (sound =="bark") ? "dog" :
    (sound =="meow") ? "cat" :
    (sound =="moo") ? "cow" :
    mammal # keep original if no match

    In GNU Awk you have a switch statement.

    In cppawk, there is a case statement which compiles to GNU Awk switch or portably.


    $ cat case.awk
    #include <case.h>

    {
    case ($0) {
    of ("woof", "bark")
    print "dog"
    cbreak
    matching (/mee*oo*w/, /purr*/)
    print "cat"
    cbreak
    of ("moo")
    print "cow"
    cbreak
    otherwise
    print "unknown beast"
    cbreak
    }
    }
    $ cppawk -f case.awk
    bark
    dog
    woof
    dog
    meeeeow
    cat
    moo
    cow
    purrrrrrr
    cat

    Cases use the "of" or "matching" keywords for exact strings or regexes. Each can
    have multiple arguments.

    Each case must end with cbreak (intentional termios/curses pun), cfall
    for fall-thrugh or cret(arg)/creturn(arg) to return out of the function.

    There is no implicit fallthrough.

    Code generated for gawk (default):

    $ cppawk --prepro-only -f case.awk
    # 1 "<stdin>"
    # 1 "<built-in>"
    # 1 "<command-line>"
    # 1 "/usr/include/stdc-predef.h" 1 3 4
    # 1 "<command-line>" 2
    # 1 "<stdin>"
    # 1 "case.awk"
    # 1 "/home/kaz/bin/cppawk-include/case.h" 1
    # 32 "/home/kaz/bin/cppawk-include/case.h"
    # 1 "/home/kaz/bin/cppawk-include/case-priv.h" 1
    # 32 "/home/kaz/bin/cppawk-include/case-priv.h"
    # 1 "/home/kaz/bin/cppawk-include/narg-priv.h" 1
    # 32 "/home/kaz/bin/cppawk-include/narg-priv.h"
    # 1 "/home/kaz/bin/cppawk-include/base.h" 1
    # 33 "/home/kaz/bin/cppawk-include/narg-priv.h" 2
    # 33 "/home/kaz/bin/cppawk-include/case-priv.h" 2
    # 33 "/home/kaz/bin/cppawk-include/case.h" 2
    # 2 "case.awk" 2

    {
    switch ($0) {
    case "woof": case "bark": {{{
    print "dog"
    break; }}}
    case/mee*oo*w/: case /purr*/: {{{
    print "cat"
    break; }}}
    case "moo": {{{
    print "cow"
    break; }}}
    default: {{{
    print "unknown beast"
    break; }}}
    }
    }

    Code generated for awk with no switch, like mawk:

    $ cppawk --awk=mawk --prepro-only -f case.awk
    # 1 "<stdin>"
    # 1 "<built-in>"
    # 1 "<command-line>"
    # 1 "/usr/include/stdc-predef.h" 1 3 4
    # 1 "<command-line>" 2
    # 1 "<stdin>"
    # 1 "case.awk"
    # 1 "/home/kaz/bin/cppawk-include/case.h" 1
    # 32 "/home/kaz/bin/cppawk-include/case.h"
    # 1 "/home/kaz/bin/cppawk-include/case-priv.h" 1
    # 32 "/home/kaz/bin/cppawk-include/case-priv.h"
    # 1 "/home/kaz/bin/cppawk-include/narg-priv.h" 1
    # 32 "/home/kaz/bin/cppawk-include/narg-priv.h"
    # 1 "/home/kaz/bin/cppawk-include/base.h" 1
    # 33 "/home/kaz/bin/cppawk-include/narg-priv.h" 2
    # 33 "/home/kaz/bin/cppawk-include/case-priv.h" 2
    # 33 "/home/kaz/bin/cppawk-include/case.h" 2
    # 2 "case.awk" 2

    {
    for ((__once = 1) && (__pass = 0) || (__val = $0); __once; __once = 0) {
    if (__pass || ((__val == ("woof")) || (__val == ("bark"))) && (__pass = 1)) {{{
    print "dog"
    break; }}}
    if (__pass || ((__val ~ (/mee*oo*w/)) || (__val ~ (/purr*/))) && (__pass = 1)) {{{
    print "cat"
    break; }}}
    if (__pass || ((__val == ("moo"))) && (__pass = 1)) {{{
    print "cow"
    break; }}}
    if (__pass = 1) {{{
    print "unknown beast"
    break; }}}
    }
    }
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From mack@mack@the-knife.org (Mack The Knife) to comp.lang.awk on Fri Oct 10 08:10:56 2025
    From Newsgroup: comp.lang.awk

    In article <10c866d$2lhr4$1@dont-email.me>,
    Mike Sanders <porkchop@invalid.foo> wrote:
    Just discovered this, pretty nifty!

    nested ternary example:

    sound = "moo"

    mammal = (sound =="bark") ? "dog" :
    (sound =="meow") ? "cat" :
    (sound =="moo") ? "cow" :
    mammal # keep original if no match

    This is where associative arrays shine:

    BEGIN {
    annimal["bark"] = "dog"
    annimal["meow"] = "cat"
    annimal["moo"] = "cow"
    # etc. ...
    }
    { print animal[$1] }

    Much simpler, and each additional sound/animal pair requires
    only one additional line of code.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.lang.awk on Fri Oct 10 13:06:04 2025
    From Newsgroup: comp.lang.awk

    On 10.10.2025 10:10, Mack The Knife wrote:
    In article <10c866d$2lhr4$1@dont-email.me>,
    Mike Sanders <porkchop@invalid.foo> wrote:
    Just discovered this, pretty nifty!

    nested ternary example:

    sound = "moo"

    mammal = (sound =="bark") ? "dog" :
    (sound =="meow") ? "cat" :
    (sound =="moo") ? "cow" :
    mammal # keep original if no match

    This is where associative arrays shine:

    Indeed! - But don't withhold (or forget) the necessary test and
    assignment to match the OP's example...


    BEGIN {
    animal["bark"] = "dog"
    animal["meow"] = "cat"
    animal["moo"] = "cow"
    # etc. ...
    }

    sound in animal { mammal = animal[sound] }


    { print animal[$1] }

    Much simpler, and each additional sound/animal pair requires
    only one additional line of code.


    Janis

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Kaz Kylheku@643-408-1753@kylheku.com to comp.lang.awk on Fri Oct 10 17:04:53 2025
    From Newsgroup: comp.lang.awk

    On 2025-10-10, Mack The Knife <mack@the-knife.org> wrote:
    { print animal[$1] }

    Much simpler, and each additional sound/animal pair requires
    only one additional line of code.

    Without function indirection (Gawk extension), or an eval feature
    (doesn't exist in any Awk I know), you cannot dispatch actions, only
    substitute values for keys.
    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @Kazinator@mstdn.ca
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Mike Sanders@porkchop@invalid.foo to comp.lang.awk on Fri Oct 10 19:38:35 2025
    From Newsgroup: comp.lang.awk

    On Thu, 9 Oct 2025 17:09:13 +0200, Janis Papanagnou wrote:

    (Let's call it "cascaded". Nested conditionals would in the general
    case - where you'd have another level of conditionals between the
    '?' and ':' - look even more complex and be much less readable, in
    both variants, conditional statements and conditional expressions.)

    [...]


    Fuller reply coming soon (promise - I know I've had allot of hit
    & run posts lately..)

    And all you other folks too... excellent replies all of them.
    Appreciate you all allowing me to 'learn/think aloud'.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Mike Sanders@porkchop@invalid.foo to comp.lang.awk on Fri Oct 10 19:41:11 2025
    From Newsgroup: comp.lang.awk

    On 10 Oct 2025 08:10:56 GMT, Mack The Knife wrote:

    This is where associative arrays shine:

    BEGIN {
    annimal["bark"] = "dog"
    annimal["meow"] = "cat"
    annimal["moo"] = "cow"
    # etc. ...
    }
    { print animal[$1] }

    Much simpler, and each additional sound/animal pair requires
    only one additional line of code.

    Indeed, good point.


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Mike Sanders@porkchop@invalid.foo to comp.lang.awk on Sat Oct 11 11:46:38 2025
    From Newsgroup: comp.lang.awk

    On Thu, 9 Oct 2025 17:09:13 +0200, Janis Papanagnou wrote:

    (Let's call it "cascaded". Nested conditionals would in the general
    case - where you'd have another level of conditionals between the
    '?' and ':' - look even more complex and be much less readable, in
    both variants, conditional statements and conditional expressions.)

    'Cascaded' - nice & clear distinction.

    Hmm.. - what specifically are you astonished about? The conditional expression per se, or that cascading is not explicitly forbidden?

    Not astonished really. Actually I already knew ternary could be held
    within ternary but, somehow or another I thought it must be balanced,
    ternary in both branches (regardless of depth):

    x = (y > z) ? ternary-again : ternary-too

    vs a mix...

    x = (y > z) ? ternary-here : (a != b) ? c : ternary-default

    and note that the statement-cascades need no final else block where
    the nested ternary expression needs one to be complete.

    Yes, or put differently no final 'else'.

    For "comparison" in Awk there should probably also be shown the
    awk-ish variant

    sound == "bark" { mammal = "dog" }
    sound == "meow" { mammal = "cat" }
    sound == "moo" { mammal = "cow" }

    Or, not exactly the same but often you compare against fields, here
    an example illustrated for $0

    /^bark$/ { mammal = "dog" }
    /^meow$/ { mammal = "cat" }
    /^moo$/ { mammal = "cow" }

    More good examples.

    And if you're using GNU Awk there's the 'switch' statement available
    to not repeat the variable you compare against

    switch (sound) {
    case "bark": mammal = "dog"; break
    ...
    }

    Yeah in my mind, switch/case is the most useful.

    I think "for comparison" all these options one has should be shown;
    all have their own pros and cons.

    (In case your astonishment is per se from the ternary already, note
    also that "C"/Awk's way isn't that "nifty" if compared to some other languages' conditional expressions.[*])

    Oh, I don't know, for shorter constructs, especially one liners, awk
    is plenty good in my thinking at least.

    (That got longer than intended, but for a "comparison" necessary.)

    Not at all, very happy you filled more detail. Your reply will be saved
    to my notes.

    [*] Compare that to Algol 68. There's no difference whether you have conditionals in "statement" or "expression" constructs, and you can
    also have it on both sides of assignments, and you can choose between
    the abbreviated or verbose form.

    IF sound = "bark" THEN mammal := "dog"
    ELIF sound = "meow" THEN mammal := "cat"
    ELIF sound = "moo" THEN mammal := "cow"
    FI

    mammal := IF sound = "bark" THEN "dog"
    ELIF sound = "meow" THEN "cat"
    ELIF sound = "moo" THEN "cow"
    ELSE mammal
    FI

    ( sound = "bark" | mammal := "dog" |:
    sound = "meow" | mammal := "cat" |:
    sound = "moo" | mammal := "cow" )

    mammal := ( sound = "bark" | "dog" |:
    sound = "meow" | "cat" |:
    sound = "moo" | "cow" | mammal )

    The expression variants need a final 'else' only if you want to keep
    the previous variable contents if nothing matches. Otherwise, as is
    often the case (if you want it empty) you'd of course simply write

    mammal := ( sound = "bark" | "dog" |:
    sound = "meow" | "cat" |:
    sound = "moo" | "cow" )


    And one example for conditionals on the left hand side

    ( amount < 0 | losses | gains ) +:= amount

    and this is also possible in the syntactical variant with 'IF'.

    For "nested" forms - note the distinction from "cascaded" on top
    of the post - you can also use both syntactical variants mixed
    for better readability; e.g. write the outer levels with 'IF' and
    inner levels with parenthesis. For example

    IF ... THEN
    ( ... | ... |: ... | ... )
    ELIF ... THEN
    ( ... | ... |: ... |: ... | ... )
    ELSE
    ( ... | ... | ... )
    FI

    (and compare that to a pure 'IF' based or a pure parenthesis based
    use).

    Ah yes, I'm familiar with several of these 'forms'.

    That's all "pretty nifty", isn't it? :-)

    Very nifty in fact. I learned more than I posted. Thanks for sharing your knowledge,
    much appreciated.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Mike Sanders@porkchop@invalid.foo to comp.lang.awk on Sat Oct 11 11:55:57 2025
    From Newsgroup: comp.lang.awk

    On 10 Oct 2025 08:10:56 GMT, Mack The Knife wrote:

    This is where associative arrays shine:

    BEGIN {
    annimal["bark"] = "dog"
    annimal["meow"] = "cat"
    annimal["moo"] = "cow"
    # etc. ...
    }
    { print animal[$1] }

    Much simpler, and each additional sound/animal pair requires
    only one additional line of code.

    I dont know, I'm torn here...

    Associative arrays, as I'm sure you'd agree, are a quintessential
    awk feature & really do make coding chores so much easier. And yet
    for a short logic block, I think ternary has it beat:

    scale = (unit == "T") ? 1e12 :
    (unit == "B") ? 1e9 :
    (unit == "M") ? 1e6 :
    (unit == "K") ? 1e3 : 1

    Nice, compact, even symmetrical looking. Doubly so one liners.

    At any rate, your point is true & I appreciate your remarks Mack.

    Me? Just posting what I learn on my journey in the hopes that
    others will do likewise =)




    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Kaz Kylheku@643-408-1753@kylheku.com to comp.lang.awk on Sat Oct 11 16:58:46 2025
    From Newsgroup: comp.lang.awk

    On 2025-10-11, Mike Sanders <porkchop@invalid.foo> wrote:
    On Thu, 9 Oct 2025 17:09:13 +0200, Janis Papanagnou wrote:

    (Let's call it "cascaded". Nested conditionals would in the general
    case - where you'd have another level of conditionals between the
    '?' and ':' - look even more complex and be much less readable, in
    both variants, conditional statements and conditional expressions.)

    'Cascaded' - nice & clear distinction.

    It is nesting, but it is right associative. This is nesting:

    if (c1) {
    } else {
    if (c2) {
    } else {
    if (c3) {
    }
    }
    }

    Its still nesting when we remove the extra braces around the
    alternative ifs:

    if (c1) {
    } else
    if (c2) {
    } else
    if (c3) {
    }

    The c3 if is a constituent expression (i.e. nested within)
    the c2 if, which is nested within the c1 if.

    Because the nesting is right-leaning we can think of it as linear.
    and write it that way/

    if (c1) {
    } else if (c2) {
    } else if (c3) {
    }

    Same like Lisp lists where we have a right-leaning structure

    .
    a .
    b .
    c nil

    coresponding to the notation

    (a . (b . (c . nil)))

    which is preferentially spelled without the dots and extra
    parenteheses as:

    (a b c)

    and so then we call that a list; and not a nested list.Only this kind of
    object is called a nested list:

    (a (b c) d)

    The cell structure is nested, and so is the explicit dot notation
    for it. The list isn't nested, because the concept "list" is the name
    for a right-leaning nesting of the cell structure, viewed linearly,
    with an accompanying flat notation.
    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @Kazinator@mstdn.ca
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From mack@mack@the-knife.org (Mack The Knife) to comp.lang.awk on Sat Oct 11 17:44:04 2025
    From Newsgroup: comp.lang.awk

    In article <20251010100336.109@kylheku.com>,
    Kaz Kylheku <643-408-1753@kylheku.com> wrote:
    On 2025-10-10, Mack The Knife <mack@the-knife.org> wrote:
    { print animal[$1] }

    Much simpler, and each additional sound/animal pair requires
    only one additional line of code.

    Without function indirection (Gawk extension), or an eval feature
    (doesn't exist in any Awk I know), you cannot dispatch actions, only >substitute values for keys.

    So what? The OP wasn't looking for a way to dispatch actions.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Kaz Kylheku@643-408-1753@kylheku.com to comp.lang.awk on Sat Oct 11 18:46:32 2025
    From Newsgroup: comp.lang.awk

    On 2025-10-11, Mack The Knife <mack@the-knife.org> wrote:
    In article <20251010100336.109@kylheku.com>,
    Kaz Kylheku <643-408-1753@kylheku.com> wrote:
    On 2025-10-10, Mack The Knife <mack@the-knife.org> wrote:
    { print animal[$1] }

    Much simpler, and each additional sound/animal pair requires
    only one additional line of code.

    Without function indirection (Gawk extension), or an eval feature
    (doesn't exist in any Awk I know), you cannot dispatch actions, only >>substitute values for keys.

    So what? The OP wasn't looking for a way to dispatch actions.

    Nested/cascaded ternary will do that:

    cond1 ? increment_this++
    : cond2 ? call_this()
    : foo[this] = that

    It's just not shown in the minimal example where it yields
    string literal values.
    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @Kazinator@mstdn.ca
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.lang.awk on Sun Oct 12 01:45:38 2025
    From Newsgroup: comp.lang.awk

    On 11.10.2025 13:55, Mike Sanders wrote:
    On 10 Oct 2025 08:10:56 GMT, Mack The Knife wrote:

    This is where associative arrays shine:

    BEGIN {
    annimal["bark"] = "dog"
    annimal["meow"] = "cat"
    annimal["moo"] = "cow"
    # etc. ...
    }
    { print animal[$1] }

    Much simpler, and each additional sound/animal pair requires
    only one additional line of code.

    I dont know, I'm torn here...

    Associative arrays, as I'm sure you'd agree, are a quintessential
    awk feature & really do make coding chores so much easier. And yet
    for a short logic block, I think ternary has it beat:

    scale = (unit == "T") ? 1e12 :
    (unit == "B") ? 1e9 :
    (unit == "M") ? 1e6 :
    (unit == "K") ? 1e3 : 1

    Nice, compact, even symmetrical looking. Doubly so one liners.

    Even in case of "short logic blocks"...[*]

    BEGIN { # definition
    S[""] = 1
    S["T"] = 1e12
    S["B"] = 1e9
    S["M"] = 1e6
    S["K"] = 1e3
    }

    scale = S[unit] # application

    The point with the ternary cascaded conditional is that it gets
    traversed at runtime and that the comparisons take place multiple
    times on every call; e.g., above unit "K" needs four comparisons
    before the test triggers.

    The associative array will get initialized once (typically in the
    BEGIN section) and the lookup is just a single array access.

    IMO, concerning its "compactness" or its "symmetry" it's certainly
    also not worse that the conditional cascade.

    Janis

    [*] To be clear; S[""] = 1 is not the same as accepting all other
    units as a value of "1" (as in your cascade), but it appeared more
    sensible a choice in case of units. And with arrays you can simply
    check beforehand whether a unit is defined at all by 'unit in S',
    which is obviously another advantage (unless you define a default
    value, say 0, and test against that return value separately).

    [...]


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.lang.awk on Sun Oct 12 01:54:51 2025
    From Newsgroup: comp.lang.awk

    On 11.10.2025 13:46, Mike Sanders wrote:

    Oh, I don't know, for shorter constructs, especially one liners, awk
    is plenty good in my thinking at least.

    Yes, sure.

    Actually, the existence of (uninitialized usable) associative arrays
    is what contributes significantly to writing powerful one-liners (or
    also many more complex things in a terse way) in Awk.

    Janis

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Mike Sanders@porkchop@invalid.foo to comp.lang.awk on Sun Oct 12 03:47:12 2025
    From Newsgroup: comp.lang.awk

    On Sat, 11 Oct 2025 16:58:46 -0000 (UTC), Kaz Kylheku wrote:

    Hey Kaz!

    Guys you're miles ahead of me, I'm still learning.
    Must study your reply more but 'linear' is sticking in my mind.
    There is something to that as well as your left/right examples
    that I can not yet articulate (its frustrating to recognize
    these patterns but lack the vocabulary to describe them - argh!).

    At any rate thanks Kaz.

    On 2025-10-11, Mike Sanders <porkchop@invalid.foo> wrote:
    On Thu, 9 Oct 2025 17:09:13 +0200, Janis Papanagnou wrote:

    (Let's call it "cascaded". Nested conditionals would in the general
    case - where you'd have another level of conditionals between the
    '?' and ':' - look even more complex and be much less readable, in
    both variants, conditional statements and conditional expressions.)

    'Cascaded' - nice & clear distinction.

    It is nesting, but it is right associative. This is nesting:

    if (c1) {
    } else {
    if (c2) {
    } else {
    if (c3) {
    }
    }
    }

    Its still nesting when we remove the extra braces around the
    alternative ifs:

    if (c1) {
    } else
    if (c2) {
    } else
    if (c3) {
    }

    The c3 if is a constituent expression (i.e. nested within)
    the c2 if, which is nested within the c1 if.

    Because the nesting is right-leaning we can think of it as linear.
    and write it that way/

    if (c1) {
    } else if (c2) {
    } else if (c3) {
    }

    Same like Lisp lists where we have a right-leaning structure

    .
    a .
    b .
    c nil

    coresponding to the notation

    (a . (b . (c . nil)))

    which is preferentially spelled without the dots and extra
    parenteheses as:

    (a b c)

    and so then we call that a list; and not a nested list.Only this kind of object is called a nested list:

    (a (b c) d)

    The cell structure is nested, and so is the explicit dot notation
    for it. The list isn't nested, because the concept "list" is the name
    for a right-leaning nesting of the cell structure, viewed linearly,
    with an accompanying flat notation.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Mike Sanders@porkchop@invalid.foo to comp.lang.awk on Sun Oct 12 03:49:39 2025
    From Newsgroup: comp.lang.awk

    On Sun, 12 Oct 2025 01:54:51 +0200, Janis Papanagnou wrote:

    Actually, the existence of (uninitialized usable) associative arrays
    is what contributes significantly to writing powerful one-liners (or
    also many more complex things in a terse way) in Awk.

    If I HAD to choose only one, associative arrays would be the keeper.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From dave_thompson_2@dave_thompson_2@comcast.net to comp.lang.awk on Sun Oct 12 20:58:03 2025
    From Newsgroup: comp.lang.awk

    On Sat, 11 Oct 2025 11:55:57 -0000 (UTC), Mike Sanders
    <porkchop@invalid.foo> wrote:

    scale = (unit == "T") ? 1e12 :
    (unit == "B") ? 1e9 :
    (unit == "M") ? 1e6 :
    (unit == "K") ? 1e3 : 1


    scale = 1000 ^ index("KMBT",unit)
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.lang.awk on Mon Oct 13 04:30:27 2025
    From Newsgroup: comp.lang.awk

    On 13.10.2025 02:58, dave_thompson_2@comcast.net wrote:
    On Sat, 11 Oct 2025 11:55:57 -0000 (UTC), Mike Sanders
    <porkchop@invalid.foo> wrote:

    scale = (unit == "T") ? 1e12 :
    (unit == "B") ? 1e9 :
    (unit == "M") ? 1e6 :
    (unit == "K") ? 1e3 : 1


    scale = 1000 ^ index("KMBT",unit)

    Nice hack. Just note that for the case of "no unit" - i.e. for an
    empty string - index() returns 1, thus scale becomes 1000 and not
    1 (as returned for other characters than the defined ones).

    One problem with such arithmetic hacks is that it doesn't "scale"
    nicely, e.g. when multi-character unit strings are involved, or
    if the scales are not defined in regular forms. - Explicit 'if'
    cascades, or string-keys in associative arrays are more robust.

    Janis

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From mack@mack@the-knife.org (Mack The Knife) to comp.lang.awk on Mon Oct 13 08:07:05 2025
    From Newsgroup: comp.lang.awk

    In article <20251011114253.330@kylheku.com>,
    Kaz Kylheku <643-408-1753@kylheku.com> wrote:
    On 2025-10-11, Mack The Knife <mack@the-knife.org> wrote:
    In article <20251010100336.109@kylheku.com>,
    Kaz Kylheku <643-408-1753@kylheku.com> wrote:
    On 2025-10-10, Mack The Knife <mack@the-knife.org> wrote:
    { print animal[$1] }

    Much simpler, and each additional sound/animal pair requires
    only one additional line of code.

    Without function indirection (Gawk extension), or an eval feature >>>(doesn't exist in any Awk I know), you cannot dispatch actions, only >>>substitute values for keys.

    So what? The OP wasn't looking for a way to dispatch actions.

    Nested/cascaded ternary will do that:

    cond1 ? increment_this++
    : cond2 ? call_this()
    : foo[this] = that

    It's just not shown in the minimal example where it yields
    string literal values.

    Point taken.
    --- Synchronet 3.21a-Linux NewsLink 1.2