Fork me on GitHub

hi all, how do I look up a functions spec at run-time? s/get-spec doesn’t seem to to work?

Alex Miller (Clojure team)14:01:16

it should if you pass it a fully-qualified symbol


ah thankyou. just spotted it said that in the docs… an I get the fully qualified symbol for a function from that function?

Alex Miller (Clojure team)14:01:27

you don’t need to get it from anywhere?

Alex Miller (Clojure team)14:01:31

user=> (defn foo [] nil)
user=> (s/fdef foo :args (s/cat) :ret nil?)
user=> (s/get-spec `foo)
#object[clojure.spec.alpha$fspec_impl$reify__2451 0x8c11eee "[email protected]"]
user=> (s/form (:args (s/get-spec `foo)))

Alex Miller (Clojure team)14:01:26

I used back-tick there - syntax quote will resolve symbols so that’s an easy way, but I also could have done (s/get-spec 'user/foo)

Alex Miller (Clojure team)14:01:55

note that what you get back is a function spec instance, but that spec supports keyword lookup of :args, :ret, and :fn

Alex Miller (Clojure team)14:01:22

or you can use s/form on it directly

user=> (s/form (s/get-spec 'user/foo))
(clojure.spec.alpha/fspec :args (clojure.spec.alpha/cat) :ret clojure.core/nil? :fn nil)


ah I see now. wonderful thank you Alex!


Rich mentioned in a podcast (I think) that there was some sugar forthcoming which allowed a map to specify/lift the namespace for all the keys in the map (if they all had the same namespace) to the map level such that each individual key in the map could be printed / declared as un namespaced for cleanliness? Is there news on this, or a preview of what it might look like? I'm working on something similar and an example would be great to see. This was mentioned in the context of using spec, so that's why I'm putting it here vs. another channel.


It's syntax sugar -- already in 1.9


#:foo{:bar 1} = {:foo/bar 1}


user=> *print-namespace-maps*
user=> {:foo/bar 42}
#:foo{:bar 42}


same example even


the universal example


So this foo walks into a bar. Bartender says, "Hey buddy, what kind of example you trying to set?"


Ah, missed it.. thanks @ghadi and @bronsa


ok, so if I have a function `f’ thats been passed in to another function and I don’t know it’s fully qualified name is there a way to find it?


if by function you mean var then yes


ah I do mean var I think - how do I look up a fully qualified name/spec for a function referenced by a variable?


oh hang on `var?' just gave me a false...


maybe if you give a code example of what you’re trying to do it might be clearer


I’m trying to look up if a particular function has had a spec written for it.


i.e does a function have a spec specified for it.


if you have a fully-qualified symbol, you can do this


(get (s/registry) 'my.ns/function)


if you have a function, you cannot


I won’t have the fully qualified symbol when I come to do it - does this mean it’s a no go?


"So what are you actually trying to do?"


ah ok - this is a shame - The REPL seems to be able to look up the fully-qualified symbol for function


@gihadi - it is a bit convoluted - I’m experimenting with agent based computing - and turning functions in to agents using only the information in there type signatures


(well there spec’d signatures)


can you turn on instrumentation prior a priori?


not what I want unfortuantely - I’m doing some crazy stuff with the spec - I unpack info about each argument and tehn search a collection for it.


the only thing I can’t do is look up wether or a not a function has had a spec written for it (when I don’t have its fully wualified name)

Alex Miller (Clojure team)17:01:05

If you don’t have the qualifier, then it’s ambiguous what you’re referring to

Alex Miller (Clojure team)17:01:42

A function of the same name could be spec ed in many nses

Alex Miller (Clojure team)17:01:16

That said, the registry is just a map with either qualified symbols or qualified keywords as keys - you could search for it


ok - thanks Alex. So is there a way to look up a functions source namespace/name?


just the function…


the REPL seems to know hwere it came from

Alex Miller (Clojure team)17:01:26

A function instance doesn’t hold an explicit name for its source var


bb-simple.core> (defn function [a] a)
bb-simple.core> (def z function)
bb-simple.core> z


so I can store a function in z - the REPL tells me where I defined it


when all I have is z is there a way to find that it refers to bb-simple.core/function?


not reliably

Alex Miller (Clojure team)17:01:01

that’s not the default printer - you must be running with something addition in your repl


ah - it’s the CIDER repl in emacs

Alex Miller (Clojure team)17:01:41

the function class name is a munged version of the original function name (assuming it was from a var, can be from other places too)


what that’s doing is using demunge to get from the class name to an approximation of the original var


but that is not relibale and can only be done if the function was compiled from a defn

Alex Miller (Clojure team)17:01:22

you can demunge to recover the class name, but the munge operation is not a true function (mathematically) in that multiple inputs map to the same class name

Alex Miller (Clojure team)17:01:34

that’s where the unreliability comes from


oh ok this all sounds a bit yuck. Think I’ll steer clear for now. It’s a lot of extra typing for me but such islife

Alex Miller (Clojure team)17:01:25

(Compiler/demunge (.getName (class z)))