Hi all! I created a little stack-based programming...
# share-your-work
m
Hi all! I created a little stack-based programming language which I'm using to solve Advent of Code this year. It's not as revolutionary as most of the projects here, the most interesting feature is the syntax, which uses forward Polish notation. In the future, I want to explore if this could work well for REPL-driven development. https://codeberg.org/marton/taka
🍰 1
❤️ 9
i
I'm twenty years into this racket and it's never before occurred to me that RPN implies FPN. So that's cool.
😂 1
Ahhh it's like s-exprs, sorta. Cool. Right.
m
Kind of but not really. The grouping happens by the number of items a function consumes from the stack instead of parens.
👍 3
g
various asides (hoping that they might provide further inspiration)... • the correct term for
forward polish notation
is
polish notation
(Perplexity (LLM)) • APL uses right-to-left evaluation but "parses" based on the operator,
2 x 3 + 4
evaluates to 14 (not 10) • Perplexity clarification: APL uses strict right-to-left associativity with uniform precedence •
+ * 2 3 4
in Taka is
(+ (* 2 3) 4)
in lisp and
(2 x 3) + 4
in APL and
2 x 3 + 4
in grade-school math and infix-with-precedence PLs •
2 x 3 + 4
in APL is
(* 2 (+ 3 4))
in lisp, hence,
* 2 + 3 4
in Taka (?) and
3 4 + 2 *
in Forth • TCL uses Polish Notation by default (TCL's
expr
provides infix) • Dylan, before being converted to infix, was Polish Notation (perplexity) • Lisp REPLs traditionally use the variable
*
to denote the last value computed in the REPL,
**
for the next-to-last, and so on (in lisp, the character
*
placed in the first position of an expression is treated as an operator not a variable (which leads into the lisp-2 v. lisp-1 rabbit hole) • REPLs are for program development, so "efficiency" has a different meaning (in a REPL, developer turn-around time is more important than production-level "efficiency") • I would be interested in your comments on the following thought, as you go down the REPL learning curve: I wonder if we no longer need to build REPLs into languages, but that we need to build languages around the UNIX shell to form a REPL capable of running many languages? I think that REPL is spelled wrong. There should be 2 P's. REPPL. • Not now, but, when you get back to exploring REPLs, you might wish to look at (and discuss) the following thoughts and further reading https://programmingsimplicity.substack.com/p/we-lost-something-1970s-repls-were?r=1egdky
In the 1970s, Lisp and APL REPLs represented something we’ve lost: true interactive, exploratory programming environments where developer feedback was instantaneous, context was persistent, and the entire system was designed around the developer’s cognitive workflow.
...
For decades, programming languages have tried to optimize for both development and production simultaneously, a conflation that created unnecessary complexity.
...
k
This loss is one of my topics in Redressing the Balance: A Yin-Yang Perspective on Information Technology. It's sad to look back at 30 years of working in computational science and noting that my (almost) first environment, APL, was the best I ever had in terms of being made for the work I do. "Almost" because my very first programming environment was BASIC on a TRS-80. I learned APL (initially on an IBM mainframe) a year later.
👍 1
j
@guitarvydas I disagree with your claim that “the correct term for
forward polish notation
is
polish notation
“, since “forward” in this context is helpful disambiguation. Wikipedia says “The term Polish notation is sometimes taken (as the opposite of infix notation) to also include reverse Polish notation” – that pattern of use means you need a term for non-reverse Polish notation that isn’t just “Polish notation”.
g
I don't really have a strong opinion on this. I was only going by what my LLM told me, and, we know that LLMs are always right,,, right? I've heard of RPN, but never of FPN (or even PN). If Forth is RPN, maybe Taka is RRPN? :-)
k
There's a term in linguistics (which I don't remember) for words that have changed meaning to the point that expressing their original meaning requires an additional tag. Example: landline phone/residential phone. FPN sounds much like that.
b
@guitarvydas I wouldn't call TCL "polish notation". TCL is prefix notation, and doesn't need parens for 1-level invocation, like all shell-like languages. But it does NOT infer nesting from known arity. You can use explicit brackets but you can't just write it flat: (for math, special infix parser expr was the original approach, but can import prefix commands that behave like any other commands)
Copy code
% namespace import ::tcl::mathop::*
% + [* 2 3] 4
10
% + * 2 3 4
cannot use non-numeric string "*" as right operand of "+"
which was the whole point: > I came upon the idea of a parenthesis-free notation in 1924. I used that notation for the first time in my article Łukasiewicz (1), p. 610, footnote. Uiua does accept
+ × 2 3 4
same as Taka — unsurprising, it's also stack-based and right-to-left. ML, F#, Elm, Haskell are I think are all prefix but not Polish, they don't use function arity to parse? Again, they have infix math operators but can define e.g.
Copy code
fun add x y = x + y;
fun mul x y = x * y;

add (mul 2 3) 4
But trying it now, I can't make flat
add mul 2 3 4
work in any of them. Well, these langs don't have real arity, they simulate
add 2 3
looking like 2-arg function call via currying, these parse as two 1-arg calls. Futhermore, they all encourage higher-order functions, so when they see
add mul
they can't say "ah mul is a function not a value, so I need to parse mul's arguments before returning to the outer add's arguments". Instead they try to call add with mul as an arg and then complain it's an
Int -> Int -> Int
while add wants an
Int
. Well, arguably a functional language could do type-directed-parsing? Are there any such? Possibly too DWIM but an intriguing space to explore... I don't think stack-based is the only way to process Polish notation, just very attractive for its simplicity. e.g. I think rewrite rules could do it too? P.S. wikipedia lists "prefix notation" as one of the synonyms for Polish. Nevertheless, I think that's the accepted name for the distinction I'm trying to make.
🎸 1
At first look: • Taka's use of quotations for definitions and control structures is reminiscent of PostScript and Factor, but prefix order is much saner to read 👍
.
delimiting RTL segments in longer LTR flow is similar to Uiua's RTL-within-lines but top-down order, but with clever "method like" syntax pun 😉
Played with it more, it's quite fun. Took the liberty of plugging taka in a new answer to @Michael Homer's 3yo question Should a concatenative language use prefix or postfix term ordering? I really like uiua & taka's top-down right-to-left order as a new local optimum! (I'm ambivalent about inline
.
; I feel it requires too much mental jumping from the reader, losing some of the 1:1 I find attractive in polish notation. YMMV. Formally
.
is same as a newline right? Maybe too much Python trained me to look differently at vertical "statements" vs. horizontal "expressions"...)
m
Cool, thanks for checking it out! I've had uiua on my radar and probably read the blurb like "yes, this is exactly what I want to have", but then forgot about it until I implemented Taka. I'll have to revisit it.
Formally
.
is same as a newline right?
Exactly. I find it convenient in some one-liners, like (random example from one of the AoC solutions)
something. map [text/split
'. filter [not empty?]]`, and for some simple infix-like things, like writing
x. + 1
or
if-else [x. = 123] ...
. But yeah it's best used sparingly. It's kind of annoying when I want to write
let $y x. + 1
but that doesn't work the way one might expect, instead it has to be
x. + 1. let $y
, or
let $y + 1 x
if that is readable enough. Assigning a name to a variable at the end of a "pipeline" is unusual, but tbh it could be used more, especially in an interactive REPL session. I've done it a few times in Clojure with
(->> ... (def result))
And yeah, I used forward PN to explicitly contrast it with RPN. And I kind of agree that RPN is so much more common that PN without any prefix could refer to that as well.