Tacit Primes?
Tacit Primes?
Using this method for finding primes:
primes←
{
(~R∊∘.×⍨R)/R←1↓⍳⍵
}
Is it possible to refactor this as a tacit function?
primes←
{
(~R∊∘.×⍨R)/R←1↓⍳⍵
}
Is it possible to refactor this as a tacit function?
Re: Tacit Primes?
First replace the local assignment of R with an inner dfn:
Then proceed with stepwise transformations:
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:
There are several optimisations, which reduce the size of the final "compiled" tacit function. Here's an example:
{(~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}
Re: Tacit Primes?
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↓⍳))
Re: Tacit Primes?
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?
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?
Re: Tacit Primes?
Yes, that would be a good description.
Note that commute can also be coded as a fork:
Note that commute can also be coded as a fork:
f⍨ ←→ ⊢f⊣
Re: Tacit Primes?
And seemingly:
f⍨ ←→ ⊣f⊢
f⍨ ←→ ⊢f⊢
f⍨ ←→ ⊣f⊣
Re: Tacit Primes?
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⍨
Re: Tacit Primes?
2(÷⍨)4
2
2(⊣÷⊣)4
1
2(⊢÷⊣)4
2
I see!
Re: Tacit Primes?
For what it's worth, I'm collecting some notes on this subject: http://dfns.dyalog.com/n_tacit.htm.
Contributions welcome.
Contributions welcome.
- Dick Bowman
- Posts: 235
- Joined: Thu Jun 18, 2009 4:55 pm
- Contact:
Re: Tacit Primes?
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).
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