I downloaded dyalog for mac, and when I run ⊂ 2 3 it does not display the result with box characters around it, even though the examples under help for Enclose do show them. Do I need to change some setting?
@Jonah Mostly the IDE, but I'm on Windows where the default IDE is a it more evolved than RIDE. While, VS Code with APL extensions isn't bad, I really need the interactive part of development.
Finally, is there an online equivalent of the J dictionary with more info on each verb? And (bonus) a way to jump directly to that or see the info inline from the IDE?
Perfect. Oh one more. Any tips for learning given that I already know J well? I found the free online "Mastering APL" but at 800 pages that's a bit overwhelming. I can probably figure most things out with the help you linked and analogizing with J, but figured I'd ask if there's any key pieces of reading I shouldn't miss.
@Jonah While APL started with 1 due to the legacy of mathematics, I think the need for availability of 0 was quickly recognised once Iverson's notation became a programming language, especially when dealing with number bases. But then it turned out that giving the users a choice was even worse, so Iverson settled on 0 for J which was intended as a programming from the outset.
@Jonah No. I prefer 1. I don't mind so much having to adjust my indices, other than for golfing purposes. In fact, I wouldn't even mind dispensing with the possibility of a mod-based cyclical indexing; make 1 the first element and ¯1 the last.
The 0th element could conveniently be the prototypical/fill element.
I think that indexing from 0 in any language was a mistake that was routinely indulged in because it made pointers and arrays "interchangeable". C is the most visible example of this, but it's often the way compilers for other languages handle things "behind the scenes"
It's simply not natural to think of arrays with zero-indexing.
Yes, but I question whether being able to convert between types so casually is necessarily a good thing. There's something to be said for Pascal's "type fascism".
How would I generate a list of rotations of a matrix in a compact way?
For example, given `m←4 4⍴⍳16` and I want `(¯1⊖m)(1⊖m)(1⌽m)(¯1⌽m)`. Is there a better way? Seems like it should be possible to express this as a cartesian product of operations and left-args somehow.
@Adám - It is. I have no objection to being able to use non-integers to index arrays, but I'm not convinced that not requiring that to be stated explicitly is a good thing. In Pascal, I'd be able to say VAR FOO: ARRAY[BOOLEAN] OF whatever; to explicitly say that I'm going to index FOO with a boolean.
My experience suggests that such restrictive use of types protects against some errors that are common in C-family languages.
@xpqz 4⍴⊂m makes a vector of 4 nested copies of m. ⌽⍉ means turn by 90 deg. {⌽⍉⍵}\ is a scan that leaves m[0] as is, turns m[1] once, m[2] twice, etc. i think you already understand 1⌽¨. and finally {⍉⌽⍵}\ turns the matrices back in the other direction.
(replaced "rotate" with "turn" to avoid clash with apl terminology)
So looking at the final bit {⌽@i ⍵⊢m} I understand what it must do, but not quite how it works. It should 'apply' the valid moves to generate the new state.
@xpqz {} is applied to each (¨) location with which we should swap the 0
so, @i⍵ selects the two cells of the matrix that should be swapped
⌽@i⍵⊢m swaps them
here ⌽ applies to the list of values selected from the matrix, so the axes on which i (the zero) and ⍵ (the other cell) lie don't matter. i mean, there's no need for ⊖.
d can be generated in a golfier way: ⊢/4 2⍴1-⍳3 3 but i wrote it as (0 1)(1 .. for "readability" :)
@xpqz - Readability is in the eye of the beholder. I'll bet @Adám doesn't have any problem reading APL code, no matter what. On the other hand, I still have to work my way through it one step at a time...
I agree. If you don't speak Chinese, reading it would be a challenge. But very readable for the natives. I'm getting to a point where I can decipher APL (slowly). The hard bit is the reverse -- I don't think I'd arrived at @ngn's solution for a while.
But someone (maybe here?) said that if a line of APL expresses the same logic as 50 lines of C, it's not unreasonable to spend longer reading and writing that line of APL.
@xpqz - Oh, yes - I tend to come up fairly quickly (for me) with the "naïve" solutions in APL for a particular problem; I'm familiar with the basic elements of the language (at the TradAPL level), but I haven't "internalized" the idioms, never mind the golfations thereof.
Once I see a golfed solution, I can generally work through it to understand what's happening - but originate such? Not within my capabilities (yet).
@JeffZeitlin I often start with a naïve solution & either golf that or after that spend time thinking of different approaches. Starting with the best approach pretty much never happens
@Adám Brings up a question I've been wondering about. For those of you who write and read trains alot, does it become routine, or do you generally start with a relatively verbose expression and start trying remove the alphas and omegas?
@PaulMansour both happen. I often start with a dfn, convert it to a train, and work on the train, but sometimes starting with a train is easier due to the problem at hand
@PaulMansour This is part of the reason I can't deal with the backtick keyboard or "rolling" shifting keys (having to let go of them and press them in a specific order). I tend to hold my APL key depressed and type multiple symbols in a row.
@dzaima - By "naïve" approach, I'm referring to seriously basic stuff - almost like translating a Pascal or BASIC solution into APL, rather than using the kind of thing found in e.g., APLCart. Even "standard" stuff like outer and inner products don't show up until the "first refinement" of the naïve solution.
in the cases when i don't start with a naïve approach, i already have a specific algorithm/idea in mind (or have spent a while on coming up with one - a naïve solution often helps thinking of better algorithms)
for example, for this CMC i had these "steps" of golfing saved (first half in dzaima/APL, second in Dyalog; there were other things i tried, but only saved these)
(quick notes on dzaima/APL used there - ⊤A: convert to binary; ⌿: {⍺/⍵}; f⍤g: {f ⍺ g ⍵}; f⍛g: {(f ⍺) g ⍵}; A⍨: {A} (with original context of course))
Thanks for the warm welcome @Adám; been meaning to join the chat room for quite some time! I'd be absolutely thrilled, and honored, to intern at Dyalog. I was unable to find a place to apply on the website though. Is there an application one should fill out?
/me is busily keying in the APL source for Star Trek, and is seeing some optimizations already, but wants to ask some questions before applying them. AFTER he gets it all keyed in and verified working.
@Adám - Oh, I fully intend to preserve the version I'm keying in for historical interest. But, for example, there's a random function that was a duplicate from BASIC's, which I think is functionally equivalent to roll with ⎕IO←0; that's one possible 'fix' I'd apply to a copy.
@Adám - ?0 would mimic the BASIC RND(), yes, but the way it's actually being used elsewhere in the program, I believe that I can replace calls to ⌊(RND×b)+1 with a simple ?b. There's also the use of SIN and COS which are just straight-up aliases for the indicated ○ functions.
And a few other things.
Like there's one place where the BASIC calculation was just copied straight up, but APL's order of evaluation changes what's being calculated; I'd end up correcting that as well.
@Adám - Yes. IIRC (I'm about a hundred lines beyond it, and using the del editor at the moment), it calculates (RND×20+20) which in BASIC would multiply the random by 20 and add 20; in APL, it's going to multiply the random by 40.
@Adám Thanks; will do so after my upcoming big deadline! Quick question: It sounded like me being in the UK was a factor in the invitation, though you did say it'd be online for now... I was intending to return to California (home) this weekend; would it be preferable (as far as an internship is concerned) to stay?
@AviF.S. We've had remote interns. The main locality issue is a political one; getting visas. (Also, are there flights from UK to US now?) The internship wouldn't have to be right this instant either.
@JeffZeitlin I thought Trump ordered a stop to all European flights, besides for UK (failing in) enforcing total lockdown, allowing leaving home only for 1) infrequent necessary shopping 2) ONE form of exercise a day 3) provide or get medical help 4) travel to/from key work — where "key" means necessary for country to survive.
All of that is true! Though there remain flights for US nationals and their family stuck abroad, at least coming from the Schengen Area and other approved ones...
@Adám - It's questionable whether he had the power to order that at all; even assuming that it's de facto valid, there has been an exception for repatriating Americans who would otherwise have been stranded overseas. I believe that the UK is no longer an exception, and I believe that Italy, for example, may have closed off even the repatriation option with their own lockdown.
I believe that former Speaker of the House Newt Gingrich is currently stuck in Rome because of it.
Must say, I'm terribly ashamed that the first time I finally do join the Orchard, I completely distract everyone with totally off-topic conversations...
@Adám Haha, thanks! I looked it up right after, but was afraid of falling behind when I was actually sending the message
@JeffZeitlin Phew! Well, nonetheless, a different topic to attempt to be helpful and redeem my reputation: I'd been meaning to suggest, esp. to @Adám since you made it and are the Dyalog representative here, to add APLcart under the set of "Getting Started..." or "How do I..." links on TryAPL.
I've found it to be a nice resource, and it's listed under dyalog.com/introduction.htm under "Getting Started" as well as one of the Dyalog talks on Youtube. However, I imagine many people getting started begin on TryAPL.
Not only are they missing out but the following link is given instead: Search idiomatic APL expressions under "How do I...?" Potentially an opportunity there to help get it out to more newbies!
@Adám Re the previous bit: Were I accepted, it'd be a real bummer to have to intern remotely, but good to know it's a possibility. As I'm trying to weigh the pros/cons of returning given the new opportunity, do you have a sense of the chances of being accepted? That is, to figure out if it's worth staying just in case I get in!
@Adám I see, makes sense! As for the returning home, do you have a sense of the acceptance rate? To figure out whether it's worth changing plans to stay (haven't bought the ticket yet) in the hopes of more APL...
@AviF.S. I think we mostly accept qualified applicants. At the moment, your location would not matter, as it'll have to be remotely anyway. Only upside to stay here is time zone differences. When you have the time, just send an email with your general background, current APL experience, and what your future plans might be.
What's happening here? I get that in (4 2 3)÷(1 1 5)(1 5 1)(5 1 1) the 4 2 3 is being divided by the "columns" of the boxes on the right (if they were stacked), but I don't understand why. Especially confusing is why this works for boxes, which in general won't have homogenous length.
Related: In J you can do 4 2 3 % 3 3 $ 1 1 5 1 5 1 5 1 1 to get the same result (without boxes), but in APL 4 2 3 ÷3 3 ⍴1 1 5 1 5 1 5 1 1 gives a rank error. I would have expected the latter to work but not expected the boxed version linked above to work. Can you set me straight?
@Adám Ah, good oh. That {1=≢⍵:⍺ ⋄ '-'}⌸'aabbc' has an output of --c for finding the letters with a count of 1, but {1=≢⍵:⍺}⌸'aabbc' has no output at all, where I'd expect c alone; but where is the computation going, what's happening?
@TessellatingHeckler Since at least one of the calls causes the condition to give 0, that call has no result, and so an overall result cannot be assembled.
@ngn Yeah, nope. Don't do that unless you're golfing. And certainly, that is bad advice to a Jer.
@TessellatingHeckler You may want to use (∪(/⍨)1=⊢∘≢⌸)'aabbc' instead.
"the leading axis model and its various incompatibilities with APL had been a major reason to break with APL and create a new language." ... interesting
@dzaima thanks, that does help. So given that it looks like the "leading axis conformability" is happening automatically when the args are boxed (ie, the (4 2 3)÷(1 1 5)(1 5 1)(5 1 1) version) but not when they're raw. Is this just a historical matter that the feature could be bolted on to the boxed version because it was added later?
@Adám I don't know; yes it should be an empty list .. of whatever the APL equivalent of empty string or System.Object[] is, I suppose. I'm still unsure why {1=≢⍵:⍺⋄''}⌸'aabbc' does work, and the output looks like c but has a tally of 3
@Jonah Not really. The behaviour comes naturally from APL's traditional scalar extension plus viewing "boxes" not as solid items but simply as having elements that are themselves arrays.
@TessellatingHeckler Because the result becomes '' '' 'c'
"The behaviour comes naturally from APL's traditional scalar extension plus viewing "boxes" not as solid items but simply as having elements that are themselves arrays." But by that same argument it seems like it should work without the boxes too... what am I missing?
"APL did not see higher rank arrays as collections of lower rank arrays." oh so a matrix is its own 2D thing, not a collection of arrays of the same length?
@Jonah Exactly. You can see evidence of this in the behaviour of ∊ (membership) which, for each rank zero element in the left argument, checks if such a rank 0 element exists in the right argument.
Not even. I think it is quite easy to implement too. (I can ask.) It is simply conservatism in making any language changes. Notice that ⌸ (Key) was added in version 14.0 by Roger Hui (of J fame) and does treat arrays as collections of arrays of one lesser rank, so you could get the unique major cells with ⊣⌸, but it took until 17.1 before ∪ (Unique) was amended to behave the same. Until then, it only handled vectors. There was nothing preventing the extension other than conservatism.
"You can see evidence of this in the behaviour of ∊ (membership) which, for each rank zero element in the left argument, checks if such a rank 0 element exists in the right argument." It's funny I've found situation in J where I wished it behaved like this. Related: Wanting to just "sum up" an higher-dim object, regardless of shape, but having to flatten , first. Ofc, I get how this desire goes against the grain of the J / array-think world view, but it's weirdly persistent.
@Jonah The problem is that it is easy to flatten first if that's what you want, but with a primitive that does it for you, the opposite becomes impossible. Another example is A⍴B which is like J's A$,B
"but with a primitive that does it for you, the opposite becomes impossible." Yeah, I get that part. My quibble is that, mentally, I don't want to flatten the thing and then add the elements, because thing shape is part of its identity, and I don't want to make a mental shift like that. I want to "add things elements in a shape-ignoring way". So in J terms I want another adverb to modify the meaning of +/, rather than destructure my thing first.
I know I could write one... I'm just talking about language design preferences.
@Jonah Ah, that's where you want to use another suggested extension, structural under. It is like J's Dual, but on the structure of an array rather than on its value. So e.g. A∊⍢,B would first ravel A and B, then do the membership, and then put the corresponding Boolean values back into the structure they came from. (Of course, this wouldn't matter with APL's current definition of ∊.)
@Jonah But any meaningful name would be longer than typing it out. It is simply All←∘, so you can do +/All myMatrix — but why not write +/∘,myMatrix or even +/,myMatrix ?