March 2022 Monthly Update

By Alyssa Parado

Biff

At the start of the project, I had mostly finished updating Biff’s library code. Since then, I’ve finished updating the template project. As a refresher, some of the changes from the previous version of Biff include:

So the code is pretty much complete. There’s just a handful of cleanup things that I’ll do right before the release. (I also still need to test everything on Mac, especially develop-in-prod). Besides that:

Once the main documentation page is complete, I’ll write a bunch of doc strings and update the API docs page. Then it’ll be time to release.

Orchard

I’ve invested a day to look into my preferred method of solving this: inspecting the produced JS objects inside the running VM, in a similar manner to the JVM implementation.

It turns out even the only kind of viable way to do that is Function.caller which has multiple problems:

  1. It’s deprecated
  2. We’d have to rewrite every generated JS function to add this
  3. We would have to execute every function
  4. Worst: There is no general way to even run every code path

Further investigation

The next possibility I will check is a hybrid version, which is less useful but still a lot better than nothing: Using the cljs compiler to provide the references while compiling the code.

This is not ideal since it doesn’t allow investigating code that is already running and will probably not allow investigating hierarchies inside JS code. It should be good enough for most consumers of orchard though since it’s mostly used during development.

Typed Clojure

The goal of this project funded by Clojurists Together is to (resurrect) support for type checking ClojureScript files in Typed Clojure.

Roughly 10,000 lines of refactoring, improvements, and feature work has culminated to a working minimal project that can check a .cljc file in both Clojure and ClojureScript.

The work I completed for the previous Clojurists Together funding for Typed Clojure has been transferred to ClojureScript, as my proposal speculated. The minimal project shows off how a type error involving (clojure.core/inc a) is presented as if inc were a regular function–in Clojure it is inlinable yet Typed Clojure prints (inc a) instead of clojure.lang.Numbers/inc, and in ClojureScript is it a macro call yet prints ((do inc) a) instead of a js* call (some room for improvement).

A new macros namespace typed.clojure has been created for cross-platform use. Instead of using clojure.core.typed or cljs.core.typed, you can use typed.clojure and the correct implementation will be chosen automatically. A new namespace was created so then we can (eventually) target self-hosting ClojureScript forcing reader conditionals on users.

The base type environment for both Clojure and ClojureScript has been moved to typed.ann.clojure. It houses 2400 lines of annotations and serves as a real-world example of how to annotate functions, protocols, and records for multiple platforms using reader conditionals.

Typing rules for macros are now shared across Clojure and ClojureScript implementations. This means the work completed for the previous Clojurists Together project can be transferred to ClojureScript, such as the improved error messages for let-destructuring.

Reveal

The test runner is done! New versions of Reveal (Free 1.3.270 and Pro 1.3.339) provide:

Here is what it looks like:

During the remaining month, I plan to revamp the Reveal site to make it more structured and approachable, and in turn, make Reveal easier to set up, understand, and use.

Deep Diamond

My goal with this round is to implement Recurrent Neural Networks (RNN) support in Deep Diamond. The first month was dedicated to literature review (and other hammock-located work), exploration of OneDNN implementation of RNN layers, and implementation of RNN prototype in Clojure in Deep Diamond.

Deep Diamond currently supports general tensor operations, fully connected NN layers, and convolutional (CNN) layers, on CPU and GPU. Based on this, relatively stable, infrastructure, I started adding Vanilla RNN implementation backed by OneDNN (Intel, CPU).

OneDNN RNN implementation is, like all the low-level backends that leading DL frameworks use, very heavy, convoluted, and rather unclojure-y. So it takes some time to discover how it should be properly used, and how to best hide its complexity under a nice high level Clojure.

Specifically, this was implemented in the first month of Q1:

So far, I’m pretty satisfied with the progress, as I think I have discovered the roughest edges of Intel’s implementation, and found ways to fit this into existing Deep Diamond code. I expect the following 2 months of the project to require lots of work and tests, but I feel I shouldn’t expect nasty surprises. I believe that by the end of the funding period I’ll be able to release the version of Deep Diamond that will have the functionality I’ve proposed.

Firefox

Custom Formatters for Firefox

Hello everyone, I am Sebastian! I am currently working on bringing Custom Formatters to Firefox, and by that allow tools like cljs-devtools to work with Firefox.

What are Custom Formatters?

Custom Formatters allow to display specific objects within the DevTools using formats and styles provided by the website. Those Custom Formatters are used in different places throughout the DevTools - everywhere were the objects are displayed. Mainly this is done in the Web Console and the Debugger.

Daniel also provided a short introduction to the feature with links to more information in his article about the funding of this feature.

Current status

In bug 1746830 I introduced a preference devtools.custom-formatters behind which this feature is implemented. This preference can be enabled via about:config.

I’ve also added an option called Enable custom formatters to the Settings panel in bug 1746831. This option controls the preference devtools.custom-formatters.enabled.

Currently, I am working on implementing the formatting itself in bug 1746824. This includes interpreting JsonML and using it to style the object.

A work-in-progress patch of this can be seen at https://phabricator.services.mozilla.com/D140119.

If you want to follow the progress, please have a look at the meta-issue.

What’s next?

I’ll finalize the patch mentioned above. This lays the foundation to display the Custom Formatters. Though by itself this change won’t have a visual difference. It requires the Custom Formatters defined within the page to be interpreted. This is covered in bug 1734840, which will be the next thing I am working on.

Clojure-LSP

We had huge performance improvements and a new long waited feature requested, Java interop!

Release 2022.03.25-12.02.59

This release fixed an annoying performance issue we had with our custom linter for unused public vars, on one of the big projects we tested where before use to take 30s to analyze async the whole project for only that linter, it takes 0.2s now! A new feature was included, the ability to find definition of defmultis, finding all defmethods! We now have more built-in completion snippets on clojure-lsp following @practicalli-john suggestions. Regarding the API/CLI usage, we fixed a issue where could cause some false-positives regarding clean-ns and format and we started working on a big refactor, creating a new submodule that may be extracted out of clojure-lsp in the future, called lsp4clj, with that we could implement other LSP servers (for probably other languages) in clojure easier!

Here is the changelog of this release:

Release 2022.03.31-14.21.14

This was a release with fewer new features/improvements but things we were researching/working for a long time, with this release and the help from clj-kondo, we now have support for Java interop. This is a long-waited feature that now makes clojure-lsp be able to find definition of java classes, and even decompile the .class if no java source is found. We also automatically try to find the JDK source or download it if the setting is enabled. This is a huge step for clojure-lsp, making it a better IDE tool and helping the development of clojure projects that use java interop, make sure to check docs Besides that, we had another performance improvement regarding big projects/files, removing CPU spikes for those cases.

Here is the changelog of this release:

Bozhidar Batsov

In the past couple of months my main focus were:

In CIDER we’ve been working towards replacing some fragile logic for dealing with package sources and Javadoc with the external enrich-classpath tool. While this already works reasonably well in most scenarios, there’s still some edge cases that need to be addressed (mostly probably in CIDER 1.4).

Another big change is some untangling of the dependency-injection code in CIDER, which was a total mess before CIDER 1.3.

My availability was impacted heavily by the war in Ukraine, that’s why this update is coming a bit late.

Dependabot Core