Python vs 3 Character APL Solution

แชร์
ฝัง
  • เผยแพร่เมื่อ 6 ก.ย. 2024

ความคิดเห็น • 43

  • @heeerrresjonny
    @heeerrresjonny 3 ปีที่แล้ว +33

    I know it may not be the main draw of APL, but I would love to see some performance comparisons between the elegant APL solutions in these videos, and the "best" solutions in other languages. It'd be interesting to see what (if any) tradeoffs there are, or if there are any surprising scaling effects based on the input.

    • @billr3053
      @billr3053 3 ปีที่แล้ว +5

      Yes I'm also interested in APL performance. I know Dyalog is always improving their product and getting graphics card processors and down-to-the-metal machine code to do the crunching. Recognizing huge libraries of idioms and writing specialized code for them. If the expression is "common" they have probably already optimized it. That's something a generic language on generic platforms can't do. Well, maybe JavaScript engines enjoy such advancements since there is an ongoing battle for performance specs between browsers.

  • @mohammadsheikh7564
    @mohammadsheikh7564 3 ปีที่แล้ว +15

    You have a great way of explaining the APL syntax from the ground up! Appreciate all the work you put into your videos.

  • @zokalyx
    @zokalyx 3 ปีที่แล้ว +8

    First time seeing APL code. I'm just as amazed as scared by it.
    Also great video

  • @oantolin
    @oantolin 2 ปีที่แล้ว +2

    In J the solution is just {~, that is, index-selfie in APL terminology (index does not need the indices enclosed in this case in J).

  • @zcubesdemoes2191
    @zcubesdemoes2191 หลายเดือนก่อน

    //z^3
    a=[0,2,1,5,3,4];
    a#a
    // Actual logic is just #, which is an index access operator, if operated on any array. For this problem, the answer is just one character (3 to be generous). # operator is far more powerful and is polymorphic depending on the types of arguments it operators on.

  • @remyclarke4020
    @remyclarke4020 3 ปีที่แล้ว +2

    Always love seeing APL content Connor.
    Have you had a look at the Fin APL idioms list yet? I've had a look at it but I have a hard time digging into it.
    I'd love if you would make a series with them. (Perhaps a backwards format, where you start with the APL idiom and then implement the same thing in another language).

  • @kinki2474
    @kinki2474 ปีที่แล้ว +1

    Since the python solution is functional & can fit in a single expression. Instead of defining a function & returning, you can use lambdas

  • @MrAbrazildo
    @MrAbrazildo ปีที่แล้ว +3

    2:28, C++ solves this in 3 characters too:
    #define D auto rslt = arr; auto it = rslt.begin();
    #define F for (auto &n: arr) *it++ = arr[n];
    #define R return rslt;
    template auto buildArray (const T &arr) { D F R }

  • @cstockman3461
    @cstockman3461 ปีที่แล้ว

    A point-free Haskell solution would be:
    buildArray = map (-1). map (!!) id . map (+1)
    Where () is the S combinator when used with functions

  • @Russtopia
    @Russtopia 3 ปีที่แล้ว +1

    GNU APL doesn't support tacit (forks, trains) but the solution is really just as brief:
    ⎕IO←0
    n ← (0 2 1 5 3 4)
    (⊂n)⌷n
    0 1 2 4 5 3
    tests ← (0 2 1 5 3 4) (5 0 1 2 3 4)
    buildArray ← {⊂⍵⌷⍵}
    buildArray ¨ tests
    0 1 2 4 5 3 4 5 0 1 2 3
    It's actually pretty easy to back-port Dyalog APL's forks and 2-trains to APL2 syntax
    [From aplwiki.com/wiki/Tacit_programming#Trains]
    Trains
    A train is a series of functions in isolation. An isolated function is either surrounded by parentheses or named. Below, ⍺ and ⍵ refer to the arguments of the train. f, g, and h are functions (which themselves can be tacit or not), and A is an array. The arguments are processed by the following rules:
    Forks
    A 3-train is a fork:
    (f g h) ⍵ === ( f ⍵) g ( h ⍵)
    ⍺ (f g h) ⍵ === (⍺ f ⍵) g (⍺ h ⍵)
    The left tine of a fork can be an array:
    (A g h) === A g ( h ⍵)
    ⍺ (A g h) ⍵ === A g (⍺ h ⍵)
    Atops
    A 2-train is an atop:
    (g h) ⍵ === g ( h ⍵)
    ⍺ (g h) ⍵ === g (⍺ h ⍵)

  • @VRchitecture
    @VRchitecture ปีที่แล้ว

    That’s beautiful! ☺️

  • @martin42
    @martin42 2 ปีที่แล้ว +2

    Why not nums[1 + nums] ?
    I learned APL decades ago, so maybe I'm not hip with some of the newer techniques. It would seem to me this is a problem that fits the fundamentals very well though. Also, this way you don't have to mess with quad-IO.

    • @Khaktos
      @Khaktos 2 ปีที่แล้ว

      I'm quite a noob with APL but this was my first thought too. But watching his other APL videos, he often mentions point-free programming and how much he likes that style. So basically the "enclose-index-identity" fork is just a codegolfed and point-free solution

    • @sebastiangudino9377
      @sebastiangudino9377 ปีที่แล้ว

      Because that could not be further from an elegant solution. It's not point free. It's not expresive, it's not taking advantage of combinators, and it has that ugly inline 1 constant. The 3 character solution might be harder to read at a glance. But it is a lot more idiomatic

    • @martin42
      @martin42 ปีที่แล้ว +1

      @@sebastiangudino9377
      > could not be further from an elegant solution
      It is the most elegant solution by far. It is ground-truth-basic APL, dating back to the original language I learned from the very people who created it back in the early 80's.
      > It's not point free. It's not expresive, it's not taking advantage of combinators
      Oh, please. Be careful not to confuse modern jargon and fads with getting the job done with clean, simple and BACKWARDS COMPATIBLE code.
      > that ugly inline 1 constant
      Again. Be careful about making these kinds of judgements. There's nothing "ugly" about this approach. You will find it in every APL codebase from here to the origins of the language. "Ugly"? Now we are writing code to display at the Louvre? C'mon.
      What is dangerous is messing with quad-IO. I made that mistake as a newbie 40 years ago. It opens the door to untold misery in real code. It's one thing to write a cute little solution to a problem. Quite another to design and support a codebase running an entire factory or a DNA sequencing system (both of which I did in APL back in the day). I don't even want to get into just how dangerous it can be to try to be "elegant" in real production code.
      > it is a lot more idiomatic
      That's very funny. How many years of production programming in APL do you have? Right.

  • @VincentZalzal
    @VincentZalzal 3 ปีที่แล้ว +2

    Apart from the fact that it is (unfortunately) a 1-based array language, in Matlab/Octave, you would do nums(nums) directly (and probably the same in numpy Python, but 0-based). Why is the "horseshoe" operator necessary in APL? What does it do exactly?

    • @martin42
      @martin42 2 ปีที่แล้ว

      In APL you can change the index origin to be 0. That's the "quad IO" he refers to in the video. You'd be amazed how useful this can be.

    • @VincentZalzal
      @VincentZalzal 2 ปีที่แล้ว

      @@martin42 My comment about 1-based language was about Matlab/Octave actually ;) My question is about the first glyph, I think it's called enclose? What does it do? What is the difference between (enclose nums) and just nums? In other words, why would (identity index identity) not work?

    • @martin42
      @martin42 2 ปีที่แล้ว +2

      @@VincentZalzal Ah, sorry for not understanding your question. The index operator takes a scalar as the left argument. We want to pass it a vector instead. One way to do this is to "enclose" the vector into a scalar. In APL a scalar has a rank of 0, a vector 1 and a matrix 2. If you enter something like "⍴⍴5", you are asking for the rank of the number 5. The result will be 0. The rank of a vector, say, 1 2 3 4, will be 1: "⍴⍴1 2 3 4". So, the trick to be able to pass several numbers, a vector, as the left argument of the index operator, is to fist enclose it into a scalar...think of wrapping it inside a scalar. So "⍴⍴ ⊂1 2 3 4" gives you a rank of 0.
      Example using conventional indexing and an standard index origin of 1:
      "APL is not fun"[1 2 3 4 5 6 11 12 13 14]
      Result: "APL is fun"
      If you wanted to use the index operator (⌷) instead, you can't do this because the operator expects a scalar on the left:
      (1 2 3 4 5 6 11 12 13 14)⌷"APL is not fun" ....this will not work
      If you enclose the vector...
      (⊂1 2 3 4 5 6 11 12 13 14)⌷"APL is not fun"
      You get "APL is fun" again.

    • @VincentZalzal
      @VincentZalzal 2 ปีที่แล้ว

      @@martin42 Thank you, I understand now! In Matlab/Octave/Python-numpy, the index operator can actually use rank-0 or rank-1 arguments, but in APL, it must be rank-0. And the enclose function, by reducing the rank, allows a kind of "map" function (as in functional programming), applying the index operator on each element enclosed.

    • @VRchitecture
      @VRchitecture ปีที่แล้ว

      @@martin42 You’ve made APL fun again ☝🏻😂

  • @arisweedler4703
    @arisweedler4703 2 ปีที่แล้ว +1

    Oh wow. A fork is an S’ combinator. Goooootcha. Yeah I still don’t get how APL sees 3 functions in ()s and that they’re unary binary unary. Especially when so many glyphs operate on functions themselves, like the compose (or bind) operator. Hmm! There’s clearly a dimension I am missing. Accepting the fact that arguments have to be either values or function is confusing. Or… it’s not, but realizing that I had to was.
    Ok. Unrelated. I think I finally understand what point free means. I don’t get the etymology but I think I can look it up now and understand it as I have enough (albeit loose) intuition.

    • @xGOKOPx
      @xGOKOPx 2 ปีที่แล้ว

      Point-free means just that you don't mention the argument

  • @nanthilrodriguez
    @nanthilrodriguez 3 ปีที่แล้ว

    code_report, I don't have vision problems, but I have a very difficult time reading the colors of your ipython session.

  • @Lantos1618
    @Lantos1618 2 ปีที่แล้ว

    insane

  • @billr3053
    @billr3053 3 ปีที่แล้ว +3

    Why not nums[nums]

    • @ooloncolluphid9975
      @ooloncolluphid9975 3 ปีที่แล้ว

      "TypeError: list indices must be integers or slices, not list" :) it does work on numpy tho

    • @billr3053
      @billr3053 3 ปีที่แล้ว

      @@ooloncolluphid9975 Sorry, mine was an APL solution.

    • @arraymac227
      @arraymac227 3 ปีที่แล้ว +1

      it makes expressions like (nums,morenums)[nums,morenums] messier than (⊂⌷⊢)nums,morenums, i.e. nums only needs to be present one time

    • @flyingsquirrel3271
      @flyingsquirrel3271 3 ปีที่แล้ว +1

      Thats also valid python if you're using a numpy array :)

  • @snooli111
    @snooli111 3 ปีที่แล้ว +2

    BQN:
    ⊏˜

  • @raffimolero64
    @raffimolero64 2 ปีที่แล้ว

    APL is just math with a compiler

  • @guillaumeremy1720
    @guillaumeremy1720 3 ปีที่แล้ว

    APL ∧ Category Theory ⊃ ⌽ 'Push the Subscribe Button' ⌽