For a while now I've been wanting a generic notation to explain various things on my wiki(tropical arithmetic, multisets, other programming languages, ternary logic, primes, etc..) and I found a PL design I really enjoy writing.

It lands in a weird place, I feel like it might be the only concatenative language without a stack? As far as I know anyways.

I took a day to implement it, and shoved it into a little interactive playground. I have yet to populate the examples.

https://wiki.xxiivv.com/site/rejoice
https://wiki.xxiivv.com/etc/rejoicerepl/

@neauoire This may be the first concatenative notation for a counter machine that isn't rule-based. There is at least one deque catlang that has been made.

Also, based on our talks of how rejoice executes, would you have a ton of junk operation in your call queue?

@andnull yeah, but no junk, only the whole program basically. Kind of like Joy I suppose?

ex:

@neauoire Poking around and reading the docs, it seems like things are a bit different from the last time I peak at Rejoice. I was thinking when it was still "replace symbol with definition".

times^5
@Loop
Loop/times junk

I believe before this would have left a bunch of unevaluated junk items in the pending queue. The end result would have been [junk^5] but now it's [junk]. Gonna make recursion tricky cause you essentially only have tail recursion. The non-determinism of multiple address compounding that 

@neauoire A simple demonstration of the "multiple label" behavior in your implementation of Rejoice. Could be worth adding as an example of what can/could happen.

[JumpA JumpB JumpC]

@JumpA a
@JumpB b
@JumpC c
[] [JumpA JumpB JumpC] a b c
[] c
[c] b c
[b c] a b c
[a b c] b c
[a b^2 c] c
[a b^2 c^2]
@andnull Yes! I have a ton of explaining to do still, this is kind of a early draft. Right now there's no subroutine calls, so it's quite limiting. I'm not sure how close to a full programming language I want to get yet.

@neauoire Subroutines would irocinally be falling back into typical FRACTRAN. But with the power to specify many loops and decode prefix tree*. I have a multistack esolang specdraft called AGAIN built around that idea. Gonna be updating it Eventually (tm) with HERE/LEAVE operations.

* I can show what I mean in a bit

@andnull the idea here was to have exactly that fractran but with GOTOs, to do away with the cost of scanning the entire program everytime, not that I need speed for this, but it comes with more readable programs as well, which I wanted. I tried a lispy UX at first(Bägel), but it was clumsy, it seemed like catlang was, once again, hitting all the marks.

I think the main point I'm going for is to have multisets as datastructure, concatenation flow ended up being what was most natural.

If I don't need subroutines to explain some of the stuff I'll use this for, I think.. I might just not add them X) We'll see, tail recursion might be enough.

@neauoire Okay, messing about. I have an example of what subroutines with returns look like in Rejoice:

done-a PutAs @DoneA
done-b PutBs @DoneB
done-add A+B->C @DoneAdd
.#c

@PutBs
b b b b b
Return

@A+B->C
@A->C [c A->C]/a
@B->C [c B->C]/b
Return

@PutAs
a a a
Return

@Return
[DoneA]/done-a
[DoneB]/done-b
[DoneAdd]/done-add

Basically, push a symbol the mark your return point then jump to the subroutine. Once the subroutine ends jump to your return handler. The return handler then finds the "entry" point you program should return to. Surprisingly graceful construct compared to how I thought it'd look.

@andnull WOA WAT

@neauoire This kinda of "mapping return locations to symbols" is partially what inspired AGAIN. In this cause, it doesn't have gotos (aside from AGAIN which jumps to the top of the program), but you can emulate gotos by pushing a prefix to the code you want to run.

In the case of Rejoice, you push a symbol that can be decoded into an address to return back to.

Esolang: AGAIN

@andnull Is it alright if I shape this example in a way I can document it on the page? I think it's quite cool, I don't think I've ever come across this way of emulating subroutines. Do you happen to have fizzbuzz or tictactoe in AGAIN?

@andnull ok I see how AGAIN is similar, you can never jump forward in again right? Other than walking over a bunch of IF..END blocks.

Oh this is so cool, I hadn't caught this the first time I read through your posts about AGAIN.

@neauoire
1) feel free to lift whatever you want from AGAIN. It's a very conceptual page rn.

2) Not, yet, I need to write an interpreter for AGAIN. It currently exist as a little thought experiment / unimplemented specthing. I could make that my little task for tomorrow.

3) That is correct, AGAIN can only jump backwards via AGAIN or forwards with IF/END. Rejoice is more flexible since there is arbitrary jumps forwards and backwards. However, both are share the limitation that you have no return stack of addresses. Thus you need a mechanism for turning Symbols into Locations. In AGAIN, it's via "walk a prefix". For Rejoice it's "decode a symbol to an address using a LUT".

@neauoire I have been kinda obsessed with like:

  • Every program can be describe as prefix trees to specific instruction.
  • Event-based programming is kinda like searching for an entry point into a function with multiple starting points.
  • How do you do function calls when all you have is symbols, conditional control-flow, and loops.

I kinda have a small notebook filled with scribbles that need writing at some point.

@neauoire Also, state machines, I have just been obsessed with state machine lately.
@neauoire I guess a short way to put this whole thing: you have to encode call/return as a set of state transition when you don't have return addresses.
@andnull just got back from dinner, I'll experiment with these return trampolines of yours! You have excellent intuition for these really bizarre systems, I love to see you do your magic like that. 

@neauoire What's fun is this lends naturally to say...

@OnScreen ( -- )
...
Done

@OnTick ( frame -- )
...
Done

@Done
( possible co-routines in the bag or something )
...

@andnull I've been porting some Fractran programs, and made this multiplication function, which shows a bit how it short-circuits matching.

x^3 y^4

@Mul ( x y -- res )
[Mul z res]/y
@Move ( z -- y)
[Move y]/z
Mul/x
@Clean ( y -- )
Clean/[res y]

@neauoire Yeah, I realized my A+B->C rule could decompose into A->C and B->C allowing for a tighter looping process.
@neauoire Also, I think this generalizes a ton of patterns I was using in Vera like a million times better.