Tacit Primes?

For users of dfns, both novice and expert
mwr0707
Posts: 17
Joined: Wed Oct 28, 2015 9:49 am

Tacit Primes?

Post by mwr0707 »

Using this method for finding primes:
primes←
{
(~R∊∘.×⍨R)/R←1↓⍳⍵
}

Is it possible to refactor this as a tacit function?
JohnS|Dyalog

Re: Tacit Primes?

Post by JohnS|Dyalog »

First replace the local assignment of R with an inner dfn:

      {(~R∊∘.×⍨R)/R←1↓⍳⍵}  →  {(~⍵∊∘.×⍨⍵)/⍵}1↓⍳⍵}

Then proceed with stepwise transformations:

      {A f Y} → ( A f{Y})    ⍝ dfn → Agh-fork
{X f Y} → ({X}f{Y}) ⍝ dfn → fgh-fork
{ f Y} → ( f{Y}) ⍝ dfn → gh-atop
{⍺} → ⊣ ⍝ dfn → primitive fn
{⍵} → ⊢ ⍝ dfn → primitive fn

where:
    A is a constant array-valued expression (not containing an ⍺ or ⍵)
    X, Y are array-valued expressions containing ⍺s or ⍵s
    f is a function-valued expression

The only tricky transformation is for /, which is a function/operator hybrid in Dyalog, so X/Y ~→ ({X}/{Y}). Instead, use:
      {X/Y} → ({X}(/∘⊢){Y})

There are several optimisations, which reduce the size of the final "compiled" tacit function. Here's an example:
      {X f g Y} → {X f∘(g) Y}
{ f g Y} → { f∘(g) Y}
JohnS|Dyalog

Re: Tacit Primes?

Post by JohnS|Dyalog »

So for your specific example:
      {(~R∊∘.×⍨R)/R←1↓⍳⍵}              ⍝ local var → inner dfn
→ {{(~⍵∊∘.×⍨⍵)/⍵}1↓⍳⍵} ⍝ { f Y} → (f {Y}) ⍝ atop
→ ({(~⍵∊∘.×⍨⍵)/⍵}{1↓⍳⍵}) ⍝ (A f Y} → (A f {Y}), {⍵} → ⊢, f⊢ → f
→ ({(~⍵∊∘.×⍨⍵)/⍵}(1↓⍳)) ⍝ {X / Y} → ({X}(/∘⊢){Y})
→ (({~⍵∊∘.×⍨⍵}(/∘⊢){⍵})(1↓⍳)) ⍝ {⍵} → ⊢
→ (({~⍵∊∘.×⍨⍵}(/∘⊢)⊢)(1↓⍳)) ⍝ X f g Y → X f∘(g) Y
→ (({~⍵∊∘(∘.×⍨)⍵}(/∘⊢)⊢)(1↓⍳)) ⍝ Y f Y → f⍨Y ⍝ commute
→ (({~∊∘(∘.×⍨)⍨⍵}(/∘⊢)⊢)(1↓⍳)) ⍝ f g Y → f∘(g) Y
→ (({~∘(∊∘(∘.×⍨)⍨)⍵}(/∘⊢)⊢)(1↓⍳)) ⍝ {f ⍵} → f
→ ((~∘(∊∘(∘.×⍨)⍨)(/∘⊢)⊢)(1↓⍳))
mwr0707
Posts: 17
Joined: Wed Oct 28, 2015 9:49 am

Re: Tacit Primes?

Post by mwr0707 »

Thanks John,

I was struggling with how to get the right argument value all the way to the left of the membership function. I hadn't considered the use of the compose operator.

Can we say that by using compose to glue functions together, that we are increasing the leftward "argument throw" of the following commute operator?
JohnS|Dyalog

Re: Tacit Primes?

Post by JohnS|Dyalog »

Yes, that would be a good description.
Note that commute can also be coded as a fork:
      f⍨ ←→ ⊢f⊣
mwr0707
Posts: 17
Joined: Wed Oct 28, 2015 9:49 am

Re: Tacit Primes?

Post by mwr0707 »

And seemingly:
      f⍨ ←→ ⊣f⊢

      f⍨ ←→ ⊢f⊢

      f⍨ ←→ ⊣f⊣
JohnS|Dyalog

Re: Tacit Primes?

Post by JohnS|Dyalog »

I think ⊢f⊣ has the edge because it handles both monadic and dyadic functions derived from ⍨:

      f⍨⍵ ←→  (⊢f⊣)⍵ ←→ ⍵ f ⍵      ⍝ monadic f⍨
⍺f⍨⍵ ←→ ⍺(⊢f⊣)⍵ ←→ ⍵ f ⍺ ⍝ dyadic f⍨
mwr0707
Posts: 17
Joined: Wed Oct 28, 2015 9:49 am

Re: Tacit Primes?

Post by mwr0707 »

      2(÷⍨)4
2

      2(⊣÷⊣)4
1

      2(⊢÷⊣)4
2



I see!
JohnS|Dyalog

Re: Tacit Primes?

Post by JohnS|Dyalog »

For what it's worth, I'm collecting some notes on this subject: http://dfns.dyalog.com/n_tacit.htm.
Contributions welcome.
User avatar
Dick Bowman
Posts: 235
Joined: Thu Jun 18, 2009 4:55 pm
Contact:

Re: Tacit Primes?

Post by Dick Bowman »

Please bear with my ignorance, but could you explain the benefits of tacit as opposed to non-tacit? Readability? Performance?

I see the Wikipedia entry saying "... It is also the natural style of certain programming languages, including APL and its derivatives ..." - which is attributed to Neville Holmes (I remember him sending many posts to the J forum on this topic).
Visit http://apl.dickbowman.com to read more from Dick Bowman
Post Reply