[HN Gopher] Ivy - An interpreter for an APL-like language
       ___________________________________________________________________
        
       Ivy - An interpreter for an APL-like language
        
       Author : georgia_peach
       Score  : 125 points
       Date   : 2022-08-07 06:19 UTC (16 hours ago)
        
 (HTM) web link (pkg.go.dev)
 (TXT) w3m dump (pkg.go.dev)
        
       | kevingadd wrote:
       | The precedence rules are terrifying. I get it, but:
       | 
       | > 3/6*4 is 2 while 3 / 6*4 is 1/8 since the spacing turns the /
       | into a division operator. Use parentheses or spaces to
       | disambiguate: 3/(6*4) or 3 /6*4.
       | 
       | having to be up-front as a warning feels like a sign that your
       | approach to precedence is fundamentally broken and you should
       | _require_ parentheses. (Also the idea that 1 /8 and 1 / 8 are
       | different things feels bonkers to me in general, but maybe that's
       | just taste.)
        
         | eis wrote:
         | Fully agreed. I stopped considering this practical in any way
         | when I read
         | 
         | > 3*4+5 is 27
         | 
         | I'm sorry but if your calculator does not follow standard
         | mathematical rules for operator precedence then I'm out. But
         | the space issue takes it to another level.
         | 
         | I also get it, it derives from APL which is right to left and
         | all operators have same precedence but it's just so far from
         | practically usable for normal people... there's a reason noone
         | uses APL today. And sure it's just a plaything but seems weird
         | to even create apps for iPhone, iPad and Android and a logo for
         | it.
        
           | iasay wrote:
           | Agree with this.
           | 
           | I'd rather actually we used postfix notation as that not
           | ambiguous at all. I would like a modern "dc" written in Go if
           | I'm honest. With engineering units, BCD decimal arithmetic,
           | blackjack and hookers.
           | 
           | Actually if there was a postfix notation spreadsheet with
           | that capability it would be an interesting tool.
        
             | kqr wrote:
             | Isn't Emacs calc-mode what you're asking for? You can use
             | it as a stand-alone application even if you don't use Emacs
             | for anything else.
        
               | iasay wrote:
               | That's like going to Japan to eat sushi. I'd rather make
               | it at home :)
        
               | kqr wrote:
               | Sushi is very easy to make compared to replicating calc-
               | mode.
               | 
               | It's more like going to Japan to ride a Japanese train.
               | Would you rather build a full-scale replication in your
               | back yard?
        
               | iasay wrote:
               | True but sometimes we do things for the journey :)
        
           | mananaysiempre wrote:
           | Quick, what should be the order of precedence among (binary!)
           | flip, transp, rot, rho, and iota?
           | 
           | APL / Ivy have so many operators a conventional precedence
           | order would likely be completely impossible to remember or
           | work with.
           | 
           | (One option I'd consider viable in general would be to define
           | associativity and perhaps compatible groups like {+, -} or
           | {*, /} but force explicit parentheses when operators from
           | different groups are used, but that wouldn't feel like a
           | calculator.)
        
         | is0tope wrote:
         | One thing I really like about kdb+/q is the fact that it has
         | strict right-to-left execution/precedence. While I know it's a
         | standard, I don't want to deal with bodmas, or whatever it is.
         | Having right to left makes it clear and unambiguous how it will
         | execute. Saying that, it does also encourage huge one line
         | abominations. Everything in moderation i guess...
        
         | legulere wrote:
         | I wonder if programming languages having precedence rules at
         | all is an atavism from the 70s when it was an interesting
         | problem for parsing. Adding parentheses makes things clearer in
         | 99% of the cases.
        
           | somat wrote:
           | Programing languages require precedence rules because
           | mathematicians decided that having a screwball precedence
           | would make their notation more concise, over the hundreds of
           | years of being used and taught these notations have become
           | the expected form of math, and programing languages(all of
           | which tend to be math heavy) usually will try to follow the
           | expected rules.
           | 
           | Honestly as an interested amateur I think that much of the
           | notation used in math is one of the weakest parts of the
           | discipline. there are two things that I think would aid the
           | notation greatly.
           | 
           | 1. Most complex equations have a lot of moving parts within
           | them, however the notation has no way of indicating what
           | these parts are for and why they are there, you better hope
           | that the author has taken to time to document their equation
           | properly.
           | 
           | 2. the terrible symbology. you have heard the joke about the
           | two hard things in computer science. it turns out that
           | programmers are usually fairly good at naming things, the
           | mathematicians are the true dark masters at names. if you
           | have an item in your equation that represents the confidence
           | of a rating they will not name it confidence_rating, no, they
           | will name it s(a small sigma), good luck searching(or even
           | typing) that.
           | 
           | Now I get why it was done, they tended to a notation that was
           | as concise as possible, this makes it much faster to
           | manipulate parts when you are working on something. however I
           | feel this has the opposite effect when trying to teach it to
           | others.
        
             | tialaramex wrote:
             | > Programing languages require precedence rules
             | 
             | WUFFS doesn't have operator precedence.
             | https://github.com/google/wuffs/blob/main/doc/wuffs-the-
             | lang...
             | 
             | As its designers explain: A bare a * b + c is an invalid
             | expression. You must explicitly write either (a * b) + c or
             | a * (b + c).
             | 
             | Why doesn't WUFFS have precedence? Because it's focused
             | intensely on solving its specific problem, Wrangling
             | Untrusted File Formats Safely. Having solved the buffer
             | problem (you can't write buffer[oops_too_big] type mistakes
             | in WUFFS, they _will not compile_ ) and the integer
             | overflow problem (likewise, it doesn't compile) they wanted
             | to also solve that problem where the programmer thought
             | there were making one calculation, but due to precedence
             | rules they were actually making a different calculation.
        
             | rob74 wrote:
             | Well yeah, having precedence rules makes the notation more
             | concise and can save you from typing lots and lots of
             | brackets. And I don't think multiplication/division having
             | higher precedence than addition/subtraction (and, by
             | extension, AND having higher precedence than OR) is all
             | that "screwball" - and even if it were, if you paid
             | attention in elementary school, you already know it, so
             | programming languages can rely on it. Of course, the moment
             | they start getting "creative" with precedence, those
             | exceptions turn into massive footguns...
        
           | masklinn wrote:
           | > I wonder if programming languages having precedence rules
           | at all is an atavism from the 70s
           | 
           | It's not an "atavism from the 70s", it's a mirror of
           | mathematical conventions, as well as a syntactic convenience.
           | 
           | Language designers have tried to do away with precedence all
           | along by having uniform evaluation (e.g. smalltalk, as well
           | as APL and all its descendents hence Ivy, probably), removing
           | infixes (lisp, forth, assemblies), or requiring explicit
           | prioritisation (I think I saw that a while back though I
           | don't remember the language).
           | 
           | > Adding parentheses makes things clearer in 99% of the
           | cases.
           | 
           | It also adds a significant amount of noise for 99% of the
           | cases, for no value since any schoolchild past 12 or so has
           | integrated the precedence rules.
        
             | Macha wrote:
             | > It also adds a significant amount of noise for 99% of the
             | cases, for no value since any schoolchild past 12 or so has
             | integrated the precedence rules.
             | 
             | As all the viral "Only 25% of people got this right" stuff
             | that pops up from time to time proves: No they haven't.
             | 
             | Also since we're rarely writing equations composed entirely
             | of single digit numeric literals and are using reasonable
             | variable names, the percentage of characters overhead and
             | therefore noisiness of using brackets is much less than in
             | the short examples being thrown around.
        
           | tgv wrote:
           | If memory serves well, normal operator precedence was already
           | present in the first FORTRAN, which was proposed in 1953.
           | 
           | And APL's priority system is: there is no priority.
           | Everything is evaluated right to left. Pike's Ivy is no
           | exception. 3/4 differing from 3 / 4 is a lexical convention:
           | 3/4 is a rational number.
        
           | bruce343434 wrote:
           | > Adding parentheses makes things clearer in 99% of the cases
           | 
           | I will challenge that in saying that
           | 9*2+3/2^3
           | 
           | is clearer than the far more noisy
           | (9*2)+(3/(2^3))
           | 
           | Precedence is something you learn in high school.
           | 
           | edit: fighting with the painful markdown of hn
        
             | laumars wrote:
             | I think all the points there are true:
             | 
             | The latter example is more noisy, you do learn precedence
             | in high school yet the latter example is also more clear
             | because it is the most accurate way of conveying intent.
        
             | nerdponx wrote:
             | This is the 1% of cases!
        
             | pasc1878 wrote:
             | It is not that easy see the many threads over
             | BODMAS/PEDMAS/BEDMAS.
             | 
             | If you actually do maths you never have the / or / operator
             | in writing equations it is always a horizontal line so you
             | can't write maths in one line.
             | 
             | In your case I think the bracketed form is easier to read
             | 
             | If forced to write on one line suspect I would write as 9*2
             | + 3/(2^3)
        
               | nerdponx wrote:
               | And multiplication is very often written as two variables
               | just sitting next to each other with no additional
               | operator character in between.                  ((2*a) +
               | (2*b)) / c
               | 
               | in math would be                   2a + 2b
               | -------            c
               | 
               | Traditional precedence rules make more sense with
               | traditional handwritten notation.
        
           | pasc1878 wrote:
           | No it predates that. I think in an attempt to use the way
           | arithmetic is usually written. See
           | https://rosettacode.org/wiki/Operator_precedence for a list.
           | 
           | COBOL, FORTRAN and Algol60 all have that so this dates from
           | the '50s
           | 
           | I think out of major languages only LISPs, APL and successors
           | and Forth don't have precedence rules
        
         | vonwoodson wrote:
         | I keep a YouTube video in my back pocket just for this
         | argument: [The Order of Operations is Wrong by
         | mintuephysics](https://youtu.be/y9h1oqv21Vs)
        
           | jasonwatkinspdx wrote:
           | Yeah, there's a legendary twitter thread that removed all
           | doubt for me. Thousands of teachers, professors, and
           | engineers all confidently asserting that their version of
           | PEDMAS is the correct and unambiguous one.
           | 
           | Stuff like this is very difficult to change, because the
           | conventions both global and fundamental... but we also
           | shouldn't pretend like history happens to always chose the
           | perfect convention. It's more a matter of we've just learned
           | to live with the warts.
        
         | hhyndman wrote:
         | APL was the first language I learned in school and I was thrown
         | by the precedence of the mathematical operators, but once the
         | other operators were put in play, it was an incredibly simple
         | rule -- and rarely did I or other APL developers have bugs
         | relating to order of operation.
         | 
         | I then moved to C++ and was gobsmacked the the precedence rules
         | and was forced to use parentheses to get things right. I have
         | seen hundreds of bugs produced by programmers that tried to be
         | clever and avoid parens relying on their faulty memory of the
         | precedence priorities.
         | 
         | Just look at the C++ Operator Precedence table listed at the
         | following URL. It's wild!
         | 
         | https://en.cppreference.com/w/cpp/language/operator_preceden...
        
           | hhyndman wrote:
           | An interesting article relating to "operator precedence is
           | broken". https://www.foonathan.net/2017/07/operator-
           | precedence/
        
         | kqr wrote:
         | This is odd particularly as : the traditional ratio symbol
         | seems free.
        
         | coldtea wrote:
         | Sound like a typical Rob Pike design. Idiosyncratic, not that
         | user friendly, and mostly "works for me" affair (considering
         | things like the Sam editor and parts of Golang).
        
           | EdiX wrote:
           | > Sound like a typical Rob Pike design
           | 
           | It's actually from APL.
        
             | coldtea wrote:
             | Yes, but adopted to taste, and adopted by a person who
             | shared the design sensibility
        
           | Jabbles wrote:
           | Given that Go does not have the same syntax, you cannot claim
           | that these are examples of "typical Rob Pike design".
        
             | masklinn wrote:
             | GP's not talking about this specific syntax but about Rob
             | Pike's general approach to language and system design.
             | 
             | A flagrant example of
             | 
             | > idiosyncratic, not that user friendly, and mostly "works
             | for me" affair
             | 
             | being date/time patterns in Go.
        
               | Jabbles wrote:
               | You can't just cherrypick examples and say this is
               | typical.
               | 
               | Even worse, you (GP) can't say this is typical without
               | providing any examples when the most obviously relevant
               | analogy (precendence in Go) does not support your
               | statement.
        
               | coldtea wrote:
               | It's not about the particular intepreter or specific
               | precedence design, it's about the tendecies described:
               | what kind of stuff he often appears to like and/or
               | produce.
               | 
               | Now, you might disagree with that, but at least disagree
               | with what I tried to say, not what I didn't mean :)
        
               | indymike wrote:
               | The op was commenting Rob Pike's body of work and Ivy's
               | operator precedence certainly does fit this description
               | to a tee.
        
               | eis wrote:
               | You are misunderstanding his point even though masklinn
               | explained it. It's not about the specific point of
               | operator precedence. It is about designing something that
               | has internally sound logic but is very unexpected by a
               | typical new user. And he provided the example of time
               | package patterns in Go which imho fits very well. Yea it
               | makes sense but I'm sure there are hordes of users that
               | think "why doesn't this work like in virtually every
               | other language?".
               | 
               | It's probably good to not take the "typical" too
               | literally and more as a "Rob Pike has done a few designs
               | in the past that have this quality".
        
               | mseepgood wrote:
               | > "why doesn't this work like in virtually every other
               | language?
               | 
               | What's the point in creating something new if you simply
               | repeat what already exists?
        
               | coldtea wrote:
               | Doing it better in other aspects (e.g. 100% same design
               | but faster or safer, etc.)?
               | 
               | Refactoring?
               | 
               | Making a FOSS version?
               | 
               | Learning?
               | 
               | Doing it in Rust because it's fashionable?
               | 
               | Competition with an existing player in the same market?
               | 
               | And lots of other reasons besides...
        
               | jasonwatkinspdx wrote:
               | Except that comment is just straight up wrong.
               | 
               | This approach to precedence comes straight from Iverson
               | and APL itself. Iverson originally started out designing
               | a more uniform mathematical notation. It developed into a
               | programming language secondary to that. Note that J, K,
               | and others in this family all duplicate this choice
               | largely. And there's mainstream languages that have
               | chosen the middle ground of allowing basic precedence for
               | + - * / expressions but require explicit grouping
               | otherwise.
               | 
               | It's not a particularly outlandish idea.
               | 
               | So attributing it to Rob Pike's personality traits is
               | just off the mark. It's ok to be critical but it should
               | be specific and informed, not just bashing someone
               | character as a whole, and if you're gonna take it that
               | far, you'd probably better at least know what you're
               | actually talking about.
               | 
               | And note I've been critical of Rob's choices and behavior
               | surrounding Go's date/time on a particular issue, so note
               | this isn't empty hero worship on my part.
        
               | coldtea wrote:
               | > _So attributing it to Rob Pike 's personality traits is
               | just off the mark_
               | 
               | That's fine, since I didn't speak about Pike's
               | "personality traits", but to his architecure/design
               | tendencies.
               | 
               | And I didn't attribute this design to him. I know of APL,
               | and even if I didn't the influence is right there in the
               | TFA title. I _compared_ it to his designs ( "sounds like
               | a typical Rob Pike design"), i.e. he adopted it because
               | he does have these design tendencies, and so this was to
               | his taste.
               | 
               |  _> not just bashing someone character as a whole_
               | 
               | Where exactly are you getting that from? As if I've
               | called him a "bad person" or something?
        
               | ducktective wrote:
               | Are the `-option` thing in Go CLI apps and method
               | capitalization (`myobject.GetStuff()`) other examples of
               | these idiosyncraticies?
        
               | coldtea wrote:
               | The -option I'd say yes. Although this is vintage UNIX
               | style behavior, in 2009, when Golang emerged, it should
               | have picked GNU-style. No reason except idiosyncrasy or
               | nostalgia to go with single dash.
               | 
               | For method capitalization, I'd say no, as this is the
               | case in any other popular languages too (C# to name but
               | one).
        
           | pverghese wrote:
           | Rubbishing someones character for a design choice is just too
           | extreme. Sounds like you have something personal against Rob
           | Pike rather than anything constructive to add
        
             | coldtea wrote:
             | This is about design tendencies.
             | 
             | Not about character in general, much less about
             | "rubbishing" it.
             | 
             | In light of this, "sounds like you have something personal
             | against Rob Pike", is moot.
        
           | samatman wrote:
           | I wouldn't describe UTF-8 in those exact terms!
        
             | coldtea wrote:
             | True. That would be the Ken Thompson influence!
        
         | dan-robertson wrote:
         | Is it just that fractions are first-class objects? And I guess
         | then you just want to always separate operators with spaces.
        
           | masklinn wrote:
           | > Is it just that fractions are first-class objects?
           | 
           | The problem is that                   3/4
           | 
           | is a rational literal, while                   3 / 4
           | 
           | is a division. This seems unique(ly error prone) in the
           | language, other operators do _not_ have to be spaced.
        
       | cpach wrote:
       | Out of curiosity:
       | 
       | I noticed that Pike chose the, uh, "username", _robpike.io_ for
       | this project. (It's probably called something else than username
       | in this context.)
       | 
       | What are the benefits of using a domain name as
       | username/organization name in this context?
        
         | shric wrote:
         | https://robpike.io/ is... interesting.
        
           | owl57 wrote:
           | A showcase of Go? The backend is probably less than 20 lines,
           | uses only stdlib and serves (so to say) all the HN crowd just
           | fine.
        
           | lima wrote:
           | Especially since it's implemented server-side.
           | 
           | Even works with curl :-)                   curl --no-buffer
           | https://robpike.io
        
         | unsafecast wrote:
         | You're not dependent on GitHub. If you ever decide to switch
         | to, say, sourcehut, you can keep the install command and not
         | break anything.
         | 
         | It also looks way nicer, and it's easier to deal with (I'd
         | rather type `import "robpike.io/ivy"` than a GitHub link), but
         | that's a flaw in the way go does packages imo
        
           | cpach wrote:
           | Ah. Interesting.
           | 
           | I see that requesting https://robpike.io/ivy@latest yields a
           | 302 that points to http://godoc.org/robpike.io/ivy@latest
           | (not sure exactly what _go install_ would do with that URL
           | though)
        
             | p4bl0 wrote:
             | Maybe it doesn't do this redirect if the user agent is the
             | one of _go install_?
             | 
             | It would be a convenient way to have the package url works
             | for both the package itself and its documentation :).
             | 
             | EDIT: well now for me it redirects to:
             | https://github.com/golang/go/issues/43036 so... whatever is
             | happening here might not be on purpose, actually.
        
             | unsafecast wrote:
             | As far as I know, 'go get' (not install; that's different)
             | uses git to download a repository.
        
               | unsafecast wrote:
               | Oh, sorry. It's install after all. I assumed it's a
               | library.
        
             | icholy wrote:
             | https://robpike.io/ivy@latest?go-get=1
        
         | [deleted]
        
         | oefrha wrote:
         | It's called remote import path and it's trivial to use your own
         | domain. All you need is a meta tag in the HTML:
         | <meta name="go-import" content="import-prefix vcs repo-root">
         | 
         | The code can reside anywhere, independent from the domain in
         | the import path.
         | 
         | https://pkg.go.dev/cmd/go#hdr-Remote_import_paths
         | 
         | Edit: I see in another comment that you tried to curl
         | https://robpike.io/ivy and got a 302 redirect to pkg.go.dev.
         | That's meant for humans. You need to add ?go-get=1 for the go
         | toolchain:                 $ curl 'https://robpike.io/ivy?go-
         | get=1'       <meta name="go-import" content="robpike.io/cmd/doc
         | git https://github.com/robpike/doc.git"> ...
         | 
         | Personally I don't bother with responding differently based on
         | the go-get query param. I just put a <meta http-
         | equiv="refresh"> alongside the <meta name="go-import"> so that
         | the whole thing can be served statically and still be useful to
         | both humans and machines.
        
       | ianthehenry wrote:
       | I really like Ivy as a simple, friendly introduction to APL.
       | There is a surprising lack of APL-derived languages that use
       | words to name things -- most stick with the original symbols; J
       | and friends choose equally-cryptic symbols composed of ASCII
       | characters.
       | 
       | Earlier this year I decided to solve AoC 2021 in Ivy, then watch
       | Russ Cox's videos to see how he did it and use that to learn
       | something about array programming -- a topic I knew absolutely
       | nothing about going into this.
       | 
       | Unfortunately, Ivy really is, as Rob Pike says, a plaything. It
       | is buggy -- if you ever write a function that returns a vector or
       | a higher-rank array, you are entering bizarre undefined behavior
       | territory. The array-language equivalent of "concat_map" or
       | "flat_map" or "mapcat" or whatever you want to call it just
       | produces garbage values, which is _very confusing_ when you 're
       | learning about array programming for the first time ("Wait, this
       | vector says its length is 25, but it contains 50 elements...?" or
       | "The transpose of this array is just the first column repeated
       | over and over??").
       | 
       | Beyond that, a very cool thing about array languages is that, you
       | know, functions can implicitly act on entire arrays. You can
       | multiple a vector by 2 and it will know to multiply every element
       | in the vector by 2, because multiplication is defined for
       | scalars.
       | 
       | But in Ivy, this is only true for the built-in functions. There
       | is no way to write user-defined functions that have this implicit
       | act-on-every-element behavior. Which is basically _the_ looping
       | primitive in array languages -- so to do anything nontrivial, you
       | have to write it out with explicit recursion (still with the
       | caveat that your functions can only return scalars, or you enter
       | undefined behavior town) or rewrite your operations as binary
       | operations with an ignored right-hand side and use  "fold" to
       | "map" them. It's bad.
       | 
       | The latter is crippling enough that Russ Cox eventually forks Ivy
       | to add support for it, but it is not currently part of the
       | language. https://github.com/robpike/ivy/pull/83
       | 
       | Anyway that's a long comment to say: Ivy is a good, friendly
       | introduction to APL syntax (stranding, ambivalent functions,
       | precedence, etc) and _some_ array language concepts, but it is
       | far more of a calculator than a programming language.
       | 
       | But it's a good arbitrary-precision calculator! And if you're
       | still interested in trying it, maybe check out this thing I made.
       | It's an... Ivy programming environment?... that lets you run Ivy
       | scripts and see the results inline. (Ivy's repl is... very
       | primitive, and has to be wrapped by something like readline. Russ
       | Cox uses 9term to get around this; self-modifying programs are my
       | preferred approach.)
       | 
       | https://github.com/ianthehenry/privy
       | 
       | My frustration with Ivy led me to look into other array
       | languages, trying to find one that 1) used English words instead
       | of cryptic symbols and 2) worked. And I really couldn't find any!
       | Someone should do something about that. :)
        
         | 7thaccount wrote:
         | The q and k languages are part of the commercial Kdb+ array
         | database that all the major banks use for rapid analysis.
         | Seriously cool stuff and probably the state of the art in array
         | programming. Kdb+ also has dashboards and other useful things.
         | The original creator left to form his own company called
         | shaktiDB, so that is another commercial product. Dyalog APL is
         | the most advanced true APL out there. Unfortunately, you may
         | notice a trend here that all the best tech in this space is
         | currently commercial and closed source. That's a major deal
         | breaker for some and for good reason.
        
         | mlochbaum wrote:
         | I believe Nial fits the bill here? It has some symbols, but
         | less than most C-family languages. https://www.nial-array-
         | language.org/
        
           | ianthehenry wrote:
           | You know, I discounted Nial prematurely because its array
           | model seemed weird and different and -- still not actually
           | knowing anything about array languages -- I became very
           | enamored with J's ability to slice and reassemble arrays
           | based on function rank, which is something that I thought
           | Nial could not do (I don't actually remember _why_ I thought
           | this). I should actually read through the Nial docs and see
           | what I 've been missing.
        
             | mlochbaum wrote:
             | Nial uses the nested array model, which arguably is weird,
             | but is also shared by every surviving APL dialect that
             | supports nesting. J's boxed model comes from SHARP APL, but
             | A+ was the only other language to pick it up and both those
             | have stopped development.
             | 
             | https://aplwiki.com/wiki/Array_model
             | 
             | And it sounds like you've found it, but Nial does have the
             | RANK transformer, which looks essentially the same as J's
             | rank conjunction " .
        
       | jiripospisil wrote:
       | For those curious to see the language in action, Russ Cox
       | recorded solutions to many of the AoC 2021 challenges in Ivy.
       | 
       | https://www.youtube.com/user/rscgolang/videos
        
       | Saser wrote:
       | Russ Cox (who worked together with Rob Pike on Go for a long
       | time) solved several of last year's Advent of Code puzzles using
       | Ivy. Here's a YouTube playlist where he has recorded himself
       | doing so:
       | https://youtube.com/playlist?list=PLrwpzH1_9ufMLOB6BAdzO08Qx....
       | I don't think he's solving the problems for the first time in
       | these videos, instead merely demonstrating how they can be solved
       | using Ivy.
        
       | titzer wrote:
       | > Unlike in most other languages, operators always have the same
       | precedence and expressions are evaluated in right-associative
       | order. That is, unary operators apply to everything to the right,
       | and binary operators apply to the operand immediately to the left
       | and to everything to the right. Thus, 3 _4+5 is 27 (it groups as
       | 3_ (4+5))
       | 
       | This seems like a blatant unforced error.
        
         | mananaysiempre wrote:
         | This is entirely in line with the APL tradition. I suspect part
         | of the motivation is that APL has a _lot_ of binary operators,
         | none of which have a conventional infix form in traditional
         | mathematics or anywhere else.
         | 
         | (Cf also the Smalltalk tradition, which associates all "binary
         | messages" to the _left_ , but that has the motivation of
         | allowing user-defined names without fixity declarations.)
        
         | anonymous_sorry wrote:
         | Ivy is described as a "plaything". Rethinking rules that
         | everyone takes for granted and seeing where it leads seems like
         | a fun way to play.
         | 
         | My first CASIO scientific calculator at school didn't
         | understand operator precedence. Since that was how basic
         | calculators worked too, it seemed perfectly natural. I loved
         | that calculator - there was a simplicity and purity to it.
         | 
         | When I got a fancier one at uni that had been taught BIDMAS, it
         | took me a long while to get used to, and I never really enjoyed
         | using it. I don't think it was just because the squidgier keys
         | were less satisfying to tap.
        
         | cardanome wrote:
         | Now, let's imagine an APL-like language with precedence:
         | 
         | APL has a huge number of operators and worse, you can and will
         | define your own, as the classic distinction between operators
         | and functions does not apply to APL. So a huge precedence table
         | to memorize! Plus, with user defined operators you would either
         | have to force them to be all the same precedence, which is kind
         | of a bummer, or you allow them to define their own precedence.
         | It should be obvious that this would be a huge mess.
         | 
         | So actually no having precedence is the most sane way forward
         | but you also gain something: Order of precedence errors are
         | quite common both in mathematics and programming. Doing away
         | with precedence rules gets rid of a whole class of errors.
         | Awesome! (If you are going to respond that you never make any
         | errors, well congrats on being smart, I am not. I try to avoid
         | relying on lesser known precedence rules in my code as best as
         | I can.)
         | 
         | So what do we gain from precedence rules again? Shorter and
         | less noisy? Ugh, have you seen APL? I think they are good.
         | 
         | The notation of APL is explicitly designed to be human
         | friendly. Lot's of thought was put into it. I recommend reading
         | this Iverson paper:
         | http://www.sigapl.org/Articles/Notation%20as%20a%20Tool%20of...
        
       | henrydark wrote:
       | It took me a while to understand the syntax in general and the
       | primes example in particular. For those facing the same obstacle,
       | here is what I understood:
       | 
       | 1. Read single lines from right to left.
       | 
       | 2. Imagine a stack of one variable that you keep replacing the
       | top as you go from right to left, kind of like concatenative
       | languages (e.g. FORTH, kitten, factor), but right to left instead
       | of left to right.
       | 
       | 3. Here is a step by step translation of the primes example to
       | imepartive pseudo code:                 op primes N = (not T in T
       | o.\* T) sel T = 1 drop iota N
       | 
       | First of all this is a function definition, so can be put to
       | function primes(N)         return (not T in T o.\* T) sel T = 1
       | drop iota N
       | 
       | Now we apply the two rules above:                 function
       | primes(N)         x = iota(N) // 1..N         x = drop(1, x) //
       | 2..N         T = x         ToT = outerproduct(T, T) // a*b for
       | all a, b in T, so 4,6,...,N^2         return [x in T not in Tot]
       | 
       | So we get a O(N^2) (or maybe O(N^3), depending on how `in` is
       | implemented) algorithm for primes until N.
       | 
       | Here is a similar algorithm in python that might help further:
       | def primes(N):         T = range(2, N)         ToT = [a*b for a
       | in T for b in T]          return [x for x in T if x not in ToT]
        
         | dan-robertson wrote:
         | I guess you've added a backslash in the outer product to
         | prevent HN formatting weirdness. It isn't an outer product
         | where the operation is 'scan product'.
        
         | otabdeveloper4 wrote:
         | def primes (array.skip(count.@, 1)..          tuple(@,
         | {mul.@:combo(@,@)})..          tuple(T=second.@,
         | ?[1!=has(T,@),@:first.@])),         primes.3000
         | 
         | https://tab-lang.xyz
        
         | [deleted]
        
       ___________________________________________________________________
       (page generated 2022-08-07 23:02 UTC)