Skip to content

rocketnia/fexpress

main
Switch branches/tags
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Fexpress

CI

Fexprs are well-known to make compilation difficult in the general case. If the behavior of an abstraction can depend on the combination of run-time information and the exact source code the abstraction was called with, then some of the source code must survive as-is until run time.

Some of the source code. With Fexpress, we demonstrate that by adding cetain features to fexprs, we can compile code that doesn't depend on dynamic fexpr use:

> (define test-env
    (env-of-specific-values
      (hash 'the fexpress-the
            'ilambda fexpress-ilambda
            'clambda fexpress-clambda
            'funcall (lambda (f . args) (apply f args))
            '+ +
            '* *)))
> (define (logging body)
    (parameterize ([current-fexpress-logger pretty-print])
      (body)))
> (define (fexpress-eval-and-log expr)
    (logging (lambda () (fexpress-eval test-env expr))))
> (fexpress-eval-and-log
    '(funcall
       (clambda (square)
         (funcall
           (clambda (double)
             (funcall double
               (funcall double
                 (+ (funcall square 3) (funcall square 4)))))
           (clambda (x) (+ x x))))
       (clambda (x) (* x x))))
'("Evaluating Racket code:"
  (lambda (env -funcall -+)
    (lambda (-square)
      (#%app
       -funcall
       (lambda (-double)
         (#%app
          -funcall
          -double
          (#%app
           -funcall
           -double
           (#%app
            -+
            (#%app -funcall -square (#%datum . 3))
            (#%app -funcall -square (#%datum . 4))))))
       (lambda (-x) (#%app -+ -x -x))))))
'("Evaluating Racket code:" (lambda (env -*) (lambda (-x) (#%app -* -x -x))))
100

The above code only invoked global variables, and those global variables were procedures and a certain fexpr (fexpr-clambda) which implemented its own compilation support, so the result was fully compiled code.

To invoke only global variables, that code uses a Lisp-2-style funcall operation. If it had invoked the local variables directly, Lisp-1 style, Fexpress's implementation wouldn't figure out that they weren't fexprs, so it would have generated code that called back into the interpreter for those calls.

But Fexpress shows off another solution for that. Using rudimentary type annotations, even the Lisp-1 style can turn into efficient code:

> (define my-compose
    (fexpress-eval-and-log
      `(the ,(->/t_ (list (non-fexpr-value/t+))
               (->/t_ (list (non-fexpr-value/t+))
                 (any-value/t_)))
         (clambda (f)
           (clambda (g)
             (clambda (x)
               (f (g x))))))))
'("Evaluating Racket code:"
  (lambda (env)
    (lambda (-f) (lambda (-g) (lambda (-x) (#%app -f (#%app -g -x)))))))
> (logging (lambda () (((my-compose sqrt) add1) 8)))
3

For more information on the way Fexpress is built, what extension points and building blocks it has available, and where it might go from here, see the documentation.

The current incarnation of Fexpress is merely a proof of concept. We've prioritized simple and direct implementation to demonstrate the concepts, and the API may be unstable as a result. This version will stick around and keep serving as a demonstration, but we also envision making a more full-featured and stable Fexpress alongside it.

Installation and use

This is a library for Racket. To install it from the Racket package index, run raco pkg install fexpress. Then you can put an import like (require fexpress/proof-of-concept) in your Racket program.

To install it from source, run raco pkg install from the fexpress-lib/ directory.

Documentation for Fexpress is available at the Racket documentation website, and it's maintained in the fexpress-doc/ directory.

About

A compilation-friendly fexpr language. (Proof of concept.)

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published