Sunday, August 20, 2017

Cutting Guards

I wrote a small example program, found that the source-to-source transform for getting rid of guards was faulty, and found that since I allow for a variadic number of arguments, a trivial transform doesn't exist.

Below, an example:

     def f = [ X ? X == 0 -> 1 | -> 15 ]

The problem with a variadic number of arguments is that in the above example you would need code for the case where an argument is consumed, but the match failed, and for the case where an argument isn't consumed. Thus, in a trivial solution, you'd copy code for every guard.

There is no trivial solution without copying code - a potential exponential blow-up -, moreover guarded matches add little in expressiveness over just using an if-then-else. I decided to cut guarded commands.

Friday, August 18, 2017


Well, in Egel you can trivially write down variadic functions, like sum shown below.

>> def sum = [ X, Y -> sum (X+Y) | X -> X ]
>> sum 1 2 3 4

But is the reverse possible too? Best I got to was this:

>> def un = [ 0 -> 0 | N -> N (un (N-1)) ]
>> un 5
(5 (4 (3 (2 (1 0)))))

I think I need something like a reverse too though I am not sure. Also get the feeling I am reinventing Lisp. Which is a bad idea I guess, Lisp will always be better at being Lisp than Egel will ever be.

Changes in the Operational Semantics

I decided to make a fundamental change in the semantics. Egel is untyped, so you need to deal with the case where a constant is applied to another constant; i.e., what does "a" 1 reduce to?

I sidestepped the issue until now and went for a scheme where "a" 1 reduces to "a", thus every constant gobbles up any arguments supplied to it. Mostly I did that because it was convenient, the code is somewhat shorter.

But it seems more natural to simply not reduce; i.e., the result should simply be "a" 1. That seems like a little change but users might make small typos, like forget an operator, and find it too hard to debug a program where constants 'magically' disappear.

The trivial case is easy to implement but now all operators also need this behavior. I.e., (1+2) 3 now reduces to 3, whereas it should reduce to 3 3.

Wednesday, August 16, 2017

Log 081617

Well. I ticked off the items on my to-do list. So, the new one:
  1. Switch over to the standard syntax for 'let'.
  2. Allow for assignment in the REPL.
  3. Maybe allow for object definitions in the REPL.
  4. Support a time-out in the IRC bot.
Another four items. Great!

Tuesday, August 15, 2017

Log 081517

The byte code generation bug turned out to be insignificant but in order to debug it, I changed some code first to trivialize some invariants, then I found the snag.

I fixed some small stuff but didn't find the motivation yet to tick off other parts of the to-do list.

Sunday, August 13, 2017

Log 081317

I implemented a quick-and-dirty IRC bot for Egel, a C++ application which allows for online evaluation. That gave me the opportunity to work on a somewhat neat manner of incorporating the Egel runtime in a C++ application.

It works but not to my satisfaction. I need to change and support two things: 1) Evaluation now works in a cumbersome manner with callbacks which need to go. 2) I need to think about a scheme to call Egel routines from the evaluator. I am not sure what I want here but some tighter integration seems in order.

I also found a not so nice bug in bytecode generation. Well, that's a show stopper. I am not worried since I trust the evaluation scheme I got but annoyed that a bug like that can pop up that late during development. I need to either test a lot or idiot proof it, and it turns out I am not idiotic enough to write down really strange programs which bring all bugs to the surface.

Then there is OO. I think I'll need syntactic sugar for an extend relation. That's not too hard but some work.

So, in order, my small todo list below:
  1. Fix the byte generation bug.
  2. Make calling the evaluator sane.
  3. Add extend relation to objects.
The work is never done.

Friday, August 11, 2017

Log 081117

I implemented a scheme for creating objects but I didn't add a safe scheme yet for destructive assignment.

For the moment I see three different approaches:
  1. Ignore, just let cycles be created. This what I have now.
  2. Detect cycle creation, and fail if a cycle would be created.
  3. Conservatively copy, that part of the tree which holds the cyclic reference is copied.

I am also working a bit on an IRC bot but didn't progress very far yet.