[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)