Morel release 0.5.0
I am pleased to announce Morel release 0.5.0. Coming fourteen months after release 0.4.0, this release contains various extensions to syntax to make the language more powerful and easy to use.
We describe a few of the new features in this article. For more information, see the official release notes.
1. List-valued functions in pipelines (into and through)
[MOREL-171] lets you
use list-based functions in a pipeline, adding two clauses to
the from expression:
intooccurs at the end of a pipeline, and converts a list to a scalar value;throughoccurs in the middle of a pipeline, and converts a list into another list.
First, into.
from scans steps into expression
is equivalent to
(expression) (from scans steps)
expression must be a function of type 'a list -> 'b (for some
types 'a and 'b), and if the output of the last step is 'a then
the type of the whole from expression is 'b.
For example, sum has type int list -> int, and so into sum
converts a stream of int values into an int result.
Next, through is similar to into, but has a pattern so that
following steps can refer to the data items:
expression1 through pattern in expression2 steps
is equivalent to
from pattern in (expression2) (expression1) steps
For example, suppose we have a clean_address function that takes a
list of orders and returns a list of orders with state and zipcode
filled out. To stream orders through this function, we simply add the
line through clean_over in clean_address to the pipeline.
Note that the pipeline function itself takes a list argument and
returns a list. We could therefore include it in a higher-level query
using the through keyword, and include that query in another query.
The into and through keywords, combined with Morel’s ability to
include queries in function declarations, allow us to do something
very powerful: to compose complex and efficient data flows from
concise functions.
2. Comma-separated scans
If you speak SQL, you will know that there are two ways to write a join:
-- Comma syntax
SELECT e.ename, d.dname
FROM Emp AS e,
Dept AS d
WHERE e.deptno = d.deptno;
-- ANSI (SQL-92) syntax using JOIN keyword
SELECT e.ename, d.dname
FROM Emp AS e,
JOIN Dept AS d ON e.deptno = d.deptno;Morel has analogous syntax:
but used to only allow the comma join syntax immediately after the
from keyword, before clauses such as where or join had occurred.
Following
[MOREL-216], Morel
allows comma-separated joins later in the pipeline, and also allows
on in comma-joins. The following is now legal:
This will be particularly convenient (when we have solved some query-planning issues in [MOREL-229]) for writing queries that use unbounded variables to solve constraints:
3. Duplicate elimination (distinct)
[MOREL-231] adds a
distinct clause to the from expression. It makes the rows unique.
Here is a query that finds the set of distinct job titles:
distinct is short-hand for group with all fields and no aggregate
functions (compute clause), and is similar to SQL’s SELECT
DISTINCT.
4. Multiple branches in fn
[MOREL-230] allows a
lambda (fn expression) to have multiple branches, similar to case.
Following this change, the following expressions are equivalent:
Prior to this change, the first expression would give a syntax error.
5. Int structure
[MOREL-228]
implements the Int structure, a collection of functions and values
related to the int type.
Per Moscow ML it has the
following interface:
Example use:
The Int structure is an instance of the
INTEGER signature in the Standard ML Basis
Library but Morel
does not currently have signatures.
Conclusion
Now that I have resigned from Google, I will have more time to work on Morel bugs and features, in two areas in particular.
I want to improve how Morel handles
ordered and unordered multisets,
because SQL tables are unordered, functional programming languages use
ordered lists, and real applications need to mix both.
We will add a bag type, and to keep the
Hindley-Milner type system
happy when converting between the list and bag types, we will need
better support for
operator overloading.
I believe that Morel can be an attractive solution for graph, deductive and constraint-programming problems. To that end, I will be working on constraints, universal and existential quantifiers, deduction of ranges, and tail-call optimization.
If you have comments, please reply on Bluesky @julianhyde.bsky.social or Twitter:
I am pleased to announce release 0.5 of @morel_lang, 14 months after release 0.4. There are several syntax extensions to make the language more powerful and convenient, including 'into', 'through' and 'distinct'. https://t.co/ultWQwErar
— Julian Hyde (@julianhyde) March 5, 2025
This article has been updated.