@Adám going back to being an intern after 3 years of cooptation would be weird. For a job, I don’t think I hve a tenth of the qualification required to do that
Also, I know Dyalog is looking for people in the very-long term, and I’m not sure I want to set things in stone 1 month after my graduation ceremony :)
@Ven Instead of asking Dyalog for a job, why don't you email careers@ and ask what Dyalog can offer you? Of course, include as much as you can about your background and experience.
That’s definitely nice of you — looking for jobs abroad has been a bit of a pain — but having golfed a few answers here with your help doesn’t qualify me much :)
@Ven Oh it sure does. We've had a few such people as interns (@marinus and @H.PWiz) , and @Nathan visited 6 weeks ago — and was hired. He now helps customers and is involved in plans for the future. @RichardPark knew nothing of APL when we hired him, and now he's helping customers and writing documentation and guides, and developing showcase applications…
@Ven Yes, yes, that, and you've golfed a lot and been active in the room here, and some lessons too, iirc. You even attended a meet-up. That's way more than most can claim.
I get the feeling that the power operator is quite new, and that it works particularly well with dfns; if that's so, and APL isn't mandated to do tail recursion optimization.. what would be a traditional way to approach a recursive problem?
with an explicit loop? with a right-arrow goto? transform it some other way?
@TessellatingHeckler APL does do tail recursion when (obviously) possible. Dfns can explicitly recurse by calling themselves using ∇ (meaning they don't need a name). Tradfns can recurse using their name. "Mutual recursion" (f calls g and g calls f) also requires naming. Then we have explicit loops using either control structures or goto.
@Adám I believe Dyalog does tail call optimization, but NARS2000 doesn't - but I'm not sure I can find a reference more recent than 2013 for that. Self-recursion with ∇ is what I used, I was just wondering what someone from earlier years would do - I guess explicit loops with control structures is probably my answer
I still need to learn to write code that goes beyond one line :D
@TessellatingHeckler NARS is a research system, not intended for (and in with no attempt to achieve) performance. I think all traditional APL vendors implement tail recursion.
but it's interesting that it is a traditional thing; the first implemented LISP slightly predates the first implemented APL, I think? I'm a lot more interested in these ideas now, than I ever was when "studying" CS
PowerShell my default script doesn't optimise it, nor C#, nor CPython.
@TessellatingHeckler → (which is exactly the same as :GoTo) can take a vector and branches to the line indicated by the first element. If the vector is empty, it does nothing, and execution proceeds as usual.
@TessellatingHeckler Yes, top: is a label, which simple has the effect of making the name top be a constant equal to the line number of the line that top: appears on.
@Adám "branches to the line" - the line number? scratch that, a constant equal to the line number. That's how the →top⍝ jump line that I recognise, must work.
@TessellatingHeckler So it says, top: this line is called so; → go to; (condition); / replicate 0. So if the condition is true, you get 1/0 and if false, you get 0/0.
@TessellatingHeckler Yes, → uses numbers of lines with the first line being number 0.
1/0 evaluates to a 1-element list of a single 0. 0/0 evaluates to the empty numeric list.
→0 means "return" and →⍬ (⍬ is shorthand for empty numeric list) means do nothing — proceed with the next statement.
@TessellatingHeckler Right, each function has sequential line numbers from 0, and are continuously renumbered if additional code is inserted. That was so from day 1 of APL. I have no idea why BASIC has such a silly system.
@TessellatingHeckler Traditionally, line 0 would be a "picture" of how the function (tradfn, that is) is called, including what variable(s) constitutes the result, so branching to 0 essentially means go to the declaration of what needs to be returned — and thus, return it.
@Adám I'm glad you added that explanation; my experience was leading me to "you would want to jump to the end of a function to end it, and to the beginning to restart it. But you don't know where the end of an arbitrary length function is, but you always know it begins at line 0 so that must be a convenience". I have seen that kind of line at the beginning of a trad-fn, I think, without understanding the syntax of it
@Adám I think I can read it; have I seen variations with more than a single left and right arg ? Is there an official connection between the result at the beginning of line 0, and the return value? I imagine there must be, but I'm suspicious it might be "the last thing evaluated is returned" and convention to name them the same in both places.
@TessellatingHeckler In Dyalog, result and right argument may be name lists, e.g. (res1 res2)←FnName (arg1 arg2), and there is additional syntax for "shy" (we can get back to what that means) results and optional left arguments, and also to declare locals. But the header is strict: The function returns whatever is named as in the stated result, no matter what happens in the function.
@TessellatingHeckler Don't confuse tradfns (traditional functions) with dfns (a relatively new Dyalog invention). The latter do not have any name for their result and instead, the first non-assignment is returned (bar guards and errors).
@Adám OK, neat. "shy" results can wait for a while :) Yes, trad-fns and d-funs are different, and from how much I see dfn code around, people could almost have called them "more funs" (boom boom)