[HN Gopher] Uiua: A minimal stack-based, array-based language
___________________________________________________________________
Uiua: A minimal stack-based, array-based language
Author : xpointer
Score : 125 points
Date : 2023-09-27 11:28 UTC (11 hours ago)
(HTM) web link (www.uiua.org)
(TXT) w3m dump (www.uiua.org)
| queuebert wrote:
| This is exciting because it looks like BQN, but BQN had some
| unfortunate syntax in a few places.
|
| Edit: I'll be specific. Stranding required a special character in
| BQN '_', but appears to be just '_' in Uiua.
| ithkuil wrote:
| Beautiful.
|
| I'm a bit surprised by [1 2 ; .] 3
|
| Producing [1 2 3]
|
| Instead of 3 [1 2]
| jkafjanvnfaf wrote:
| This does look quite nice. I always felt that the operator
| precedence / association rules in other stack languages were by
| far the most difficult thing to get used to, not the nonstandard
| symbols. This appears more inviting in that regard.
|
| I do have to question the choice of right-to-left (array
| language) evaluation order. I've personally always preferred
| left-to-right (stack language) evaluation. I feel like right-to-
| left requires you to think to the end of a line before you start
| typing anything at all, as the first thing you type is the last
| thing that's evaluated. Left-to-right would also allow re-
| evaluating and visualizing the stack as you write each operator.
| alexisread wrote:
| ...Swap your language prefs to say, arabic? ;) More seriously
| though, I think it depends what your background is. Maths works
| in prefix notation eg. f(g(x)) but I appreciate that you can
| hold the stack in your head easier with postfixLR.
|
| Many people who are used to lisp would probably prefer prefix
| notation. non-stack or array langs have a nice tradeoff that
| you can look at the code without having to keep a model in your
| head, notably many forth users annotate their code with stack
| diagrams to help. Personally I'm quite taken with rebol syntax,
| passing a stack/array as the rightmost operand.
| http://blog.hostilefork.com/rebol-vs-lisp-macros/
| [deleted]
| jhvkjhk wrote:
| I fell in love with it immediately after I clicked the button
| that say its name.
| smabie wrote:
| If anyone's interested, I made a similar language, but inspired
| by k/q instead: https://cryptm.org/xs/
|
| example fibanacci fn: fib:(n:(neg 1)+;0@n do(2
| enlist 1@x sum x~)[0 1]);
| ithkuil wrote:
| The choice of symbols is brilliant! deshape
| flattens an array into a 1D array.
| huhtenberg wrote:
| Hmm, so [?]x10[[?]^999]
|
| yields a list of numbers, but [?]x10[[?]^1000]
|
| yields an audio clip. That's somewhat unexpected.
|
| The ^ above stands for the 3-dot cube dice glyph, which gets
| eaten by the HN backend, so it's ^ instead.
| hoosieree wrote:
| That surprised me too, but then I decided it was actually kinda
| brilliant. The alternative for when an array is "too big" to
| display is usually something like [1 2 3 ...
| 99999]
|
| Which is unsurprising, but not very usable. Audio is useful!
| shric wrote:
| My recent exposure to array programming languages came via a
| podcast called The Array Cast[1]
|
| Not affiliated, just recommending. The regular co-hosts appear to
| each be experienced with various array languages such as J, APL,
| etc. They don't get deeply technical, but it's a nice
| introduction, especially on explaining the appeal.
|
| A recent episode had Rob Pike (UTF-8, Go, etc.) on to talk about
| his array based calculator, Ivy[2]
|
| [1] https://www.arraycast.com/
|
| [2] https://github.com/robpike/ivy
| haolez wrote:
| Can array languages be used as general purpose languages in any
| practical way? Or are they really only strong as calculators?
| hoosieree wrote:
| They can be. I know J has libraries for databases, image,
| audio processing, etc. I've written an assembler in J and
| translated it to K. The array languages are pretty decent for
| prototyping machine learning stuff. Often you don't need any
| libraries at all.
|
| Here's a 2-layer perceptron, first in Python+NumPy:
| import numpy as np X = np.array([[0,0,1], [0,1,1],
| [1,0,1], [1,1,1]]) y = np.array([[0,1,1,0]]).T
| np.random.seed(1) w0 = 2*np.random.random((3,4)) - 1
| w1 = 2*np.random.random((4,1)) - 1 for j in
| range(10000): l1 = 1/(1+np.exp(-(X @ w0)))
| l2 = 1/(1+np.exp(-(l1 @ w1))) l2_error = y - l2
| l2_delta = l2_error * l2 * (1 - l2) l1_error =
| l2_delta @ w1.T l1_delta = l1_error * l1 * (1 -
| l1) w0 += X.T @ l1_delta w1 += l1.T @
| l2_delta print(np.round(l2,3)) [[0.007]
| [0.991] [0.992] [0.01 ]]
|
| And again in J: input =: 4 3 $ 0 0 1 0 1 1
| 1 0 1 1 1 1 target =: 4 1 $ 0 1 1 0 dot =:
| +/ .* sig =: {{ %>:^-y }} train =: {{
| 'ignore_me w0 w1' =. y l1 =. sig input dot w0
| l2 =. sig l1 dot w1 l2_error =. target - l2
| l2_delta =. l2_error * l2 * 1 - l2 l1_error =.
| l2_delta dot |: w1 l1_delta =. l1_error * l1 * 1
| - l1 w0 =. w0 + (|:input) dot l1_delta
| w1 =. w1 + (|:l1) dot l2_delta l2;w0;w1 }}
| 5j3":0{::train^:10000 {{<:+:?.y$0}} each 1 ; 3 4 ; 4 1
| 0.009 0.990 0.990 0.011
|
| Here's that assembler (for the Nand2Tetris assembly language)
| in K. It's intentionally golfed. L:({x^"\r
| "}'*'"/"\'0:0)^,"" T:(("R",'$!16)!!16),(($`SCREEN`KBD
| `SP`LCL`ARG`THIS`THAT)!16384,24576,!5),((-1_1_)'L@&i)!{x-!#x}
| @&i:"("=*'L
| T,:n!16+!#n:?(({$[("@"=*x)&^`I$1_x;1_x;`]}'L)^!T)^`
| C:(" "\"D&A D+A A-D D !D D-1 -D D-A D|A D+1 0 A !A A-1 -A A+1
| -1 1")!0 2 7 12 13 14 15 19 21 31 42 48 49 50 51 55 58 63
| D:$`" "`M`D`MD`A`AM`AD`AMD J:$`"
| "`GT`EQ`GE`LT`NE`LE`MP B:{,/$(x#2)\y} P:{c:*d
| :|"="\*j:";"\x;"111",/(B.7,(64*|/"M"=c)+C@"A"/"M"\c;B.3,D??d
| 1;B.3,J??1_j 1)}
| `0:({(P;{"0"^-16$,/$2\(`I$1_x)^T@1_x})[2/"@"=*x;x]}'L)@&~i
| spicybright wrote:
| Could you recommend a good starting episode? I know the
| generals of languages so I don't know if episode 1 is worth the
| time investment...
| shric wrote:
| Did you mean generals of array languages? I've only listened
| to the first 3 episodes so far and the Rob Pike episode[1] I
| mentioned. I have decades of experience in the popular
| programming languages and Lisp and some functional languages,
| but I'm new to array languages and I think I am the target
| audience.
|
| If you're already experienced with array languages I'm not
| confident to recommend any particular episodes yet. You might
| find the Rob Pike/Ivy episode entertaining but maybe not
| informative. Rob is not an array language expert (he says
| this in the episode) but he made Ivy partly from nostalgia of
| APL in his early days. His recollection of that era I found
| good to listen to.
|
| [1] https://www.arraycast.com/episodes/episode60-rob-pike
| yoyohello13 wrote:
| This is actually pretty neat. But I'm having a hard time
| understanding how to ergonomically write with glyphs. What's the
| intended workflow. Remembering a bunch of shortcuts to get [?]
| instead of just typing `find` seems harder to read and write.
|
| Edit: I think I understand from the language tour. You're
| supposed to write the ascii names like `find` then running the
| program converts built-ins to glyphs.
| camel-cdr wrote:
| I love the clear grouping of the of color coding.
| thesnide wrote:
| I wonder if someone made a language where color matters...
| ithkuil wrote:
| https://colorforth.github.io/cf.htm
| alexisread wrote:
| https://www.concatenative.org/wiki/view/colorForth
| j-pb wrote:
| Not sure if a joke referencing ColorForth. If not,
| ColorForth.[1]
|
| 1: https://en.m.wikipedia.org/wiki/ColorForth
| sondr3 wrote:
| You'll love Piet (https://esolangs.org/wiki/Piet) then :)
| SnooSux wrote:
| LMAO the trans flag colors for the transpose operator
| maximilianroos wrote:
| This is really cool -- great work.
|
| J & APL are elegant but not easy to get started with, and
| difficult to install. This looks like a newer, nicer, more open
| version.
|
| Would be great to see some Advent of Code puzzles in Uiua..
| aarroyoc wrote:
| BQN is also easier to get started. It's the only array language
| I ever tried because of that. Uiua seems to be inspired by BQN
| but it's also a stack-based language (BQN isn't).
| jonahx wrote:
| It seems _heavily_ inspired by BQN, even the style of the web
| page.
| diogenes4 wrote:
| I'm a big fan of stack-based languages conceptually, but they
| always seem to fall flat when it comes to basic reading
| comprehension. APL has the same issue, as does J. Factor did
| improve on this a little bit by eschewing the symbol fetish but
| it was still very difficult to rapidly scan the code for
| functionality. I'm not convinced the approach shown here is a
| good pairing with the human brain.
| 082349872349872 wrote:
| If (and I grant, this is a big _if_ ) you are used to them, the
| symbolic nature of APLs allows to discuss code fragments (and
| even entire* algorithms) using inline elements instead of as
| separate interspersed blocks.
|
| The difference between scanning algol-style and apl-style code
| is a little like the difference between scanning history books
| and maths books: on one hand, one must scan the latter much
| more slowly (symbol by symbol, not phrase by phrase), but on
| the other hand, there's much less to scan than in the former.
|
| * Edit: as an example, compare the typical sub-10 character
| expression of Kadane's algorithm in an array language with the
| sub-10 line expressions one typically finds online.
| saulpw wrote:
| APL people often point to the definition of "average" as
| evidence for its economy of expression: +//[?]
|
| They make the argument "the word 'average' has more symbols
| than its definition, so why not just use the definition
| inline as a tacit function?"
|
| There's some elegant beauty in this that I'm sympathetic to.
| However, I think it's fundamentally flawed for one big
| reason, which in my opinion is the core of the unreadability
| of APL (and other array languages that rely on custom
| symbology):
|
| Humans think in words, not letters. There is never semantic
| content in individual letters; a word is not defined by its
| letters. Sometimes a word's definition can be deduced from
| its syllables ("un-happi-ness") but the number of
| prefixes/suffixes is miniscule compared with the number of
| root words.
|
| We naturally chunk concepts and create referential
| identifiers to the abstractions. The point of an alphabet is
| to make the identifiers generally pronounceable and
| distinguishable.
|
| +//[?] is not pronounceable as a single word, even among APL
| experts ("add reduce divide tally" is not a word). We have a
| word for this concept in English, "average" (and synonyms
| "avg" and "mean"), in common usage among programmers and
| laymen alike. Using +//[?] to mean "average" would be like
| defining a function AddReduceDivideTally(x), which in any
| reasonable codebase would be an obviously bad function name.
|
| The semantics of array languages, like stack languages,
| already lend themselves to extraordinary expressivity and
| terseness, even without a compressed symbology. What is wrong
| with this? sum := add reduce
| average := sum divide tally
|
| I mean that is it, the essence of "average"! Anyone who knows
| both English and Computer Science can look at that and
| understand it more or less immediately. Compressing this into
| an esoteric alphabet does nothing for furthering
| understanding, it only creates a taller Tower of Babel to
| separate us from our goal of developing and sharing elegant
| definitions of computation concepts.
| alexisread wrote:
| I think for most people the learning curve is steeper with
| tacit languages, mainly as you have to hold the stack/array
| state in your head. Mathematicians will probably find it
| familiar, and as-per forth you could annotate with some sort of
| stack diagram for an aide memoire.
|
| If you're looking for something more understandable, rebol
| syntax is phenomenal. It's a concatenative prefixRL language
| like Uiua (forth is postfixLR), which you can use like a stack
| or array language by passing the stack/array as the far-right
| operand. http://blog.hostilefork.com/rebol-vs-lisp-macros/
|
| Furthermore it handles types and has (declarative) scoping
| unlike say forth which is typeless (panmorphic) and global.
|
| The idea with rebol, similar to Joy, is that operations-on-a-
| stack is analagous to passing-mutable-stack-to-function so you
| get tacit programming with both approaches. PrefixRL allows
| more of a lispy feel, especially when combined with blocks.
___________________________________________________________________
(page generated 2023-09-27 23:00 UTC)