clr

dangercoder 2025-09-04T17:16:46.274599Z

I think there's a difference in how the JVM loads classes (dependencies always being available on the classpath) and the CLR. C#'s Type.GetType(): Automatically triggers assembly loading for shared framework assemblies: https://github.com/dotnet/runtime/blob/main/src/coreclr/System.Private.CoreLib/src/System/Reflection/TypeNameResolver.CoreCLR.cs#L190-L207 The flow is:

1. C# Type.GetType() →
  2. TypeNameResolver.GetType() →
  3. ResolveAssembly() →
  4. RuntimeAssembly.InternalLoad() ← This loads from shared frameworks e.g. .NET.Sdk.Web
Clojure's RT.classForName(): Does NOT trigger assembly loading - only searches already-loaded assemblies which makes it hard/unidiomatic to consume/depend on any .NET goodies.
<Project Sdk="Microsoft.NET.Sdk.Web">

dangercoder 2025-09-04T17:20:36.216089Z

The only workaround I found is manually calling Assembly.Load() before using Clojure, but: - You need to know which assemblies to preload - Goes against .NET's design - Not discoverable - users hit "Type not found" errors

dangercoder 2025-09-04T17:20:50.358099Z

Also changing Clojure.RT is not backwards compatible I guess(?)

dangercoder 2025-09-04T17:21:51.698299Z

But if we had it, we could add <Project Sdk=".Sdk.Web"> and start using http://ASP.NET Core idiomatically like you can in C# or F#

dmiller 2025-09-04T19:03:26.895599Z

I'm open to suggestions on how to fix this. Yes, at the moment, manually calling Assembly.Load() before you hit the type of interest in Clojure code is the only way to proceed. I don't know that changing Clojure.RT is out of the question. Worst case: have a flag. Or have a way to specify the assembly resolver to use that can be set during clojure init. Looking at System.Reflection.TypeNameResolver.GetType (I wish I had had access to MS source code 15 years ago. Sigh.) One could write a dissertation on this thing. Let's consider the kind of situation we run into in ClojureCLR: RT.classForName("A.B.T"). We know nothing about the assembly. Where do we look? At the moment, it looks in loaded assemblies. If we are trying to auto-load assemblies, where do we look? What set of directories do we look in? Presumably you would like the .NET system load path? Do we know what defines that? We could certainly cobble up some way for the user to specify other paths to search. Now as we are trying to find "A.B.T", we will have to look at the internals of every assembly accessible on specified directories. This is not quite as simple as seeing if a Jar has a file named "A.B.T". It requires a full metadata analysis. We do not have to fully load the assembly. There is a provision for a MetadataLoadContext that loads assemblies for metadata inspection only. (https://learn.microsoft.com/en-us/dotnet/standard/assembly/inspect-contents-using-metadataloadcontext) So I'm thinking auto-loading of an assembly on demand is possible here. The biggest problems: What is the default for the search directories? How does the user specify additional directories? I'd love to solve this problem.

dangercoder 2025-09-05T07:17:17.793019Z

This looks interesting: Microsoft.Extensions.DependencyModel.DependencyContext.Default; https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencymodel.dependencycontext?view=net-9.0-pp

isak 2025-09-04T17:32:24.999099Z

Here is how ClojureDart does generics (not that it is necessarily better). You might find this interesting @dmiller: https://github.com/Tensegritics/ClojureDart/blob/main/doc/ClojureDart%20Cheatsheet.pdf

1
👏🏽 1
dmiller 2025-09-09T20:26:56.706029Z

Thanks for the reference.