Defaulting left arguments in ambivalent trad-fns

APL-related discussions - a stream of APL consciousness.
Not sure where to start a discussion ? Here's the place to be
Forum rules
This forum is for discussing APL-related issues. If you think that the subject is off-topic, then the Chat forum is probably a better place for your thoughts !

Defaulting left arguments in ambivalent trad-fns

Postby norbertjurkiewicz84 on Wed Jun 07, 2017 5:01 pm

It may be useful to have a cleaner way of defaulting ambivalent trad-fn left arguments...


The ability to default a Dfns argument is a very powerful feature.

      root←{      ⍝ ⍺th root
⍺←2 ⍝ default to sqrt
⍵*÷⍺
}


Traditional functions need a bit of :if logic to accomplish the same result, unless there's a feature I'm not aware of...

      Z←{lArg}TestFoo rArg
:If 0=⎕NC'lArg'
lArg←1
:EndIf

Z←lArg+rArg


It would be nice to have dfn like syntax or maybe an I-Beam to get the same functionality.

An I-beam can to accomplish this. Here the I-Beam passes the value of lArg, if available, or it's right argument.

      lArg←(10⌶'lAarg')123


Even better, the I-Beam can be aware of its scope and default to the left argument.

      lArg←10⌶123


The cleanest would be a quad function along these lines...

      lArg←⎕DEFAULT 123

or

      Z←{lArg}TestFoo rArg 
lArg←⎕DEFAULT 123
Z←lArg+rArg


The new 900 I-beam is useful to determine if the value was an argument or defaulted.

      Z←{lArg}TestFoo rArg
lArg←⎕DEFAULT 123
Z←'Default: ',(900⌶⍬)⊃'No' 'Yes'
User avatar
norbertjurkiewicz84
 
Posts: 47
Joined: Mon Nov 01, 2010 7:26 pm

Re: Defaulting left arguments in ambivalent trad-fns

Postby Phil Last on Thu Jun 08, 2017 2:44 pm

Lots of tried and tested methods without if-then-else or conditional execute but not necessarily more elegant or less clumsy.
      r←{a} f00 w
a←'a'{6::⍵ ⋄ ⍎⍺}'this'
after which a is as supplied or 'this'.
      r←{a} f01 w
z←⎕FX'r←a w' 'r←w'
after which a is as supplied or equiv to
so to use a we do
      larg←a⊣'this'
after which larg is a as supplied or 'this'
or to pass on its ambivalence to a called function we do
      res←a f02 ...
after which f02 has the same problem.

After my response to a post in an early Vector similar to the ⎕FX solution above Maurice Jordan suggested:
      r←[a] f03 w
after which a is as supplied or is

Some have suggested
      r←[a←expr...] f04 w

after which a is as supplied or the result of executing the expression in brackets.

Others have pointed out how dangerous and/or impossible this would be to implement.

Any more for any more?
User avatar
Phil Last
 
Posts: 439
Joined: Thu Jun 18, 2009 6:29 pm

Re: Defaulting left arguments in ambivalent trad-fns

Postby JohnS|Dyalog on Thu Jun 08, 2017 3:47 pm

I like Maurice's:
      r←[a] f03 w
Where a missing [a] is assigned ⊢.

For example:
      ∇ z←[nth] root m
[1] z←m*÷nth⊣2

root 64 ⍝ default: square root
8
3 root 64 ⍝ cube root
4

      monadic←2≠⎕nc'larg'  ⍝ explicit test for monadic call 
monadic←⊃0 larg⊣1 ⍝ alternative idiom for monadic call

One problem with the more complicated syntax:
      r←[a←expr...] f04 w
is that it makes it difficult to do any preamble, such as computing values to be used in expr. Imposing the restriction that expr may only be a "constant" doesn't quite fly because you often want a 1-item vector or a 0-row matrix, etc. Plus, if there's an error in expr, suspending on line[0] might be a bit strange.
User avatar
JohnS|Dyalog
 
Posts: 163
Joined: Wed Sep 10, 2008 10:01 am

Re: Defaulting left arguments in ambivalent trad-fns

Postby Phil Last on Fri Jun 09, 2017 2:42 pm

JohnS|Dyalog wrote:
      monadic←2≠⎕nc'larg'  ⍝ explicit test for monadic call 
monadic←⊃0 larg⊣1 ⍝ alternative idiom for monadic call
      monadic←1≡larg 1       ⍝ alternative⍣2
User avatar
Phil Last
 
Posts: 439
Joined: Thu Jun 18, 2009 6:29 pm

Re: Defaulting left arguments in ambivalent trad-fns

Postby petermsiegel on Wed Jun 14, 2017 5:53 pm

APL has a long tradition of preprocessors (mostly leading to implementation of new "core" features). I wrote one a while back that I use in tradfns and dfns. One feature uses double-dot notation for a number of manipulations with names on the left, including this:

name..⍺←new_value ⍝ new_value is everything to the right that's in scope

which for any name returns its value if set, and sets it to and returns new_value otherwise. It doesn't work quite like the dfns ⍺ (insofar as new_value is always executed), but it could and SHOULD (I just didn't need it, mea culpa).

When the surrounding function is FiXed, the preprocessor simply replaces the pattern above by the requisite APL code to test ⎕NC 'name'. Similarly name..⍺ new_value returns the value of name or new_value, without setting name. Some folks may dislike preprocessors (they create and solve problems); that's ok: I built the preprocessor to test out new features, including things like "cut", before they enter the standard releases, along with things from other languages, like Python or C: continuation lines, simple macros, static objects, etc.
petermsiegel
 
Posts: 47
Joined: Thu Nov 11, 2010 11:04 pm

Re: Defaulting left arguments in ambivalent trad-fns

Postby Adam|Dyalog on Sun Jul 02, 2017 1:36 am

My idea is to use a special numeric label, where execution begins if called dyadically:

      r←{nth} root x
nth←2
2: r←x*÷nth
User avatar
Adam|Dyalog
 
Posts: 13
Joined: Thu Jun 25, 2015 1:13 pm

Re: Defaulting left arguments in ambivalent trad-fns

Postby petermsiegel on Mon Jul 03, 2017 11:08 pm

Very concise.

NARS 2000 uses (used?) special labels in Trad Fns to handle special entry points:

..... User-defined function/operator prototype entry point (⎕PRO:)
..... User-defined function/operator identity element entry point (⎕ID:)

but for some reason didn't think to do this for ambivalence.
petermsiegel
 
Posts: 47
Joined: Thu Nov 11, 2010 11:04 pm

Re: Defaulting left arguments in ambivalent trad-fns

Postby Adam|Dyalog on Tue Jul 04, 2017 10:06 am

The reason for using a numerical label is that the apparent syntax can be used in dfns too, albeit with a slightly different meaning:

      root←{
2:⍵*÷⍺
⍵*÷2
}


where the 2 evaluates to true if called dyadically.
User avatar
Adam|Dyalog
 
Posts: 13
Joined: Thu Jun 25, 2015 1:13 pm


Return to APL Chat

Who is online

Users browsing this forum: No registered users and 1 guest