I can’t find any, and it’s not surprising because Julia’s composability isn’t spectacular. Different packages working together through APIs is not a novel concept, and the easing by a language’s particular features is readily apparent.
Python alone is also very composable via duck-typing. The obstacles in such glue languages comes with the 2-language problem:
- if 2 core packages implement their own versions of a data structure, especially in 2 different languages, then their dependents can easily be separated into 2 incompatible groups. That’s not necessarily the case because people can agree on a Python-level API for Python code to work with either package; the Julia ecosystem has this pattern in abstract interfaces.
- The composability is entirely in the glue language, and you can’t compile the underlying code in separate packages together at runtime, especially if they’re in separate languages. You can build another package that mixes them how you need, rewrap it in Python, and import that, but it’s obvious that working in one compiled language is smoother, especially JIT-compiled ones in interactive shells.
Since you can accomplish composability in different languages with their own perks and drawbacks, there’s not much incentive to academically nitpick. Julia didn’t invent something unlike any other language, it just collected and eased many convenient features for interactive workflows. For example, you can do limited argument dispatch in Python in various contexts if someone tries hard enough; NumPy uses NEP 18 to allow its API to use non-NumPy arrays, some of Python’s infix operators implement double dispatch in underlying dunder methods. Other reasons for language choice can easily outweigh how composability works.