What fun. I was introduced to APL in 1966. Computer Science option of Engineering Science at the University of Toronto. First year it was offered. The text for Advanced Programming was the "yellow book" A Programming Language (Ken Iverson's original book). Which I still have. One assignment I remember was to write a polyphase sort/merge, which I seem to recall took about 10 lines of code. I subsequently met Ken when he was an advisor to his son Eric, who was our (Amdahl Corp.) customer, running the Sharp APL time-sharing service in Toronto. Amdahl's corporate parts inventory system ran on Sharp APL in the early years.
I am a 45 years of experience APL developer. I will admit that this refactoring process can be a lot of fun. Who doesn't like puzzles? But I am breaking ranks here to state that the original code is superior, after removing the excess parenthesis, from a production code maintenance point of view. By itself this original logic is instantly understandable. Your refactoring utilizes many new APL features (trains, forks, etc.) that Dyalog has only introduced in the last decade or so. I feel that clarity is lost with these new whizbang syntaxes. Ask yourself, what is gained? One line of code that is half a dozen characters shorter? I do see a reason for such refactoring if the function in question is used repeatedly and speed of calculation is important. If it is run 1,000, 10,000 or 100,000 times in an app. Perhaps these new Dyalog features do run much faster. There is only one way to find out for sure; run Profile timing tests. Of course, another solution is to just go out and buy a new, faster computer.
@@tonyennis1787 I can understand any modern APL syntax. The issue is one of time. 20th century APL syntax is less massive. I can grasp any of it in seconds. 21st century APL, as promoted by Dyalog APL, takes me a minute or two to decipher. In maintenance mode those minutes add up. One must also consider that the author (myself) may not be doing the maintenance. Often it is the "new guy" just hired out of college. Sometimes I sense that new Dyalog syntax features are solutions looking for problems. Don't misunderstand my thoughts about what Dyalog is doing. I am delighted they are pushing the envelope of APL syntax. They seem to be the only organization doing this today. I can choose to use the new syntaxes or not. Progress is defined as three steps forward and only one or two steps backward. APL developers face two import issues. Performance vs. maintainability. Once the coder grasps that APL code should not look like Basic code, unless you seek dog-slow applications, then I submit that maintainability is more important for expanding APL to a wider audience; for example, to the corporate world that writes the checks we all depend upon. Last example. I sprinkle structural control statements all over in my production code .... :IF, :ELSE, :THEN, :ENDIF, etc. This is not state-of-the-art APL. I am more concerned with avoiding buggy code then I am with delivering "elegant" APL. Midnight telephone calls from frustrated clients must be minimized to preserve my sanity..
I'm also a 45 yr APL programmer. I share most of your thoughts. Connor is doing a great job with the podcast and these videos in promoting APL. But (and certainly wrt the new or novice programmer), he (and frankly others) are adding levels of complexity that just (in my opinion) aren't needed (at least for a huge majority of practical applications, or for most people looking to learn the language from an approachable level). I guess if you're raised in a world of atops, forks, trains (as he likely was) it's 2nd nature, but if you were raised in APL these add'l tools of thought take more time to decipher (let alone construct) than they're worth (especially given for the most part, they're universally slower to run - and sometimes by orders of magnitude when put to problems of scale. It's great for mental masturbation (as was always the case with APL), but for this problem, all that was needed was a simple, direct, straightforward outer product w/o the window dressing. Here are 3 solutions: original, outer product dfn, and Connor's tacit solution. Using 999, the cnfm timing were 0, 45%, 3000%. i guess i shouldnt be so surprised the simpler fn beat the outerproduct, but it's ok here as the outerproduct would allow for a lot less chaining of OR commands if the left argument were a longer vector (and yes, i do realize that outer product could/would blow up if the problem got real large). I dont mean to be taking a shot at Connor, i just think it would be a lot more instructive to show the basic solution w/o tack, compositions, etc, and then go from there to that type of solution set. tryapl.org/?clear&q=%7B%2B%2F((0%3D3%7C%E2%8D%B3%E2%8D%B5)%E2%88%A80%3D5%7C%E2%8D%B3%E2%8D%B5)%2F%E2%8D%B3%E2%8D%B5%7D999%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%203%205%7B%2B%2F%E2%8D%B80%3D%C3%97%E2%8C%BF%E2%8D%BA%E2%88%98.%7C%E2%8D%B3%E2%8D%B5%7D999%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20((%E2%88%A8%E2%8C%BF3%205%20%E2%88%98.(0%3D%7C)%E2%8A%A2)%2B.%C3%97%E2%8A%A2)%E2%8D%B3999&run
Fascinating. I never learnt APL, I started with J and there, trains (forks and hooks), are things you meet and get used to right from the start. Not only are they good for refactoring but I suspect that they aid better algebraic thinking. I was quite surprised to find out that they were "relatively new" to the world of APL.
I stumbled upon APL/360 back in 1973 at the University of Florida. At first, I was using just a regular typeball, and then splurged and bought an APL typeball. I was never taught APL in a classroom (PL(c), FORTRAN and TI 980a assembler), but I was amazed that I could invert a matrix with just an overstrike symbol. Editing was fun, since one hit the attention key to erase everything to the right. IIRC, the alpha and omega symbols were reserved, we did a lot of goto label. I was a UNIX/C systems programmer before dropping out to teach HS math.
Thank you, man. just got into this coding stuff for real like a few days ago and its taking off! People are right to be concerned about coding and technologies in the modern age but APL seems to solve those problems. Poetry in code.
If you listen to ArrayCast, you will hear long time APLer Stephen Taylor talk about how APL is like poetry: www.arraycast.com/episodes/episode-00-why-i-like-array-languages (I think this is the right episode)
i seem to recall something i have read once about feynman. apparently in the early days of computer science feynman and iverson (the inventor of apl) once met and feynman said something to the effect of: "ok, so you guys are doing this new thing called computer science. but what are you actually doing? see, we in physics have all these formulas and math and it helps us think about things and nature. we can look at a short mathematical formula and see everything in it in one short line of letters and symbols. and that is what we do all day long, we do these formulas. do you computer guys have anything like that?" and iverson of course said, no we dont and invented apl. now i dont know if that is true or a legend, but it seems to make sense to me. a popular question among aplers is what their favourite symbol is. most say something like the christmas tree or something like that. or you could say filter or something. my favourite is the less or equal symbol (or greater or equal). because that shows the actual true spirit of apl: a notation that is concise, like you would write it on a piece of paper with pen when doing math, that can have two meanings in one symbol combined, but expresses one concise thought.
Looking forward to watching the video on the different combinators! I didn’t understand the words you used about N-trains and tines. I have more work to do.
@@code_report Thank you for the explanation. I just watched the first 3 minutes (or, the second 'slide' of 3 minutes. It was from 53s to 4m0s) of Dyalog '13: Train Spotting in Version 14.0 - ua-cam.com/video/7-93GzDqC08/v-deo.html between your comment and those 3 minutes I think I have a perfect understanding. It is my understanding that trains are part syntactic sugar and part opportunity for interpreter to optimize. I can visualize what they do, now. Also stoked about learning of the 'parse' directive in Dyalog. That'll be really helpful with grokking the syntax here.
what interests me about APL is how the workflow works using non-ASCII characters ? and also what real life use cases apl has - is it used along side another programming language to do these efficient processes?
It appears to see most use in financial processing, but that may just be because other fields are less talkative. An example of using it alongside other languages is Co-dfns, which like Futhark can build libraries for GPU and multicore processing to use in other languages.
Were you to solve this problem yourself right now, without having seen it before, would you write the final piece of code right away, or would you start with more basic code and refine it? If the latter, what do you think your starting point would be?
I would have built it up point free from the beginning, and once I had one of the modulus expressions like (3|⊢)⍳9 I probably would have moved directly to 3 5∘.(0=|)⍳9. And then I would have ended up at the same point.
I can see what it did; it paired arguments and results of the left function. Sadly, I can't tell you how it expressed that; looks like magic numbers to me. A similar operation in BQN might look like: > (∨˝ 0= 3‿5 |⌜ ⊢)⍟1‿0 (1+↕9) Here ⍟1‿0 applies a function on its left both 1 and 0 times, and > unboxes the lists to a matrix, lining them up.
“Point Free” as in no pointers or named variables are used. A example of point free programming is in forth where instead of adding X and Y, you have X and Y in the computers memory stack and apply the + operator to them putting the result back on the stack for another operation, where as in C, the computer must load X and Y into memory then add them then assign the result somewhere else to save it.
You can, which reduces the number of modulo operations, but then you need to check for other values than 0. This method has its place when working with a processor where division cannot be pipelined and speed matters more than source code complexity. E.g. 15 here is the least common multiple of 3 and 5; were you planning to explain that?
JavaScript Solutions: // Using reduce const euler1st = n => Array.from({ length : n }).reduce((acc, val, index) => { const value = index + 1; return (value % 3 === 0 || value % 5 === 0) ? acc + value : acc; }, 0); // Using precedural const euler1st = n => { let result = 0; for (let i = 1; i
quick q/k4 solution: {x wsum (in[0]mod[;3 5]::)'[x]} slightly longer, use of function composition {x wsum not min x mod/: 3 5} {x wsum~&/x .q.mod/:3 5} /k4 is missing mod
Thanks for the video, you got me again running gnu-apl (I know you something else), even though I'm late😅. Here is another solution {+/⍵/⍨0=×/⊃(⊂3 5)∣⍵} ⍳99
I dont even know what APL is, but i couldn't stop watching
What fun. I was introduced to APL in 1966. Computer Science option of Engineering Science at the University of Toronto. First year it was offered. The text for Advanced Programming was the "yellow book" A Programming Language (Ken Iverson's original book). Which I still have. One assignment I remember was to write a polyphase sort/merge, which I seem to recall took about 10 lines of code. I subsequently met Ken when he was an advisor to his son Eric, who was our (Amdahl Corp.) customer, running the Sharp APL time-sharing service in Toronto. Amdahl's corporate parts inventory system ran on Sharp APL in the early years.
I am a 45 years of experience APL developer. I will admit that this refactoring process can be a lot of fun. Who doesn't like puzzles? But I am breaking ranks here to state that the original code is superior, after removing the excess parenthesis, from a production code maintenance point of view. By itself this original logic is instantly understandable. Your refactoring utilizes many new APL features (trains, forks, etc.) that Dyalog has only introduced in the last decade or so. I feel that clarity is lost with these new whizbang syntaxes. Ask yourself, what is gained? One line of code that is half a dozen characters shorter?
I do see a reason for such refactoring if the function in question is used repeatedly and speed of calculation is important. If it is run 1,000, 10,000 or 100,000 times in an app. Perhaps these new Dyalog features do run much faster. There is only one way to find out for sure; run Profile timing tests. Of course, another solution is to just go out and buy a new, faster computer.
I agree with you in principle, but do you really consider features introduced in 2011 too new to understand or use?
@@tonyennis1787 I can understand any modern APL syntax. The issue is one of time. 20th century APL syntax is less massive. I can grasp any of it in seconds. 21st century APL, as promoted by Dyalog APL, takes me a minute or two to decipher. In maintenance mode those minutes add up. One must also consider that the author (myself) may not be doing the maintenance. Often it is the "new guy" just hired out of college.
Sometimes I sense that new Dyalog syntax features are solutions looking for problems. Don't misunderstand my thoughts about what Dyalog is doing. I am delighted they are pushing the envelope of APL syntax. They seem to be the only organization doing this today. I can choose to use the new syntaxes or not. Progress is defined as three steps forward and only one or two steps backward.
APL developers face two import issues. Performance vs. maintainability. Once the coder grasps that APL code should not look like Basic code, unless you seek dog-slow applications, then I submit that maintainability is more important for expanding APL to a wider audience; for example, to the corporate world that writes the checks we all depend upon.
Last example. I sprinkle structural control statements all over in my production code .... :IF, :ELSE, :THEN, :ENDIF, etc. This is not state-of-the-art APL. I am more concerned with avoiding buggy code then I am with delivering "elegant" APL. Midnight telephone calls from frustrated clients must be minimized to preserve my sanity..
@@vessirvine2828 Thank you for this well reasoned and well-measured response.
I'm also a 45 yr APL programmer. I share most of your thoughts. Connor is doing a great job with the podcast and these videos in promoting APL. But (and certainly wrt the new or novice programmer), he (and frankly others) are adding levels of complexity that just (in my opinion) aren't needed (at least for a huge majority of practical applications, or for most people looking to learn the language from an approachable level). I guess if you're raised in a world of atops, forks, trains (as he likely was) it's 2nd nature, but if you were raised in APL these add'l tools of thought take more time to decipher (let alone construct) than they're worth (especially given for the most part, they're universally slower to run - and sometimes by orders of magnitude when put to problems of scale. It's great for mental masturbation (as was always the case with APL), but for this problem, all that was needed was a simple, direct, straightforward outer product w/o the window dressing. Here are 3 solutions: original, outer product dfn, and Connor's tacit solution. Using 999, the cnfm timing were 0, 45%, 3000%. i guess i shouldnt be so surprised the simpler fn beat the outerproduct, but it's ok here as the outerproduct would allow for a lot less chaining of OR commands if the left argument were a longer vector (and yes, i do realize that outer product could/would blow up if the problem got real large). I dont mean to be taking a shot at Connor, i just think it would be a lot more instructive to show the basic solution w/o tack, compositions, etc, and then go from there to that type of solution set. tryapl.org/?clear&q=%7B%2B%2F((0%3D3%7C%E2%8D%B3%E2%8D%B5)%E2%88%A80%3D5%7C%E2%8D%B3%E2%8D%B5)%2F%E2%8D%B3%E2%8D%B5%7D999%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%203%205%7B%2B%2F%E2%8D%B80%3D%C3%97%E2%8C%BF%E2%8D%BA%E2%88%98.%7C%E2%8D%B3%E2%8D%B5%7D999%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20((%E2%88%A8%E2%8C%BF3%205%20%E2%88%98.(0%3D%7C)%E2%8A%A2)%2B.%C3%97%E2%8A%A2)%E2%8D%B3999&run
Fascinating. I never learnt APL, I started with J and there, trains (forks and hooks), are things you meet and get used to right from the start. Not only are they good for refactoring but I suspect that they aid better algebraic thinking. I was quite surprised to find out that they were "relatively new" to the world of APL.
I stumbled upon APL/360 back in 1973 at the University of Florida. At first, I was using just a regular typeball, and then splurged and bought an APL typeball. I was never taught APL in a classroom (PL(c), FORTRAN and TI 980a assembler), but I was amazed that I could invert a matrix with just an overstrike symbol. Editing was fun, since one hit the attention key to erase everything to the right. IIRC, the alpha and omega symbols were reserved, we did a lot of goto label. I was a UNIX/C systems programmer before dropping out to teach HS math.
Thank you, man. just got into this coding stuff for real like a few days ago and its taking off! People are right to be concerned about coding and technologies in the modern age but APL seems to solve those problems. Poetry in code.
Poetry in human language is I believe about saying as much as possible with fewer written words. APL is like that.
If you listen to ArrayCast, you will hear long time APLer Stephen Taylor talk about how APL is like poetry: www.arraycast.com/episodes/episode-00-why-i-like-array-languages (I think this is the right episode)
Very cool, never seen APL before. Still this really feels like code golfing rather than refactoring.
i seem to recall something i have read once about feynman. apparently in the early days of computer science feynman and iverson (the inventor of apl) once met and feynman said something to the effect of: "ok, so you guys are doing this new thing called computer science. but what are you actually doing? see, we in physics have all these formulas and math and it helps us think about things and nature. we can look at a short mathematical formula and see everything in it in one short line of letters and symbols. and that is what we do all day long, we do these formulas. do you computer guys have anything like that?" and iverson of course said, no we dont and invented apl. now i dont know if that is true or a legend, but it seems to make sense to me. a popular question among aplers is what their favourite symbol is. most say something like the christmas tree or something like that. or you could say filter or something. my favourite is the less or equal symbol (or greater or equal). because that shows the actual true spirit of apl: a notation that is concise, like you would write it on a piece of paper with pen when doing math, that can have two meanings in one symbol combined, but expresses one concise thought.
Looking forward to watching the video on the different combinators!
I didn’t understand the words you used about N-trains and tines. I have more work to do.
There are 2-trains and 3-trains, and tine just refers to one of the functions (aka left, middle or right)
@@code_report Thank you for the explanation. I just watched the first 3 minutes (or, the second 'slide' of 3 minutes. It was from 53s to 4m0s) of Dyalog '13: Train Spotting in Version 14.0 - ua-cam.com/video/7-93GzDqC08/v-deo.html
between your comment and those 3 minutes I think I have a perfect understanding.
It is my understanding that trains are part syntactic sugar and part opportunity for interpreter to optimize. I can visualize what they do, now.
Also stoked about learning of the 'parse' directive in Dyalog. That'll be really helpful with grokking the syntax here.
With the 3s and 5s, I think we're a few steps from an apl fizz buzz.
Can you try to compute a 'Bad Apple' animation in APL? Could be interesting
what interests me about APL is how the workflow works using non-ASCII characters ?
and also what real life use cases apl has - is it used along side another programming language to do these efficient processes?
It appears to see most use in financial processing, but that may just be because other fields are less talkative. An example of using it alongside other languages is Co-dfns, which like Futhark can build libraries for GPU and multicore processing to use in other languages.
I feel like I'm watching a skilled druid trying to explain how to read and write a spell in an incomprehensible ancient language.
Is there a good place to learn about trains forks and combinators?
APL is very elegent once you understand how it works.
Were you to solve this problem yourself right now, without having seen it before, would you write the final piece of code right away, or would you start with more basic code and refine it? If the latter, what do you think your starting point would be?
I would have built it up point free from the beginning, and once I had one of the modulus expressions like (3|⊢)⍳9 I probably would have moved directly to 3 5∘.(0=|)⍳9. And then I would have ended up at the same point.
I really need to wrap my head around outer product.
you can remove the parentheses on the outer product by moving the 0= to after (or to the left of) it
How? I tried but couldn't accomplish it
Nope, results in a 0 with ι9
Are there libraries for APL for GUI programming?
Which editor do you use to write APL code on? I found the language very interesting and I would try to use it
He uses RIDE
When you explain the E Combinator at 6:25, you mention a left and a right "tine"? "thyne"? What's the word you're using there?
Tine, as in the tine of a fork
@@garklein8089 Thanks! Never heard that word for it before - people always said prong.
Sorry if this has been asked before, what is that color scheme?
Hello from the future...
Still no video on combinetors
ua-cam.com/video/JELcdZLre3s/v-deo.html
1:38 what does ",[0,5]" do?
I can see what it did; it paired arguments and results of the left function. Sadly, I can't tell you how it expressed that; looks like magic numbers to me.
A similar operation in BQN might look like:
> (∨˝ 0= 3‿5 |⌜ ⊢)⍟1‿0 (1+↕9)
Here ⍟1‿0 applies a function on its left both 1 and 0 times, and > unboxes the lists to a matrix, lining them up.
(ID +.× 0 OR.= 3 5 JOT.| ID)
I guess this would work
Probably RID (right identity).
It does, very beautiful : ⊢+.×0∨.=3 5∘.|⊢
Not knocking the fun of this, but why is the last version better, does it improve performance?
code_report likes code golf
@@tonyennis1787 Yeah, this APL language reminds me very much perl golf programs, which I was doing for fun several years ago :)
You mentioned ".3 programming" if I heard it correctly. What does it mean?
“Point Free” as in no pointers or named variables are used.
A example of point free programming is in forth where instead of adding X and Y, you have X and Y in the computers memory stack and apply the + operator to them putting the result back on the stack for another operation, where as in C, the computer must load X and Y into memory then add them then assign the result somewhere else to save it.
@@cranknlesdesires Thank you for the answer. Now I know what to google for :)
@@cranknlesdesires Haskell is another language that point-free programming is used.
cant you just use remainder of 15?
You can, which reduces the number of modulo operations, but then you need to check for other values than 0.
This method has its place when working with a processor where division cannot be pipelined and speed matters more than source code complexity. E.g. 15 here is the least common multiple of 3 and 5; were you planning to explain that?
JavaScript Solutions:
// Using reduce
const euler1st = n => Array.from({ length : n }).reduce((acc, val, index) => {
const value = index + 1;
return (value % 3 === 0 || value % 5 === 0)
? acc + value
: acc;
}, 0);
// Using precedural
const euler1st = n => {
let result = 0;
for (let i = 1; i
no thanks
Don't know why, but I felt this video got unnecessarily complicated... You should probably keep the dfn and at the end write the tacit version
quick q/k4 solution:
{x wsum (in[0]mod[;3 5]::)'[x]} slightly longer, use of function composition
{x wsum not min x mod/: 3 5}
{x wsum~&/x .q.mod/:3 5} /k4 is missing mod
beautiful, also utterly unreadable
// z^3 code. Could be far terse and simple if desired.
n=1..1000;
n.finde("x%3==0||x%5==0"!)
n=1..9;
n.finde(x=>(!(x%3) || !(x%5)))
Thanks for the video, you got me again running gnu-apl (I know you something else), even though I'm late😅. Here is another solution
{+/⍵/⍨0=×/⊃(⊂3 5)∣⍵} ⍳99