Sunday, October 31, 2021

Byte Code Player/Recorder/Optimizer

 Right, so due to side-effecting code a range of optimizations is out of reach. For example, even beta reduction is unsafe under most circumstances. Like below.

  (\f -> f . f)  (print 'hello'; (\x -> x + 1)) 0

That gives one side effect strictly right-to-left reduced, but two when 'optimized' by first beta-reducing the term.

HOWEVER,

It should be safe to just observe what bytecode instructions were emitted during the normal evaluation and glue those together.

At some point, I am going to optimize with some kind of bytecode player/recorder.



Static Programming

 I thought about dynamic programming, ... and then decided against it. Though I want people (me) to be able to inspect the runtime, I don't want people to be able to modify it (except maybe through loading modules).

Simple reason: when the meaning of a symbol doesn't change that shaves off a lookup over a table, plus you enable optimizations, and that implies way faster code.

Saturday, October 30, 2021

Friday, October 29, 2021

Searching is calculating, parsing is searching

 I elaborated on the previous small theory and implemented search combinators which I used in a small example to write a parser/evaluator for a simple expression language.

Thursday, October 28, 2021

Calculations

I added a small theory of calculations modulo a state and an example. A calculation consists of chained actions where an action is a function working on a state returning a result and a new state.

The gist is:

    ## Calculate:return a - calculate further with value a                                           

    def return =

        [ A S -> (A, S) ]                                                                            


    ## Calculate:chain f g - first do f, then g                                                      

    def chain =                                                                                      

        [ F G S -> [(A, S) -> G A S] (F S) ]                                                     

                                                                                                     

    ## Calculate:run f s - run calculation f on state s                                              

    def run =                                                                                        

        [ F S -> [(A, S) -> A] (F S) ]    


Which are, of course, a monad return and bind with a run function.

The calculation theory and the state game. The state game is straightforward, state and manipulation functions are defined, after which the game loop function results in a chain of actions, which are run on the state.



Tuesday, October 26, 2021

Pre-release v0.1.1: hotfixed critical regression

 So, a critical regression made the interpreter stall on large input. I followed a hunch that since the lexer became LL(n) instead of LL(1) the UnicodeString's charAt32 method kept resetting an internal pointer resulting in quadratic behavior. The fix worked.

Back at 50KLoc/sec parses on a synthetic example. It warranted a pre-release of v0.1.1 because this was a show-stopper for me.

Ah well. Neat, I guess.

FreeBSD 13.0 compile and install

The Egel interpreter now works on FreeBSD though you need to set the include environment variable. Took me a day to get FreeBSD+dwm running under Qemu on my Macbook Air M1, but felt worth it.