views:

74

answers:

4

can i somehow find all functions/macros that take a specific type of parameter ?

for example, what function accepts a Namespace object as parameter ?

(this is because i can create a namespace and store it in a var, but i don't know where i could use that var; what function might i pass that var to ?)

here is some code:

user=> (def working-namespace (create-ns 'my-namespace))
#'user/working-namespace
;i created a namspace and want to use it later

user=> (class working-namespace)
clojure.lang.Namespace
; out of curiosity i found out that "working-namespace" is a Namespace object

user=> (ns working-namespace)
nil
working-namespace=>
; but how do i switch to it ? this didn't do what i wanted...

user=> (refer working-namespace)
java.lang.ClassCastException: clojure.lang.Namespace cannot be cast to clojure.lang.Symbol (NO_SOURCE_FILE:0)
; this did not work either as my expectations

user=> (the-ns working-namespace)
#<Namespace my-namespace>
user=> (class (the-ns working-namespace))
clojure.lang.Namespace
; great, this gave me the same thing, a Namespace

hence the question: how do i use it dynamically (that's why i had put my namespace into a var) ? how do i get something useful for me from a var that points to a namespace ?

i can try look around for functions that make use of a Namespace object or that convert it to something else. i did and only found "intern". searching by hand not seems not that promising

what if i have this problem a million time ? is there an automated way to get me what i'm looking for without having to ask around each time ?

A: 

I don't think you can do that without a lot of hackery in a dynamic language. If you want to now what function that take namespaces look at the documentation of the namespace stuff.

For example cleaning namespaces or reload them.

nickik
that is quite difficult, time consuming and not so rewarding. i already did that for the Namespace class, and did not have much success.
Belun
+3  A: 

In Clojure 1.2 and previous function arguments dont have types. every function argument is an object. So the question really becomes "how do i find functions that will cast the object I pass them into this type. so searching for type hints will find some of them, though it wont get you everything. I wish it where more possible to answer this in general.

starting with 1.3 (current dev branch 9/2010) function paramerters and return types can have a defined type and will be passed/returned as that type instead of being cast to object and then cast on the other side. This drops one of the zeros from the exacution time of numerical functions with the important limitation that it only works for :static functions and only with direct calls (ie: not through map/reduce/filter/etc.) There is not a lot published on this change yet though it has the important breaking change that integers are no longer boxed by default and integer (actually Long) overflow throws an exception. you can read more here

(defn ^:static fib ^long [^long n]
  (if (<= n 1)
    1
    (+ (fib (dec n)) (fib (- n 2)))))

so after 1.3 is released and widely adopted you will see code with more commonly defined types because they will offer a big speed benefit and then you will be able to find more functions by argument type though still not all of them.

At the same lecture where I learned about function argument types, Rich mentioned plans in the distant Clojure future (after 'Clojure in Clojure') about better support for exposing the compiler internals to tools such as IDEs. So there is hope that someday you will get a real answer to this question. Dynamic languages make this slightly more difficult in practice and a lot harder in theory.

Arthur Ulfeldt
I'm looking for written sources describing the addition of function arguments. This post is based on a talk Rich Hickey gave at the Bay Area Clojure Meetup on 9/20/2010
Arthur Ulfeldt
wow, that seems far away
Belun
A: 

You wrote:

user=> (ns working-namespace)
nil
working-namespace=>
; but how do i switch to it ? this didn't do what i wanted...

But you did switch to the working-namespace namespace (that's why the prompt changed), so I'm not clear as to what "you wanted".

As I noted earlier, you need to present the ultimate problem are you trying to solve. It's entirely likely that messing with namespace objects won't be the solution.

Alex Taggart
i wanted to change to "my-namespace"
Belun
Easy: `(ns my-namespace)`
Alex Taggart
+2  A: 

You already got a good answer from Arthur, so I'll only answer the "how do i get something useful for me from a var that points to a namespace ?". From (doc ns), note that it says unevaluated:

user=> (doc ns)
-------------------------
clojure.core/ns
([name docstring? attr-map? references*])
Macro
  Sets *ns* to the namespace named by name (unevaluated), creating it

Now there's something you could do with in-ns if you want (the whole namespace object -> string -> symbol conversion is probably stupid, but enough to illustrate my point):

user=> (in-ns (symbol (str working-namespace)))
#<Namespace my-namespace>
my-namespace=>
Michael Kohl
very nice. thanks
Belun