Tacit Primes?

For users of dfns, both novice and expert

Tacit Primes?

Postby mwr0707 on Tue Dec 06, 2016 2:07 am

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

Is it possible to refactor this as a tacit function?
mwr0707
 
Posts: 16
Joined: Wed Oct 28, 2015 9:49 am

Re: Tacit Primes?

Postby JohnS|Dyalog on Tue Dec 06, 2016 10:17 am

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?

Postby JohnS|Dyalog on Tue Dec 06, 2016 11:19 am

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↓⍳))
JohnS|Dyalog
 

Re: Tacit Primes?

Postby mwr0707 on Tue Dec 06, 2016 7:20 pm

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?
mwr0707
 
Posts: 16
Joined: Wed Oct 28, 2015 9:49 am

Re: Tacit Primes?

Postby JohnS|Dyalog on Tue Dec 06, 2016 9:15 pm

Yes, that would be a good description.
Note that commute can also be coded as a fork:
      f⍨ ←→ ⊢f⊣
JohnS|Dyalog
 

Re: Tacit Primes?

Postby mwr0707 on Thu Dec 08, 2016 12:34 pm

And seemingly:
      f⍨ ←→ ⊣f⊢

      f⍨ ←→ ⊢f⊢

      f⍨ ←→ ⊣f⊣
mwr0707
 
Posts: 16
Joined: Wed Oct 28, 2015 9:49 am

Re: Tacit Primes?

Postby JohnS|Dyalog on Thu Dec 08, 2016 1:09 pm

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⍨
JohnS|Dyalog
 

Re: Tacit Primes?

Postby mwr0707 on Thu Dec 08, 2016 2:18 pm

      2(÷⍨)4
2

      2(⊣÷⊣)4
1

      2(⊢÷⊣)4
2



I see!
mwr0707
 
Posts: 16
Joined: Wed Oct 28, 2015 9:49 am

Re: Tacit Primes?

Postby JohnS|Dyalog on Fri Dec 09, 2016 7:30 am

For what it's worth, I'm collecting some notes on this subject: http://dfns.dyalog.com/n_tacit.htm.
Contributions welcome.
JohnS|Dyalog
 

Re: Tacit Primes?

Postby Dick Bowman on Fri Dec 09, 2016 2:12 pm

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
User avatar
Dick Bowman
 
Posts: 235
Joined: Thu Jun 18, 2009 4:55 pm

Next

Return to Functional Programming

Who is online

Users browsing this forum: No registered users and 1 guest