Spade 0.14.0

Posted 2025-06-26 by The Spade Developers

After a brief hiatus while Frans finished his PhD thesis, we are finally releasing Spade 0.14.0. This includes long awaited support for lambda functions, standard library features to go along with that, and, a much more usable LSP implementation that will no longer bail on the first error.

Lambda functions🔗

Lambda functions are "anonymous" functions that are written in-line where they are used. Their primary use case is to specify transformation on data contained in "containers" like arrays and the Option type.

For example, to add one to the value inside an Option type, you could write

match value {
  Some(inner) => Some(inner + 1),
  None => None
}

With lambda functions, you can now use the map function instead

value.map(fn (inner) {inner + 1})

which is much more concise, and chainable. In addition, the map function can be implemented on many types including arrays and the ready valid Rv type, allowing you to change the container without affecting the computation being performed.

The definition of the map function on Option looks like this

impl<T> Option<T> {
  fn map<F, O>(self, f: F)
  where F: Fn((T), O)
  {
    match value {
      Some(inner) => Some(f.call((inner,))),
      None => None
    }
  }
}

I.e. lambda functions are just values which implement the Fn trait which has a .call method.

Standard library additions🔗

With lambda functions implemented, the standard library has gained a few new "combinator" functions that make use of this new functionality

  • Option and [T; N] now have a map function
  • Option now has an and_then function
  • [T; N] now has zip for joining two arrays pair-wise and concat for concatenating them together.
  • Option now has unwrap_or, unwrap_or_undef for getting the inner value out of the option without a match block
  • Option now has sliding_window for keeping around the last N values.
  • The new std::undef::undef function allows you to create an undefined value (currently X in the Verilog backend)

Language Server Protocol and Error Recovery🔗

The Spade language server has supported inline errors, go to definition and hover for quite a while, but the compiler has been to eager to error out on the first sign of trouble making the LSP relatively useless. With 0.14.0, this is now much improved allowing the LSP to keep up.

In addition, the hover information has been improved. You can now see the types of variables and expressions when hovering over them, function signatures and documentation are shown for both functions and methods, and the inferred output type of methods is also shown on hover

These mastodon posts have a few examples of this functionality:

  • https://mastodon.social/@thezoq2/114649713513195455
  • https://mastodon.social/@thezoq2/114647080504928422
  • https://mastodon.social/@thezoq2/114647085989178649

Surfer WebAssembly plugin🔗

The integration with Surfer has long been in the source tree of surfer, requiring you to match your Surfer version with your Spade version. On the latest surfer version, it can now load web assembly plugins, so the Spade integration has been moved out into that system.

For now, this requires manual installation, by running install.bash in the spade-surfer-plugin directory, but automated install will be added to swim soon.

Surfer name translation🔗

The Spade compiler produces anonymous names _e_... for any intermediate signals it creates. As more and more functionality in Spade is written using more complex expressions like methods, this becomes hard to debug. With this update, Surfer can translate these names back to their source code location, allowing you to view signals not only for your named variables, but also intermediate expressions.

Functions can now contain wires🔗

Previously, the language did not allow & or inv & in functions. This ended up being too restrictive as it is entirely possible to write combinatorial functions using them. This restriction is now lifted.