5.7.20  Mythryl eval Operators

Scripting languages such as Perl frequently implement an eval operator allowing execution of source code strings dynamically created by the running script. This has a variety of handy uses ranging from implementing systems which interactively execute user-entered code to system which dynamically compile special-case code at need.

The SML/NJ codebase has been implemented from the start upon an incremental compiler design which makes implementation of such an operator straightforward, but unfortunately there has never been a supported interface to this functionality. Thus, for example, Moonflare’s MLud server written in SML/NJ had to use an undocumented API to access this functionality, which API was broken by subsequent releases. Perhaps uncoincidentally, development of this software ceased shortly thereafter.

Mythryl implements a supported eval operator for accessing incremental compilation functionality:

    linux> my

    eval:  evali "2 + 2";


Perl and bash, being dynamically typed, are not bothered by the fact that the type of eval depends entirely upon the contents of its string argument.

In a language like SML or Mythryl, this ill-typedness is more problematic. This is not an unsurmountable problem. If it were, SML’s interactive mode would not be able to print out the value and type of interactively entered expressions. But the solution is not something you would want to examine immediately before a meal. This problem may relate to the lack of a supported SML/NJ API for accessing incremental compilation functionality.

Eventually, eval should be tweaked to have type String -> X where X can change from invocation to invocation. (Implementing this might be a nice undergrad compiler course project. Email me a patch and I’ll merge it in!)

For the moment, at least, Mythryl’s solution is just to supply in the library a half dozen odd statically typed eval variants covering common cases:

    eval:   String -> Void;

    evali:  String -> Int;
    evalf:  String -> Float;
    evals:  String -> String;

    evalli: String -> List( Int    );
    evallf: String -> List( Float  );
    evalls: String -> List( String );

Additional variants may be implemented as needed by cloning and tweaking the existing routines.

This isn’t a great solution, but it is much better than nothing!

Comments and suggestions to: