• Why don't lambda functions work inside defined functions?

    From Brian McGuinness@b.mcguinness747@gmail.com to comp.lang.apl on Sun Jun 5 13:08:48 2022
    From Newsgroup: comp.lang.apl

    I have been experimenting with simple lambda functions to see how they work. But I ran into behavior that I don't understand, and I haven't found good documentation to explain what is going on.
    This works as expected:
    ({ri|,+/->2raari|}riu10) 0 1
    0 1 1 2 3 5 8 13 21 34 55 89
    But this doesn't work:
    rec
    [0] AraEFIBONACCI N
    [1] AraE({ri|,+/->2raari|}riuN-2) 0 1
    rec
    FIBONACCI 12
    2 ->2 ->4 ->6 ->10 ->16 ->26 ->42 ->68 ->110 ->178 ->288 ->466 0 1
    If I tried to do this using only normal defined functions I would have to use two separate functions, so it seems to me that using a lambda function should be a cleaner way to perform the operation. But I don't see how to make this work.
    --- Brian McGuinness
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Rav@invalid@invalid.invalid to comp.lang.apl on Sun Jun 5 18:11:06 2022
    From Newsgroup: comp.lang.apl

    On 6/5/2022 4:08 PM, Brian McGuinness wrote:
    I have been experimenting with simple lambda functions to see how they work. But I ran into behavior that I don't understand, and I haven't found good documentation to explain what is going on.

    This works as expected:

    ({ri|,+/->2raari|}riu10) 0 1
    0 1 1 2 3 5 8 13 21 34 55 89

    But this doesn't work:

    rec
    [0] AraEFIBONACCI N
    [1] AraE({ri|,+/->2raari|}riuN-2) 0 1
    rec

    FIBONACCI 12
    ->2 ->2 ->4 ->6 ->10 ->16 ->26 ->42 ->68 ->110 ->178 ->288 ->466 0 1

    If I tried to do this using only normal defined functions I would have to use two separate functions, so it seems to me that using a lambda function should be a cleaner way to perform the operation. But I don't see how to make this work.

    --- Brian McGuinness

    If I understand correctly, it doesn't look to me like doing the same
    thing with a defined function is doing anything differently. In
    immediate execution mode:

    ({ri|,+/->2raari|}riu12-2) 0 1
    ->2 ->2 ->4 ->6 ->10 ->16 ->26 ->42 ->68 ->110 ->178 ->288 ->466 0 1

    But:

    ({ri|,+/->2raari|}riu(12-2)) 0 1
    0 1 1 2 3 5 8 13 21 34 55 89

    I'm not familiar with the power function, but perhaps it's a precedence
    issue, which the parentheses solves. So change your defined function to:

    rec
    [0] AraEFIBONACCI N
    [1] AraE({ri|,+/->2raari|}riu(N-2)) 0 1
    rec

    / Rav
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Charles Brenner@challambrenner@gmail.com to comp.lang.apl on Mon Jun 6 13:03:13 2022
    From Newsgroup: comp.lang.apl

    On Sunday, June 5, 2022 at 3:11:09 PM UTC-7, Rav wrote:
    On 6/5/2022 4:08 PM, Brian McGuinness wrote:
    I have been experimenting with simple lambda functions to see how they work. But I ran into behavior that I don't understand, and I haven't found good documentation to explain what is going on.

    This works as expected:

    ({ri|,+/->2raari|}riu10) 0 1
    0 1 1 2 3 5 8 13 21 34 55 89

    But this doesn't work:

    rec
    [0] AraEFIBONACCI N
    [1] AraE({ri|,+/->2raari|}riuN-2) 0 1
    rec

    FIBONACCI 12
    2 ->2 ->4 ->6 ->10 ->16 ->26 ->42 ->68 ->110 ->178 ->288 ->466 0 1

    If I tried to do this using only normal defined functions I would have to use two separate functions, so it seems to me that using a lambda function should be a cleaner way to perform the operation. But I don't see how to make this work.

    --- Brian McGuinness
    If I understand correctly, it doesn't look to me like doing the same
    thing with a defined function is doing anything differently. In
    immediate execution mode:

    ({ri|,+/->2raari|}riu12-2) 0 1
    2 ->2 ->4 ->6 ->10 ->16 ->26 ->42 ->68 ->110 ->178 ->288 ->466 0 1
    But:

    ({ri|,+/->2raari|}riu(12-2)) 0 1
    0 1 1 2 3 5 8 13 21 34 55 89
    I'm not familiar with the power function, but perhaps it's a precedence issue, which the parentheses solves. So change your defined function to:

    rec
    [0] AraEFIBONACCI N
    [1] AraE({ri|,+/->2raari|}riu(N-2)) 0 1
    rec

    / Rav
    Nice work. That solves the puzzle except for a small point of language. riu is an operator hence, contrary to the rule for a function, it has short right scope - i.e. "12" or "(12-2)" - (and long left scope).
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bob Smith@bsmith@sudleydeplacespam.com to comp.lang.apl on Tue Jun 7 10:50:30 2022
    From Newsgroup: comp.lang.apl

    On 6/6/2022 4:03 PM, Charles Brenner wrote:
    On Sunday, June 5, 2022 at 3:11:09 PM UTC-7, Rav wrote:
    On 6/5/2022 4:08 PM, Brian McGuinness wrote:
    I have been experimenting with simple lambda functions to see how they work. But I ran into behavior that I don't understand, and I haven't found good documentation to explain what is going on.

    This works as expected:

    ({ri|,+/->2raari|}riu10) 0 1
    0 1 1 2 3 5 8 13 21 34 55 89

    But this doesn't work:

    rec
    [0] AraEFIBONACCI N
    [1] AraE({ri|,+/->2raari|}riuN-2) 0 1
    rec

    FIBONACCI 12
    2 ->2 ->4 ->6 ->10 ->16 ->26 ->42 ->68 ->110 ->178 ->288 ->466 0 1

    If I tried to do this using only normal defined functions I would have to use two separate functions, so it seems to me that using a lambda function should be a cleaner way to perform the operation. But I don't see how to make this work.

    --- Brian McGuinness
    If I understand correctly, it doesn't look to me like doing the same
    thing with a defined function is doing anything differently. In
    immediate execution mode:

    ({ri|,+/->2raari|}riu12-2) 0 1
    2 ->2 ->4 ->6 ->10 ->16 ->26 ->42 ->68 ->110 ->178 ->288 ->466 0 1
    But:

    ({ri|,+/->2raari|}riu(12-2)) 0 1
    0 1 1 2 3 5 8 13 21 34 55 89
    I'm not familiar with the power function, but perhaps it's a precedence
    issue, which the parentheses solves. So change your defined function to:

    rec
    [0] AraEFIBONACCI N
    [1] AraE({ri|,+/->2raari|}riu(N-2)) 0 1
    rec

    / Rav
    Nice work. That solves the puzzle except for a small point of language. riu is an operator hence, contrary to the rule for a function, it has short right scope - i.e. "12" or "(12-2)" - (and long left scope).

    Charles is exactly right. Moreover, there is one difference in the way
    dyadic operators work in APL2 and NARS2000 versus Dyalog with numeric
    strand right operands. While they all implement short right scope, in
    APL2 and NARS2000

    friu1 2 3 raEraA (friu1) 2 3

    whereas in Dyalog

    friu1 2 3 raEraA friu(1 2 3)

    One way to look at the difference is in the interpretation of 1 2 3 as
    three tokens or a single token.
    --
    _________________________________________
    Bob Smith -- bsmith@sudleydeplacespam.com
    http://www.sudleyplace.com - http://www.nars2000.org

    To reply to me directly, delete "despam".
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Charles Brenner@challambrenner@gmail.com to comp.lang.apl on Tue Jun 7 11:44:33 2022
    From Newsgroup: comp.lang.apl

    On Tuesday, June 7, 2022 at 7:50:35 AM UTC-7, Bob Smith wrote:
    On 6/6/2022 4:03 PM, Charles Brenner wrote:
    On Sunday, June 5, 2022 at 3:11:09 PM UTC-7, Rav wrote:
    On 6/5/2022 4:08 PM, Brian McGuinness wrote:
    I have been experimenting with simple lambda functions to see how they work. But I ran into behavior that I don't understand, and I haven't found good documentation to explain what is going on.

    This works as expected:

    ({ri|,+/->2raari|}riu10) 0 1
    0 1 1 2 3 5 8 13 21 34 55 89

    But this doesn't work:

    rec
    [0] AraEFIBONACCI N
    [1] AraE({ri|,+/->2raari|}riuN-2) 0 1
    rec

    FIBONACCI 12
    2 ->2 ->4 ->6 ->10 ->16 ->26 ->42 ->68 ->110 ->178 ->288 ->466 0 1

    If I tried to do this using only normal defined functions I would have to use two separate functions, so it seems to me that using a lambda function should be a cleaner way to perform the operation. But I don't see how to make this work.

    --- Brian McGuinness
    If I understand correctly, it doesn't look to me like doing the same
    thing with a defined function is doing anything differently. In
    immediate execution mode:

    ({ri|,+/->2raari|}riu12-2) 0 1
    2 ->2 ->4 ->6 ->10 ->16 ->26 ->42 ->68 ->110 ->178 ->288 ->466 0 1
    But:

    ({ri|,+/->2raari|}riu(12-2)) 0 1
    0 1 1 2 3 5 8 13 21 34 55 89
    I'm not familiar with the power function, but perhaps it's a precedence >> issue, which the parentheses solves. So change your defined function to: >>
    rec
    [0] AraEFIBONACCI N
    [1] AraE({ri|,+/->2raari|}riu(N-2)) 0 1
    rec

    / Rav
    Nice work. That solves the puzzle except for a small point of language. riu is an operator hence, contrary to the rule for a function, it has short right scope - i.e. "12" or "(12-2)" - (and long left scope).
    Charles is exactly right. Moreover, there is one difference in the way dyadic operators work in APL2 and NARS2000 versus Dyalog with numeric
    strand right operands. While they all implement short right scope, in
    APL2 and NARS2000

    friu1 2 3 raEraA (friu1) 2 3

    whereas in Dyalog

    friu1 2 3 raEraA friu(1 2 3)
    Thanks Bob. That's good to know and I didn't.
    Another situation where Morton chose to abandon APL2's parenthesis requirement is multiple assignment:
    In APL2: (one another)raE1 'ther'
    Dyalog permits: one anotherraE1 'ther'
    Morton expressed remorse for this, and eventually I saw why. I often invoke the display utility function #.disp, i.e. disp (3 2ri|'a' 23 ('b' 'cd')). Sometimes when my program crashed while inside namespace #.ns, I would thoughtlessly write disp xraEFunction ri|7, which usually works fine. But if Function returns a 2-element vector, uh oh!
    So I began writing (xyz abc)raE ..., and having thus violated my life-long habit of always omitting unnecessary punctuation in my APL code, the floodgates are getting shakey. Occasionally I now add extra parentheses for symmetry or a superfluous monadic rea for clarity.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bob Smith@bsmith@sudleydeplacespam.com to comp.lang.apl on Tue Jun 7 18:06:28 2022
    From Newsgroup: comp.lang.apl

    On 6/7/2022 2:44 PM, Charles Brenner wrote:
    [..]
    Thanks Bob. That's good to know and I didn't.
    Another situation where Morton chose to abandon APL2's parenthesis requirement is multiple assignment:
    In APL2: (one another)raE1 'ther'
    Dyalog permits: one anotherraE1 'ther'
    Morton expressed remorse for this, and eventually I saw why. I often invoke the display utility function #.disp, i.e. disp (3 2ri|'a' 23 ('b' 'cd')). Sometimes when my program crashed while inside namespace #.ns, I would thoughtlessly write disp xraEFunction ri|7, which usually works fine. But if Function returns a 2-element vector, uh oh!
    So I began writing (xyz abc)raE ..., and having thus violated my life-long habit of always omitting unnecessary punctuation in my APL code, the floodgates are getting shakey. Occasionally I now add extra parentheses for symmetry or a superfluous monadic rea for clarity.

    Yes, I agree completely with the need for surrounding parens in
    selective specifications. Principally, I want it for ease of parsing
    the line visually. Fortunately for you, Dyalog APL disallows the re-assignment of a variable to the name of an existing function, so disp
    won't be changed.

    Parens are already required in some instances of SelSpec, such as distinguishing between

    1 1riea raEb and
    (1 1riea)raEb

    which says to me that they should be required in every case of SelSpec.

    Also, in Dyalog APL you might be required to insert parens in an unusual place: around the *rightmost* part of a statement, such as

    araE1 ria a braE'ab' ria a b
    ab
    araE1 ria a (braE'ab')
    1 ab
    --
    _________________________________________
    Bob Smith -- bsmith@sudleydeplacespam.com
    http://www.sudleyplace.com - http://www.nars2000.org

    To reply to me directly, delete "despam".
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Brian McGuinness@b.mcguinness747@gmail.com to comp.lang.apl on Tue Jun 7 15:53:47 2022
    From Newsgroup: comp.lang.apl

    Thanks, now I see what's going on.

    --- Brian McGuinness
    --- Synchronet 3.21d-Linux NewsLink 1.2