Here's a fun little exploration I finally got to t...
# share-your-work
j
Here's a fun little exploration I finally got to turn into something real. (I was thinking about this back in 2020 and got derailed). What if we could make visualizations for the running state of our programs not by augmenting them inline with traces and prints, nor creating a vm in our language to high-jack the execution and record what we want, but instead our language itself could talk about its own execution? I put together a little proof of concept of such a language. It is just a little term rewriting language, but in it you have meta rules that will match on the execution of the programming itself (I do not yet have meta meta rules (ad infinitum), but there is nothing at all that would stop you from doing this and if I made this real I'd definitely do it). https://jimmyhmiller.com/term-rewriting-experiment-one
🙌 2
🤩 11
i
ah that's a fun idea. i've passed this along to june (who made nova) since it seems like the sort of thing that'd be super easy to do in that language. will let you know if hijinks ensues.
j
Yeah, I just discovered nova. Looks really nice. Great to see more term rewriting based things. Definitely an under explored paradigm
1
w
"but instead our language itself could talk about its own execution" @Jimmy Miller you are trolling me. Look up Aspect Oriented Programming. You're welcome. 🤓
j
Yeah I'm familiar. I've even read Warren Teitelman’s thesis where advice comes from. But I think at least in the implementation what I have is a bit different. `fib(5)`*→ `add(fib(sub(5, 1)), fib(sub(5, 2)))`* I don't know any aspect that lets you get things like this. They instead are about function boundaries. (Pardon the bad formatting, on mobile)
w
Probably a little different. What's the "this" you have exactly in mind? Being able advise evaluation in the way your meta rules do? I think this demo super neat and would love to understand better.
j
So at the limit, the whole entire language is just meta rules. Or a tower of meta rules. Meta rules not only see the computation, they can decide to change it. We can change our evaluation order from strict to lazy for example. Meta rules also can play the rules of macros but at a global level. They are a metaprogram that is given not only the static definition of the code, but all the code at every step in the execution.
👍 1
j
awesome stuff.
❤️ 2
w
I've often thought of a kind of thing close to what you're talking about Jimmy. I call it a "doodad" pun on functional monad, and related, you guessed it, to propagator networks. In the context of meta rules, it's a value that brings its own. Suppose
trace()
is a doodad that lifts a value to be traced to how that value is used, so when you write
fact(trace(5))
instead of
fact
being responsible for the reduction,
trace
is, and it could keep the trace count like your
tracer
does. The difference is that a doodad is like a continuation. However, you use the result of
fact(trace(5))
that would continue to be traced. You could stop it with something like a
run
in the monadic sense. WHY? Have this kind on construction. I don't know. Maybe
fact(lazy(5))
, where
if
is the forcing function. Just a thought.
j
@wtaysom I tried to get my little prototype to do that. But didn't quite have the time. But I definitely love this feature and this is the kind of stuff I want to be able to do just at the meta level. In my mind, there should be a 3-5 line meta rule that would make your trace automatically work.
👍 1
f
Arriving very very late to the party, but super interesting @Jimmy Miller!! I'm doing something very similar in cell. The expansion is part of the data, and the code can look at expansions at runtime. Have you considered making the "meta" just part of the normal level of the language, somehow?