Of course. How about introducing a special syntax for local variables?
Maybe prefixing them with a character or something?

Or, use Cyrillic for locals. (yes, that was a joke)

On 13 Aug 2016 10:19 pm, "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: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