Fri 2022-05-13

Dynamic Libraries

I added new Fexl functions dlopen and dlsym to read dynamic libraries.

It is now possible for a Fexl program to create and run C code on the fly. To do this it would write the code into a file, compile it into a shared library, load the library with dlopen, grab the new functions with dlsym, and run them.

Here is the commit on GitHub.

Fri 2022-04-29

Opinionated Programming

This morning I wrote this piece on the subject of Opinionated Programming.

Tue 2022-04-26

Template Expansion Function

I wrote this piece on the subject of Template Expansion in Fexl.

Sat 2022-02-26

More on functional components

I added a section "Elaborating on the process" to the article on functional components.

Fri 2022-02-25

Restored fexl0 feature

I released version 26.12.0 this morning, which restores the "fexl0" feature to bypass the built-in src/main.fxl library. The comment on the eval_script routine in type_standard.c now reads as follows:

Evaluate the user's script. Read the script from the file named by argv[1] if present, or from stdin otherwise.

If this program is running as "fexl0", it runs your script directly. If it is running as "fexl", it first runs the local script "src/main.fxl", which then runs your script within an extended library context.

The purpose of "fexl0" is to give you the option of bypassing src/main.fxl altogether, defining any extensions beyond the built-in C standard context as you please.

In a future release I will make fexl0 the default behavior, so it always reads your script directly without loading any default library. Predefined libraries such as the current main.fxl will be provided in the lib directory so you can pull them in with a one-liner.

I am making this change because the one-size-fits-all approach to a standard library is a losing proposition. Eventually I might even factor out the currently built-in C functions into independent libraries loaded on demand. Then you could build an entirely separate C library, put it in your own directory somewhere, and load it from within Fexl. That would even give you the power to generate binary code on the fly and run it immediately.

Mon 2022-02-21

Some notes on Fexl

Today I posted this comment to a Magmide discussion list. Here's what I wrote.

You might want to check out some of the concepts in my functional programming language Fexl. I have been using it almost exclusively for years in my business, which is accounting for investment partnerships.

Fexl is not statically typed. I figured if I wanted to build a static type system, I would do that in Fexl itself, which would start off untyped. So far I have not been inclined to do static typing. Good systematic development with regression testing and full coverage have worked very well for me. Personally, I find statically typed languages to be too burdened with cumbersome declarations.

Although Fexl is not "purely functional," you can make any program be exactly as "pure" as you want it to be. For example, I/O is straightforward, so the "Hello, world" program is simply; say "Hello, world." There is no "monad" there, just a call to the "say" routine. To make that program purely functional, you would write a function that returned the string "Hello, world." Then a higher-level "impure" layer would be tasked with applying "say" to that result.

If you want to do "memoized" functions, Fexl has routines for doing mutable variables. This can be nice for optimizing naive versions of recursive functions like Fibonacci, or the Partition count function which is far more self-recursive. (Note: I'm personally in favor of a more purely functional approach to memoization, where an immutable cache table is explicitly passed around in and out of the function, but sometimes the grungy mutable approach will save you in a pinch.)

Fexl represents recursion explicitly using the fixpoint operator, which I denote by "@". The nice thing about explicit fixpoint recursion is that a call to a recursive function can be expanded directly in place -- i.e. referential transparency applies here as well. You can also identify some interesting optimizations where some parameters are fixed and do not need to be passed into recursive calls. (Note: Tail recursion "just works" because of how I do parameter substitution. I don't have to do anything special to get it.)

Fexl also has a very useful feature for idempotent "once" calculations. If you have an expression such as (f x y) buried somewhere, and maybe it takes a long time to run or even has side effects you only want to happen once, you can change the expression to (\= f x y) and then it only runs once, if you happen to call it. I cannot emphasize enough how useful and convenient that is for my real project work.

My design goal for Fexl was to have a language which is as close to pure lambda expressions as possible, with additional syntax added only to make it practical. Most of the additional syntax has an equivalent plain lambda expression. Another goal was to implement Fexl in the smallest feasible plain C code, which I think I've done.

I'll leave it there for now. If you'd like me to elaborate anything further, please let me know. You may find some of the ideas helpful in your efforts. For example, I think I've done very solid work on concepts such as parameter substitution, and the closely related concept of modularity, which Fexl handles using functions known as "contexts."