Hi Adam. I'm enjoyng the APLCart. Question, sometimes you use parens and sometimes you don't, in cases where I don't think the parens do anything. See Count of Leading Ones vs Fast: The Number of leading ones. Is this significant, or just the way they where from whatever source you got them?
@PaulMansour It is significant. The parentheses indicate a tacit function which can be assigned to a name. Without parens, it is but an expression snippet.
@PaulMansour The performance difference can (unfortunately) be dramatic:
Let me rephrase my question: Why would or should one write (⍋⍋)a over ⍋⍋a in actual code? Is there a reason, or it is just pedagogical? Or to make it easier for future interpreters to optimize? Obviously in a three-train the parens are meaningful in a way they are not here.
@PaulMansour you're right, a monadic atop isn't very useful on its own. it's also equivalent to composition: ⍋∘⍋. however it does fit well in the bigger picture of monadic/dyadic forks/atops, so, it's there for consistency.
@PaulMansour I use tacit as a single term for train and derived function. Conceptually, +/∧\a has two function applications (each being of a single derived function), while (+/∧\)a has a single function application of a single train (which in turn consists of two applications of two derived functions). However, in the interpreter, `+/∧` is a single token, so there's only one application of a single optimised idiom function.
@J.Sallé Nope, the first one is a good old APL expression.
@PaulMansour For performance, one would (unfortunately) have to write ⍋⍋a, while for a function-focused approach, one would write (⍋⍋)a. Hopefully, in 19.0 or some such, they'll have the same performance.
@Adám Well, the grade-up example does indeed have the same performance. I assume extra speed for leading 1's is due to idiom recognition. But what do the parentheses get you? Other than littering your code?
Conceptually having a single function application rather than two must have some advantage. If not potentially performance, then what?
@ngn Just saw this, thanks. Ok, I'm not totally crazy!
@PaulMansour It isn't really the number of function applications that's important, but the Dyalog performance idiom +/∧\ doesn't at all do what it says on the tin, it just makes sure to get the right result for you. So too with all the performance idioms.
@PaulMansour I am a programmer of very little brain, and long expressions bother me, so I like to giving meaningful names to small functions. I'd write something like:
LeadingOnes←+/∧\
result←LeadingOnes boolList
which unfortunately (imho) has much inferior performance to:
OK, I get that, but it is performance and implementation related, not a language issue. I think what I was trying to get at, is the use of parens (and composition) in the APLCart list is to keep everything as a function, not an expression. (Correct?). This is certainly a valid goal. My only concern is that a newbie looking at is going think he needs composition in order to add 1 to an array.
@PaulMansour Right, I strove to keep as much as possible as functions/operators that can be isolated, for ease of use. I do expect users of the APLcart to have at least a very basic understanding of APL syntax. I'm more worried about a newbie being frustrated that f←~∨/, ⋄ f B doesn't work when ~∨/,B works than about them using unnecessary compositions and parentheses.
@Adám I don't want to complicate things, but for items that have composition and paren free expression equivalents, maybe that could be indicated somehow. I wouldn't spend much effort on that though. Once one realizes the goal/format, its all clear.
@PaulMansour I could combine them, or simply take out the functional for — or the fast form, for that sake. The goal should maybe be to teach the APL language, not optimising performance. Feature creep?
@Adám Not sure. I very much like the idea of having everything a function. I would keep that, and perhaps add the expressional equivalent on the same line if it does not get too messy. Either way, I would distinguish between having compose in the add 1 function, which is necessary to make it extractable, and the parens in double grade up, which are not necessary. I would go with the simplest expression that is extrable as a function with direct assignment.
Also, I got confused naming things "fast". This seems very tangential to the language, whereas the functional/expressional contrast is meaningful for all time ( I think)
Is there an easy way to check for the first n numbers that fulfill a condition x without recursion? I think I remember @Adám telling me something of the sorts, but I can't find it here
I actually have 2 inputs though, the number of primes n and a base b. Challenge is to find the first n primes such that b⊥(⌽b⊥⍣¯1⊢prime) is also prime.
I can just hardcode a large enough amount of primes to check for but I'd rather not do that