RT.load does not correctly map namespace to source file or dll name

Description

When doing (from C#)

and having directory containing my\util.clj on CLOJURE_LOAD_PATH I get

I believe the latter is wrong - it should be looking for my\util.clj on load path?

Also, there is a problem with compiled assemblies whose namespace contains -'s. For example, if I have compiled namespace myns.foo-bar (in file myns\foo_bar.clj) it produces myns.foo_bar.clj.dll. If I try to load it like so:

I think RT.load should "know" that compiling a namespace with - character in it is mapped to _ on the corresponding dll or source file name.

Environment

None

Activity

Show:
David Miller
August 16, 2014, 8:35 PM

One should not be calling RT.load directly. Most functions in the RT namespace are not for C# code doing Clojure interop.

In the case of RT.load specifically, internally it is called only once, during system init, to load clojure/core.

Instead of direct calls, use the new interop capability to call from C# to Clojure functions.
The Clojure.var method is actually clojure.clr.api.Clojure.var

IFn load= Clojure.var("clojure.core", "+");
load.invoke("my.util");

See if this works for you.

import
August 21, 2014, 7:49 AM

Comment made by: akaranta

Ah, ok, I thought RT's methods were public API, I think I picked this usage up from an example somewhere and it seemed to work. And mostly does.

I'm currently using Clojure-CLR 1.5.0 and class clojure.clr.api.Clojure does not seem to exist. I take it is new in 1.6.0? What is the recommended way to load a namespace / var in 1.5.0?

David Miller
August 21, 2014, 4:46 PM

That class is indeed new in 1.6.0. In 1.50, you can do exactly what clojure.clr.api does:

private static Symbol asSym(object o)
{
String str = o as String;
Symbol s = str != null ? Symbol.intern(str) : (Symbol)o;
return s;
}

public static IFn var(object qualifiedName)
{
Symbol s = asSym(qualifiedName);
return var(s.Namespace, s.Name);
}
public static IFn var(object ns, object name)
{
return Var.intern(asSym(ns), asSym(name));
}
If you have two strings, one for namespace, one for name, this simplifies to

Var x = clojure.lang.Var.intern(ns,name);

import
August 22, 2014, 12:07 PM

Comment made by: akaranta

For some reason clojure.core/load does not seem to be able to find the given namespace (i.e. the corresponding .dll) whereas RT.load does find it.

Do I need to perform some extra dance steps to tell clojure.core/load where to look for the dlls? Preferably no environment variables like CLOJURE_LOAD_PATH involved. In practice they will be in the same directory as other dlls in my app (and I can easily programmatically find that out where that is if need be). Unfortunately it is neither the current dir nor the dir of the executing assembly.

BTW, automatically adding the location of Clojure.dll to the load path would likely solve at least my issue with clojure.core/load and I would guess it to be generally useful, too.

Assignee

David Miller

Reporter

import

Labels

None

Approval

None

Patch

None

Priority

Major
Configure