|
From: | Elias Mårtenson |
Subject: | Re: [Bug-apl] A couple of bugs, and a question on the power operator |
Date: | Sat, 13 Aug 2016 20:11:13 +0800 |
With regards to lack of local variables for lambda functions, I've observed that local is the typical case, and nonlocal is somewhat rare.
Wouldn't it make sense to make all variable assignments local for lambda functions local, unless stated otherwise?
Regards,
Elias
Hi Louis,
a quick answer to your question beforehand, I will look into the bugs later.
GNU APL has implemented the power operator according to the description
in the book "Mastering Dyalog APL". The ISO standard says nothing about this
operator, it is simply not defined there.
In "Mastering Dyalog APL" I haven't found the monadic case for the right function argument
G of the power operator. In that book G seems to be always dyadic. So the monadic case looks
like a new Dyalog invention. And, if it is defined like you say, IMHO not the ultimate wisdom.
What I do not like at all is the fact that in the dyadic case F is being computed before G (it has to,
because you need the result ⍺F⍵ or F⍵ as left argument of G. And, as you say, in the monadic
case F is being computed after G.
I could imagine to implement the monadic G if it were always computed after F so that the order
of execution is consistent for the monadic and dyadic cases. But if Dyalog really has different orders
then I would prefer to not implement the monadic case in GNU APL at all because then I would only
have the choice between an inconsistent execution order (which is, in my opinion, bad) or an
incompatibility with Dyalog APL (which is also bad).
Actually in GNU APL lambdas can be ambivalent, but monadic functions (lambda or not) cannot be
ambivalent. Localizing variables assigned in lambdas automatically is technically possible but would
break backward compatibility of existing workspaces. There was a discussion on this topic earlier this
year, but no progress lately. I was thinking of some ⎕-function (like ⎕FX but with {} syntax that would
allow you to created lambdas with more control over the localization of variables).
BTW, I read the word until in your description below as F being called before G and not after G,
even in the monadic case.
/// Jürgen
On 08/13/2016 08:24 AM, Louis de Forcrand wrote:
I’ll start with the question:
The Dyalog 15.0 manual states that the power operator can take afunction right argument. In this case, that function can beeither monadic or dyadic, and can be a lambda.If it’s monadic:
(F⍣G) ⍵ ←→ ⍵ ← F ⍵ until G ⍵⍺ (F⍣G) ⍵ ←→ ⍵ ← ⍺ F ⍵ until G ⍵
If it’s dyadic:
(F⍣G) ⍵ ←→ ⍵ ← F ⍵ until ( F ⍵) G ⍵⍺ (F⍣G) ⍵ ←→ ⍵ ← ⍺ F ⍵ until (⍺ F ⍵) G ⍵
(Note that G is checked before the first time F is executed.)
I don’t know what the ISO standard says on this, but in GNU APL,dyadic G works as in Dyalog. However, “monadic” lambda G has tobe a weird function that takes both a left and a right argument,and discards the left one. That is:
Dyalog: GNU:F⍣{G ⍵} F⍣{⍺⊢G ⍵}
Is this because lambdas can’t be ambivalent? If so, I see twosolutions:
- Make ⍣ check G’s valence.
- Better: I know it’s possible to write an ambivalent tradfn(function defined with the ∇-editor) by using ⎕NC on theleft argument; wouldn’t it be possible to implement lambdascontaining only ⍵ as ambivalent, so ⍺ is simply never usedeven if it is defined (or defined even if it isn’t used)?In fact, dyadic tradfns work in this way.
Not only would this allow for cleaner use of ⍣, but it wouldalso allow for “cleaner” case statements in lambdas:
{⍎(‘case0’ ‘case1’ ‘case2’ ‘etc.’)[condition]}
which is probably the only place one would use this.
As of now, if ⍺ is present in one of the case statements butnot in the rest of the function, then ⍺⊢ must be prepended tothe lambda.
While on the subject of lambdas, IMHO variables assigned insidelambdas should be made local. More than once I’ve used a namedlambda in a tradfn and have found that one of its local variableswas modified by the lambda. Although I imagine named lambdas mustbe a pain to implement.
Also, I noticed that the assignment of a lambda to a namereturns a vector of the name of the lambda. It would beinteresting if it could return the actual lambda (of course thisprobably isn’t feasible, since it would require functionreturning expressions, a.k.a. tacit programming).
Now on to the bugs:
(g d)←'ATCTGAT' 'TGCATA'{((1↓X)Y((⊃X),Z)),[¯.5]X(1↓Y)((⊃Y),Z)⊣(X Y Z)←⍵}g d ⍬ TCTGAT ATCTGATTGCATA GCATAATCTGAT TGCATA{((1↓X)Y((⊃X),Z)),[.5]X(1↓Y)((⊃Y),Z)⊣(X Y Z)←⍵}g d ⍬ TCTGAT ATCTGATTGCATA GCATAATCTGAT TGCATA
These should be transposed. ⎕IO ←→ 0, so ,[¯.5] should give a two row,three column matrix.
←——————— - - - ———————→
)SI⋆⋆
============================================================ ================== Assertion failed: idx < items_validin Function: operator[]in file: ./Simple_string.hh:140
Call stack:
---------------------------------------- -- Stack trace at ./Simple_string.hh:140---------------------------------------- 0xa @@@@0xa @@@@0xa @@@@0xa @@@@0xa @@@@0xa @@@@0xa @@@@0xa @@@@0xa @@@@========================================
SI stack:
Depth: 9Exec: 0x7f98db4177b0Safe exec: 0Pmode: ⍎ (1↓R)((=/0⌷¨V)↓⍵⊃⍨~⍺)((2⊃⍵),1↑R←⍺⊃V) PC: 27 /Stat: (1↓R)((=/0⌷¨V)↓⍵⊃⍨~⍺)((2⊃⍵),1↑R←⍺⊃V) err_code: 0x50005thrown: at Value.cc:1051e_msg_1: 'INDEX ERROR+'e_msg_2: ' (1↓R)((=/0⌷¨V)↓⍵⊃⍨∼⍺)((2⊃⍵),1↑R←⍺⊃V)' e_msg_3: ' ^ ^'
Depth: 8Exec: 0x7f98db41b9f0Safe exec: 0Pmode: ∇============================================================ ================== Assertion failed: idx < items_validin Function: operator[]in file: ./Simple_string.hh:140
Call stack:*** do_Assert() called recursively ***============================================================ ================== *** immediate_execution() caught other exception ***
I’m sorry I couldn’t include the input preceding that )SI, it's long and veryhard to reproduce. I hope this is enough to help :-⌈
~———~
I’d like to thank you for your very hard work. I don’t know of any other APLwhich adheres to the standard while being as bug free as yours, and is aone-man project. Let alone all three!Keep in mind everything I suggest is the personal opinion of someone with verylittle experience with C++ish languages. I’m sure you know better than I do howto shape your APL. After all, you’re the one writing it!
Best of luck,Louis
[Prev in Thread] | Current Thread | [Next in Thread] |