Page 1 of 1
Inlining d-fn references
Posted: Wed Feb 08, 2012 8:32 am
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?
Re: Inlining d-fn references
Posted: Thu Feb 09, 2012 8:16 am
by DanB|Dyalog
There is currently no way to automatically do that.
Why are you trying to do this?
Re: Inlining d-fn references
Posted: Thu Feb 09, 2012 8:37 am
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⍵}
Re: Inlining d-fn references
Posted: Thu Feb 09, 2012 12:42 pm
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
Re: Inlining d-fn references
Posted: Thu Feb 09, 2012 2:17 pm
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.
Re: Inlining d-fn references
Posted: Thu Feb 09, 2012 2:33 pm
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
Re: Inlining d-fn references
Posted: Thu Feb 09, 2012 2:39 pm
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: {+/⍵}
Re: Inlining d-fn references
Posted: Thu Feb 09, 2012 2:44 pm
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.
Re: Inlining d-fn references
Posted: Thu Feb 09, 2012 3:20 pm
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.