diff --git a/HISTORY.md b/HISTORY.md
index bf42518b..ed3a698b 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -23,6 +23,106 @@ License.
For a full list of releases, see
github.
+## 0.4 / 2024-01-04
+
+Release 0.4 extends `from` syntax, adding
+`suchthat`,
+`take` and `skip`
+clauses; allows identifiers to be
+quoted using backticks;
+improves pretty-printing of
+tuples and
+long lines.
+
+Contributors:
+Julian Hyde,
+Rette66
+
+### Features
+
+* [MOREL-204]
+ Add `take` and `skip` relational operators
+* [MOREL-209]
+ File reader, and progressive types
+* [MOREL-210]
+ Fold long types when printing
+* Rename `Option.flatten` to `Option.join`
+* [MOREL-71]
+ Allow identifiers to be quoted using backticks
+* [MOREL-206]
+ Indent tuples when printing
+* [MOREL-129]
+ Define relations via constrained iterations, and introduce a `suchthat`
+ keyword to use them
+
+### Bug-fixes and internal improvements
+
+* Add `directory` property to `Session`
+* Add type parameter to `Core.Literal.unwrap()` method
+* [MOREL-208]
+ `FromBuilder` should remove trivial `yield` step between two scan steps
+* [MOREL-205]
+ Pattern that uses nested type-constructors should not be considered
+ redundant
+* Add utility methods `Static.transform` and `transformEager`
+* [MOREL-203]
+ Cannot deduce type for `from b in [SOME true, NONE]`
+* Refactor: In `Unifier.Variable`, store ordinal rather than computing it
+* Refactor: Rename `Ord.forEach` to `forEachIndexed`
+* In `CoreBuilder`, add `tuple(TypeSystem, Exp...)`, a more convenient
+ `apply`
+* Simplify `EnvShuttle`, `EnvVisitor` by adding `push` method
+* Add `interface PairList` and `interface ImmutablePairList`
+* Add method `Static.nextPowerOfTwo`
+* [MOREL-201]
+ `Real.signBit` gives different result on JDK 19/ARM
+
+### Build and tests
+
+* Run `script.sml` in tests
+* [MOREL-207]
+ Detect and fix flaky tests
+* Disallow static star import
+* [MOREL-200]
+ In the test suite, run arbitrary "lint" checks on code
+* [MOREL-198]
+ Idempotent mode for test scripts
+* Add a test for various closure and recursion scenarios
+* Allow CI runs to be triggered manually, and monthly
+
+### Component upgrades
+
+* Bump build-helper-maven-plugin from 3.3.0 to 3.5.0
+* Bump calcite from 1.32.0 to 1.36.0
+* Bump checkstyle from 10.3.4 to 10.12.7
+* Bump guava from 31.1-jre to 33.0.0-jre;
+ increase minimum guava version from 19.0 to 21.0
+* Bump hsqldb from 2.7.0 to 2.7.2
+* Bump javacc from 7.0.12 to 7.0.13
+* Bump jdk to 21; minimum jdk is still 8
+* Bump jline from 3.21.0 to 3.25.0
+* Bump junit-jupiter from 5.9.1 to 5.10.1
+* Bump maven-checkstyle-plugin from 3.2.0 to 3.3.1
+* Bump maven-compiler-plugin from 3.10.1 to 3.12.1
+* Bump maven-enforcer-plugin from 3.1.0 to 3.4.1
+* Bump maven-javadoc-plugin from 3.4.1 to 3.6.3
+* Bump maven-project-info-reports-plugin from 3.4.1 to 3.5.0
+* Bump maven-release-plugin from 2.4.2 to 3.0.1
+* Bump maven-scm-provider-gitexe from 1.9.1 to 2.0.1
+* Bump maven-site-plugin from 3.12.1 to 4.0.0-M13
+* Bump maven-source-plugin from 3.2.1 to 3.3.0
+* Bump maven-surefire-plugin from 2.22.2 to 3.2.3
+* Bump slfj from 2.0.3 to 2.1.0-alpha1
+* Add versions-maven-plugin version 2.16.2
+* [MOREL-199]
+ Support JDK 19 and 20
+
+### Site and documentation
+
+* [MOREL-211]
+ Release 0.4
+* Add Maven Central badge to `README.md`
+
## 0.3 / 2022-10-02
Release 0.3 extends `from` syntax, adding an
diff --git a/NOTICE b/NOTICE
index 50dfeddc..a2b5cc4a 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,7 +1,7 @@
morel
Standard ML interpreter, with relational extensions, implemented in Java
-Copyright (C) 2019-2022 Julian Hyde
+Copyright (C) 2019-2024 Julian Hyde
All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/README b/README
index 59b70f21..9c285aec 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-Morel release 0.3.0
+Morel release 0.4.0
This is a source or binary distribution of Morel.
diff --git a/README.md b/README.md
index ff7d58b7..7dfa0cf2 100644
--- a/README.md
+++ b/README.md
@@ -44,7 +44,7 @@ Get Morel from
net.hydromatic
morel
- 0.3.0
+ 0.4.0
```
@@ -69,7 +69,7 @@ If you are using Java 8, you should add parameters
```bash
$ ./morel
-morel version 0.3.0 (java version "13", JLine terminal, xterm-256color)
+morel version 0.4.0 (java version "21", JLine terminal, xterm-256color)
- "Hello, world!";
val it = "Hello, world!" : string
- exit
diff --git a/docs/howto.md b/docs/howto.md
index 0915470f..f82ffce5 100644
--- a/docs/howto.md
+++ b/docs/howto.md
@@ -39,7 +39,7 @@ Update version numbers in
`src/main/java/net/hydromatic/morel/Shell.java`, `README` and
`README.md`, and the copyright date in `NOTICE`.
-Switch to JDK 11.
+Switch to JDK 21.
Check that the sandbox is clean:
diff --git a/src/main/java/net/hydromatic/morel/Shell.java b/src/main/java/net/hydromatic/morel/Shell.java
index 458bc5e0..517df014 100644
--- a/src/main/java/net/hydromatic/morel/Shell.java
+++ b/src/main/java/net/hydromatic/morel/Shell.java
@@ -208,7 +208,7 @@ private static boolean canIgnoreLine(StringBuilder buf, String line) {
/** Generates a banner to be shown on startup. */
private String banner() {
- return "morel version 0.3.0"
+ return "morel version 0.4.0"
+ " (java version \"" + System.getProperty("java.version")
+ "\", JRE " + System.getProperty("java.vendor.version")
+ " (build " + System.getProperty("java.vm.version")