I’ll start with the question:
The Dyalog 15.0 manual states
that the power operator can take a
function right argument. In
this case, that function can be
either 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 to
be 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 two
solutions:
- 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 the
left argument; wouldn’t it
be possible to implement lambdas
containing only ⍵ as
ambivalent, so ⍺ is simply never used
even 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 would
also 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 but
not in the rest of the
function, then ⍺⊢ must be prepended to
the lambda.
While on the subject of
lambdas, IMHO variables assigned inside
lambdas should be made local.
More than once I’ve used a named
lambda in a tradfn and have
found that one of its local variables
was modified by the lambda.
Although I imagine named lambdas must
be a pain to implement.
Also, I noticed that the
assignment of a lambda to a name
returns a vector of the name
of the lambda. It would be
interesting if it could
return the actual lambda (of course this
probably isn’t feasible,
since it would require function
returning 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 ATCTGAT
TGCATA GCATA
ATCTGAT TGCATA
{((1↓X)Y((⊃X),Z)),[.5]X(1↓Y)((⊃Y),Z)⊣(X Y Z)←⍵}g d ⍬
TCTGAT ATCTGAT
TGCATA GCATA
ATCTGAT TGCATA
These should be transposed. ⎕IO ←→ 0, so
,[¯.5] should give a two row,
three column matrix.
←——————— - -
- ———————→
)SI
⋆⋆
==============================================================================
Assertion failed: idx <
items_valid
in 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: 9
Exec: 0x7f98db4177b0
Safe exec: 0
Pmode: ⍎
(1↓R)((=/0⌷¨V)↓⍵⊃⍨~⍺)((2⊃⍵),1↑R←⍺⊃V)
PC: 27 /
Stat:
(1↓R)((=/0⌷¨V)↓⍵⊃⍨~⍺)((2⊃⍵),1↑R←⍺⊃V)
err_code: 0x50005
e_msg_1: 'INDEX ERROR+'
e_msg_2: '
(1↓R)((=/0⌷¨V)↓⍵⊃⍨∼⍺)((2⊃⍵),1↑R←⍺⊃V)'
e_msg_3: ' ^
^'
Depth: 8
Exec: 0x7f98db41b9f0
Safe exec: 0
Pmode: ∇
==============================================================================
Assertion failed: idx <
items_valid
in 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 very
hard 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 APL
which adheres to the standard
while being as bug free as yours, and is a
one-man project. Let alone
all three!
Keep in mind everything I
suggest is the personal opinion of someone with very
little experience with C++ish
languages. I’m sure you know better than I do how
to shape your APL. After all,
you’re the one writing it!
Best of luck,
Louis