Introducing Tourio: An AI-powered visitor guide for museums, galleries and exhibition spaces.
The YouTube channel BEAM There, Done That has new video about the origin of the BEAM:
30 Years Inside the BEAM: Björn Gustavsson on Building Erlang’s Runtime
With Ubuntu/Kubuntu out of the running for “works and is mostly sane”, we are having to shift once again over to Devuan, which we have been using for servers for several years now at Tsuriai and QPQ, but not as often on desktops (because Kubuntu was just so convenient and changing habits is annoying).
This post will cover Erlang and ZX, specifically, and I’ll do another one about how the app-level transition feels moving from Kubuntu for desktop to Devuan. (Migrating servers from Ubuntu to Devuan is really easy and a major relief: everything is just simpler, flatter, more boring, and works as any SysV init system should.)
As a pseudo script:
# To run the next stuff as root we 'su -'
su -
apt update
apt upgrade
# If installing on a non-graphical system, omit the libwxgtk dep
apt install \
gcc curl g++ dpkg-dev build-essential automake autoconf \
libncurses-dev libssl-dev flex xsltproc libwxgtk3.2-dev \
wget vim git
# Get out of root now and run everything else as a normal user
exit
# Create directories we'll need
mkdir -p ~/vcs ~/bin
# Open a new terminal session for ~/bin to get into $PATH
cd ~/vcs
git clone https://github.com/kerl/kerl.git
cd ~
ln -s ~/vcs/kerl/kerl ~/bin/kerl
kerl update releases
# Pick any version in the list -- I'm working on R27 right now
ERL_VER=27.3.4.12
kerl build $ERL_VER $ERL_VER
kerl install $ERL_VER ~/.erts/$ERL_VER
echo ". \"\$HOME\"/.erts/$ERL_VER/activate" >> .bashrc
echo ". \"\$HOME\"/.erts/$ERL_VER/activate" >> .bash_profile
. ~/.erts/$ERL_VER/activate
# You already have Erlang, this will get you ZX
wget -q https://zxq9.com/projects/zomp/get_zx && bash get_zx
The above scriptish version is the cut sheet for me to use later. I haven’t done a discussion explaining what is going on above in a while, and humans stopped reading (and writing) but AI sucks, so here we go, old school HOWTO blog style…
The difference between the non-graphical and graphical build of Erlang in this context is simple:
libwxgtk3.2-dev dependency.libwxgtk3.2-dev dependency.I’ll include it below for completeness, but that’s the only difference.
On Devuan the default is to use a root account rather than sudo. I tend to log in as root using su - instead of actually logging in as root, but that’s mostly because I do this mostly over SSH, and login as root should always be disabled in the SSH config. If you add yourself to the sudoers file, though, you can do it the sudo way you may be familiar with from Ubuntu.
Everything in this section will either have to be run as root or with sudo.
apt update
apt upgrade
apt install \
gcc curl g++ dpkg-dev build-essential automake autoconf \
libncurses-dev libssl-dev flex xsltproc libwxgtk3.2-dev \
wget vim git
First, we are going to be depending on the ~/bin directory being in our path for a bit of this, so create it if it doesn’t already exist. We’ll also use a directory ~/vcs to keep version controlled stuff in one place (so if you have sync scripts for your $HOME, omit both of those from it):
mkdir -p ~/vcs ~/bin
If ~/bin didn’t exist previously, close your terminal and open a new one — this should show up in your default $PATH now. If it doesn’t take because you have chosen a funky window manager, just log out and log back in to force it to take effect.
Once ~bin exists and is in our $PATH we’re going to jump through the following steps:
cd ~/vcs
git clone https://github.com/kerl/kerl.git
ln -s ~/vcs/kerl/kerl ~/bin/kerl
cd ~
kerl update releases
ERL_VER=27.3.4.12
kerl build $ERL_VER $ERL_VER
kerl install $ERL_VER ~/.erts/$ERL_VER
echo ". \"\$HOME\"/.erts/$ERL_VER/activate" >> .bashrc
echo ". \"\$HOME\"/.erts/$ERL_VER/activate" >> .bash_profile
. ~/.erts/$ERL_VER/activate
I installed 27.3.4.12 in the example above because I’m working on something that still uses it, but you can substitute any current version and it should just work. The current latest stable is 28.5.
At this point you have Erlang. Try running erl at your terminal and it should pop up:
ceverett@soba:~$ erl
Erlang/OTP 27 [erts-15.2.7.8] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit:ns]
Eshell V15.2.7.8 (press Ctrl+G to abort, type help(). for help)
1>
This is the easiest part:
wget -q https://zxq9.com/projects/zomp/get_zx && bash get_zx
You should see roughly this output:
ceverett@soba:~$ wget -q https://zxq9.com/projects/zomp/get_zx && bash get_zx
2026-06-08 17:37:47 URL:https://zxq9.com/projects/zomp/zx-0.14.0.tar.gz [151486/151486] -> "zx-0.14.0.tar.gz" [1]
Erlang found at /home/ceverett/.erts/27.3.4.12/bin/erl
/home/ceverett/bin was found in $PATH. Good to go.
zx found at /home/ceverett/bin/zx. Checking for upgrade.
Running `zx upgrade`...
Recompile: src/zx_zsp
Recompile: src/zx_userconf
Recompile: src/zx_tty
Recompile: src/zx_sup
Recompile: src/zx_proxy
Recompile: src/zx_peers
Recompile: src/zx_peer_sup
Recompile: src/zx_peer_man
Recompile: src/zx_peer
Recompile: src/zx_net
Recompile: src/zx_local
Recompile: src/zx_lib
Recompile: src/zx_key
Recompile: src/zx_daemon
Recompile: src/zx_conn_sup
Recompile: src/zx_conn
Recompile: src/zx_auth
Recompile: src/zx
Current version: otpr-zx-0.14.0
Running latest version.
Now try a zx command, like zx describe gajudesk:
ceverett@soba:~$ zx describe gajudesk
Package : otpr-gajudesk-0.9.0
Name : GajuDesk
Type : gui
Desc : A desktop client for the Gajumaru network of blockchain networks
Author : Craig Everett <craigeverett@qpq.swiss>
Web : https://gajumaru.io
Repo : https://git.qpq.swiss/QPQ-AG/GajuDesk
Tags : ["gaju","gm","gajumaru","wallet","blockchain","cryptocurrency",
"crypto","puck"]
Yay! And now you’re all set.
There are signed one-shot installers for Windows and MacOS that will bring in Erlang R27 and ZX with integrated shortcuts available at the ZX/Zomp downloads page.
If you came here to get GajuDesk, there are installers for GajuDesk and GajuDesk + GajuMine that integrate those apps with the desktop for Windows and MacOS (clicky icons and launchers and so on) available here: GajuMining Downloads
If you came here to run GajuMining on Linux, the above steps all still apply, but there are a handful of additional steps needed, such as adding the qpq and uwiger code realms. The community setup scripts are maintained at Shane Preater’s repo here: https://github.com/shanepreater/gajumaru
But if you already have zx installed by following the steps above, you can shortcut this with:
wget -q https://github.com/shanepreater/gajumaru/raw/refs/heads/main/qpq.zrf
wget -q https://github.com/shanepreater/gajumaru/raw/refs/heads/main/uwiger.zrf
zx import realm qpq.zrf
zx import realm uwiger.zrf
rm uwiger.zrf qpq.zrf
This is how things should go:
ceverett@soba:~$ wget -q https://github.com/shanepreater/gajumaru/raw/refs/heads/main/qpq.zrf
ceverett@soba:~$ wget -q https://github.com/shanepreater/gajumaru/raw/refs/heads/main/uwiger.zrf
ceverett@soba:~$ zx import realm qpq.zrf
SHA-512 of qpq.zrf: 59082251ED81C63DFC6C3678926DF503CB42118291B3271D3612BD1E7F63AEBDEB296D81AF7446451555B7085E726B6B9C1EC8DBBF3C4C6EDB296B9C257E3AD4
Imported record locally, including a public key.
Added realm qpq.
ceverett@soba:~$ zx import realm uwiger.zrf
SHA-512 of uwiger.zrf: 704530801DF3E54D069FACD93F772FCAC8A6E776389CDE8F4F034DE1A0A516B0D44FFB3DDD88C2A82C015CB14218C17172099E477E28B3A5E293D2CC08F20000
Imported record locally, including a public key.
Added realm uwiger.
ceverett@soba:~$ zx list realms
otpr
qpq
uwiger
ceverett@soba:~$ zx describe qpq-gajumine
Package : qpq-gajumine-0.4.2
Name : GajuMine
Type : gui
Desc : Mining client for the Gajumaru Root
Author : Craig Everett <craigeverett@qpq.swiss>
Web : https://gajumining.com
Repo : https://git.qpq.swiss/zxq9/GajuMine
Tags : ["qpq","gaju","gajumaru","hive","mining","crypto"]
And that’s it. You can do CPU mining with the GUI client by running zx run qpq-gajumine or headless with a GPU setup by following the advice on Shane’s repo.
From Elixir v1.20, every program is now gradually type checked in search for verified bugs and typing violations.
The YouTube channel BEAM There, Done That has new video about native records and more:
Inside the BEAM: Björn Gustavsson on Maps, Records, and Runtime Design.
Erlang/OTP 29 is a new major release with new features, improvements as well as a few incompatibilities. Some of the new features are highlighted below.
Many thanks to all contributors!
Added support for -unsafe attributes for marking
functions as unsafe to use. The compiler will by default now
generate warnings for calls to functions in Erlang/OTP known to be
always unsafe. Furthermore, xref can now be used to find calls to
unsafe functions and functions that lack documentation.
The SSH daemon now defaults to disabled for shell and exec services, implementing the “secure by default” principle. This prevents authenticated users from executing arbitrary Erlang code unless explicitly configured.
The SFTP subsystem is no longer enabled by default when starting an SSH daemon.
In SSL, the post quantum hybrid algorithm x25519mlkem768 is now the most preferred key exchange group in the default configuration.
The module io_ansi allows the user to emit Virtual Terminal
Sequences (also known as ANSI sequences) to the terminal in order to
add colors/styling to text or to create fully fledged terminal
applications.
The new ct_doctest module allows the user to test
documentation examples in Erlang module docs and documentation files.
The ignore_xref attribute has been handled as a post-analysis
filter by build tools such as Rebar3. In this release, [xref]
itself does the filtering, ensuring that all tooling that calls
xref for any purpose can rely on these declarations to just work.
In the default code path for the Erlang system, the current working
directory (.) is now in the last position instead of the first.
There is no longer a 32-bit Erlang/OTP build for Windows.
Native records as described in EEP-79 has been implemented. A native record is a data structure similar to the traditional tuple-based records, except that is a true data type. Native records are considered experimental in Erlang/OTP 29 and possibly also in Erlang/OTP 30.
The new is_integer/3 guard BIF makes it possible to easily verify
that a value is both an integer and within a certain range. For
example: is_integer(I, 0, 100)
Multi-valued comprehensions according to EEP 78
are now supported. For example, [-I, I || I <- [1, 2, 3]] will produce
[-1,1,-2,2,-3,3].
By enabling the compr_assign feature, it is now possible to bind variables
in a comprehensions. For example:
[H || E <- List, H = erlang:phash2(E), H rem 10 =:= 0]
In the documentation for the [compile] module, there is now a section
with recommendations for implementors of languages running on
the BEAM.
The JIT now generates better code for matching or creating binaries with multiple little-endian segments.
The compiler will generate more efficient code for map
comprehensions with constant values that don’t depend on the
generator. Example: #{K => 42 || K <- List}
There are several new compiler warnings enabled by default. For each such warning, there is an option to disable it.
There will now be a warning when using the catch operator, which
has been deprecated for a long time. It is recommended to instead
use try…catch but is also possible to disable the warning
by using the nowarn_deprecated_catch option.
There will now be a warning when exporting variables out of a
subexpression. For example: file:open(File, AllOpts = [write,
{encoding,utf8}]). This warning can be disabled using the
nowarn_export_var_subexpr compiler option.
The compiler will now warn for uses of the and and or
operators. This warning can be disabled using the
nowarn_obsolete_bool_op compiler option.
The compiler will now warn for matches such as {a,B} = {X,Y},
which is better written as {a=X,B=Y}. This warning can be disabled
using the nowarn_match_alias_pats option.
For a long time, there has been a warning for using the obsolete guard
tests (such as list(L) instead of is_list(L). In Erlang/OTP 30, the
old guards will be removed from the language.
rand:shuffle/1 and
rand:shuffle_s/2.For a full list and more details about new features and potential incompatibilities see the README.
This is a follow up to our batch of set-theoretic types optimizations, this time targeting differences.
This article explores the latest batch of optimizations we did to set-theoretic types and their representation.