Inlining d-fn references

For users of dfns, both novice and expert
Post Reply
marc
Posts: 8
Joined: Wed Nov 09, 2011 8:36 pm

Inlining d-fn references

Post by marc »

Let's say that I have the following d-fns defined:

      foo ← {+⌿⍵}
bar ← {2*⍨foo⍵}

foo ⍳3
6
bar ⍳3
36

Can the call to 'foo' in 'bar' to be inlined—either through the editor or a system function—to yield,

      {2*⍨{+⌿⍵}⍵}

or similar?
DanB|Dyalog

Re: Inlining d-fn references

Post by DanB|Dyalog »

There is currently no way to automatically do that.
Why are you trying to do this?
marc
Posts: 8
Joined: Wed Nov 09, 2011 8:36 pm

Re: Inlining d-fn references

Post by marc »

Hi Dan,

Thanks for your reply.

This is a refactoring question—I sometimes have a number of (very) short d-fns defined over the course of a session that are not intended for direct use but rather contribute to a larger expression. Occasionally the larger expression is more meaningful when the expressions it references are "inlined".

In the example I provided above, this would really be a two step process:

      foo ← {+⌿⍵}
bar ← {2*⍨foo⍵}

(1)
      {2*⍨{+⌿⍵}⍵}


(2)
      {2*⍨+⌿⍵}


Hopefully the motivation here is clear: while exploring a problem, it might be useful to name the reduction something apropos the domain in question (though obviously not 'foo'!); when done, it can be convenient to fold callees into their caller. In other words,

      {2*⍨+⌿⍵}

is more expressive than

      {2*⍨foo⍵}
JohnS|Dyalog

Re: Inlining d-fn references

Post by JohnS|Dyalog »

Hi Marc,
Thanks for this suggestion: it has provoked some interesting ideas, which we have logged as an internal RFE (Request for Enhancement).
NB: Dfns enjoy "lexical scope", so take care when inlining functions that reference external (free) names:

      v←'outer'                 ⍝ outer name "v"                  
func←{v ⍵} ⍝ fn dereferences name "v"
{v←'inner' ⋄ func ⍵}'v' ⍝ outer fn dereferences outer v
outer v
{v←'inner' ⋄ {v ⍵}⍵}'v' ⍝ inner fn dereferences inner v
inner v
User avatar
Dick Bowman
Posts: 235
Joined: Thu Jun 18, 2009 4:55 pm
Contact:

Re: Inlining d-fn references

Post by Dick Bowman »

Call me stupid (many do), but it's often worth just trying things...

foo ← {+⌿⍵}
bar ← {2*⍨foo⍵}
foo ⍳3
3
bar ⍳3
9
{2*⍨{+⌿⍵}⍵} ⍳3
9

So, either the first post here is wrong or I have found a way to do something impossible. What puzzles me is the original assertion that 36=bar ⍳3.

I've nested dfns like this for a long time - stopping when the line turns impenetrably turgid.

Maybe I'm missing the point.
Visit http://apl.dickbowman.com to read more from Dick Bowman
marc
Posts: 8
Joined: Wed Nov 09, 2011 8:36 pm

Re: Inlining d-fn references

Post by marc »

Hi Dick,

Sorry, I should have clarified that index origin was 1:

      ⎕io←1
foo ← {+⌿⍵}
bar ← {2*⍨foo⍵}
foo ⍳3
6
bar ⍳3
36
{2*⍨{+⌿⍵}⍵} ⍳3
36
⎕io←0
foo ⍳3
3
bar ⍳3
9
{2*⍨{+⌿⍵}⍵} ⍳3
9
JohnS|Dyalog

Re: Inlining d-fn references

Post by JohnS|Dyalog »

I missed the point first off, too. I think Marc is saying: yes we can inline small dfns but Wouldn't-It-Be-Nice-If there were a button on the editor to do it for me? For example, I could right-click the name foo and select a menu-item to have it replaced by its defn: {+/⍵}
marc
Posts: 8
Joined: Wed Nov 09, 2011 8:36 pm

Re: Inlining d-fn references

Post by marc »

Hi John,

Glad to hear that folks are interested in this functionality.

How tricky do you think it would be to resolve scoping issues as part of a refactor? Presumably some sort of disambiguation prompt ought to be presented so that the programmer can clarify their intended binding(s)....

Re: "Wouldn't-It-Be-Nice-If there were a button on the editor to do it for me?" -- precisely.
JohnS|Dyalog

Re: Inlining d-fn references

Post by JohnS|Dyalog »

> How tricky do you think it would be to resolve scoping issues as part of a refactor?

I would have to have a biggish think about this before giving a sensible opinion. In general, one could probably say whether a requested in-lining was "safe" or not. A body of code that made an explicit (or implicit in the way that ⍳ implicitly uses ⎕IO) reference to a name external to itself, would be unsafe. Given a potentially unsafe substitution, I'm not sure how much more help the editor could reasonably be expected to give.

This is an example of the classic "name capture problem", present in many languages, including traditional APL2-style defined operators.
Post Reply