I think that's really nice. How about using ⟻ or ⇐ for that?

I know that a common argument against it that Jürgen has raised in the past
is the limitations of ⎕AV being 256 characters in length. I obviously
disagree with that, and feel that ⎕AV provides nothing that ⎕UCS doesn't.

Regards,
Elias

On 14 August 2016 at 13:40, Louis de Forcrand <[email protected]> wrote:

> And a third email about lambda locals.
>
> IMHO, a solution could be to introduce an extra assignment arrow which
> denotes explicit
> global assignment, and make the usual assignment arrow denote assignment
> which is
> local to lambdas (or have it the other way around).
> If the standard doesn’t allow something like this, maybe something along
> the lines of ⎕FX
> like:
>
> ‘A’ ⎕LC data
> ‘A’ ⎕GL data
>
> to denote explicit global or local assignment useful in lambdas or other
> places, whichever
> is not chosen to be denoted by the already existing arrow, could be used.
> I would argue that the current arrow be used for local assignment, because
> (aside from
> personal taste) global assignment is more “dangerous” if inadvertently
> used. As in,
> a person who wants to just throw together a quick lambda doesn’t usually
> want
> or need the effects of global assignment unless they can explicitly say so.
>
> Louis
>
> Sorry if I’m sending these twice; my mailer automatically sends them only
> to you Jürgen,
> so I end up forwarding them to the mailing list.
>
>
>
> On 13 Aug 2016, at 10:19, Juergen Sauermann <[email protected]>
> wrote:
>
>
> Hi,
>
> the problem is that there is no syntactical means to "state otherwise".
>
> I personally find it convenient to assign to variables outside the lambda,
> for example
> to increment a counter on every iteration of the lambda. Of course one can
> criticize the way
> APL handles variables, but the limited number of function arguments and
> return values
> makes the scoping rules of APL almost inevitable. And I still believe that
> it is a bad thing
> if the scoping rules of lambdas are different from the scoping rules of
> "normal" defined functions.
>
> So the only room for changes that remains is to have a way of adding local
> variables to the header
> line of lambdas. Something along the lines of:
>
> *      FUN←'A B C**' **⎕LOCALIZE** { ... }*
>
> where A B and C would become local variables in the named lambda FUN.
>
> I would also argue that lambdas are only a quick-and-dirty hack for
> specifying the function arguments
> of the EACH operator and friends; for serious functions ⎕FX and ∇ have all
> the features that are missing
> in GNU APL lambdas.
>
> /// Jürgen
>
>
> On 08/13/2016 02:11 PM, Elias Mårtenson wrote:
>
> 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
>
> On 13 Aug 2016 8:05 pm, "Juergen Sauermann" <[email protected]>
> wrote:
>
> 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 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
>> thrown:   at Value.cc <http://value.cc/>:1051
>> 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
>>
>>
>

Reply via email to