Help with #'

205 views
Skip to first unread message

David Simmons

unread,
Apr 22, 2012, 4:01:54 PM4/22/12
to Clojure
Hi

I'm new to Clojure but very keen to learn. I'm following Web
Development with Clojure (http://www.vijaykiran.com/2012/01/11/web-
application-development-with-clojure-part-1/) and came across the
following code:

(run-jetty #'routes {:port (or port 8080) :join? false}))

I know that #'routes is the same as (var routes) and that it is
passing the "object" rather than the actual value BUT I don't
understand why this is used. Specifically if I replace #'route with
route the code works fine. I've read somewhere this is something to do
with autoloading changes to code when developing for the web. Does
anyone have a simple explanaition for #' and why it is used here. If
you have some simple clojure code to illustrate its use I'd be really
grateful.

many thanks in advance for any help.

Dave

Stuart Campbell

unread,
Apr 22, 2012, 9:48:02 PM4/22/12
to clo...@googlegroups.com
Hi Dave,

If you write

  (run-jetty routes ...)

then the current value of "routes" is looked-up and passed to run-jetty. You won't see any change if you subsequently redefine "routes", because the original definition is what was passed to run-jetty.

On the other hand,

  (run-jetty #'routes ...)

passes a var (see http://clojure.org/vars) to run-jetty. Now whenever run-jetty invokes your handler function, the currently-bound value of "routes" is invoked.

Here's a simplified example:

  user> (defn foo [] "hello")
  #'user/foo
  user> (def a foo)
  #'user/a
  user> (def b #'foo)
  #'user/b
  user> (defn foo [] "goodbye")
  #'user/foo
  user> (a)
  "hello"
  user> (b)
  "goodbye"

Cheers,
Stuart


--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

David Simmons

unread,
Apr 23, 2012, 8:11:42 AM4/23/12
to Clojure
Hi Stuart

fantastic - it is starting to make sense now. One follow on question.

Presumably this only applies to functions? If I replace (defn foo []
"hello") with (def foo "hello") I don't get the same results. Is this
because functions are handled differently?

many thanks (again)

Dave

On Apr 23, 2:48 am, Stuart Campbell <stu...@harto.org> wrote:
> Hi Dave,
>
> If you write
>
>   (run-jetty routes ...)
>
> then the current value of "routes" is looked-up and passed to run-jetty.
> You won't see any change if you subsequently redefine "routes", because the
> original definition is what was passed to run-jetty.
>
> On the other hand,
>
>   (run-jetty #'routes ...)
>
> passes a var (seehttp://clojure.org/vars) to run-jetty. Now whenever
> run-jetty invokes your handler function, the currently-bound value of
> "routes" is invoked.
>
> Here's a simplified example:
>
>   user> (defn foo [] "hello")
>   #'user/foo
>   user> (def a foo)
>   #'user/a
>   user> (def b #'foo)
>   #'user/b
>   user> (defn foo [] "goodbye")
>   #'user/foo
>   user> (a)
>   "hello"
>   user> (b)
>   "goodbye"
>
> Cheers,
> Stuart
>
> >http://groups.google.com/group/clojure?hl=en- Hide quoted text -
>
> - Show quoted text -

Tassilo Horn

unread,
Apr 23, 2012, 8:36:30 AM4/23/12
to clo...@googlegroups.com
David Simmons <shortl...@gmail.com> writes:

Hi David,

> Presumably this only applies to functions?

No, not really.

> If I replace (defn foo [] "hello") with (def foo "hello") I don't get
> the same results. Is this because functions are handled differently?

--8<---------------cut here---------------start------------->8---
user> (def foo "hello")
#'user/foo
user> (def a foo) ;; a has the current value of foo
#'user/a
user> (def b #'foo) ;; b's value is the Var foo
#'user/b
user> (def foo "goodbye")
#'user/foo
user> a
"hello"
user> b
#'user/foo
user> @b
"goodbye"
--8<---------------cut here---------------end--------------->8---

Please note that you have to dereference b explicitly to get the value
currently bound to foo. That's because b's value is again a Var. It
seems that Clojure dereferences Var's automatically, possibly multiple
times, in case of function calls. So in Stuard's example, both (b) and
(@b) call the function currently bound to foo.

Bye,
Tassilo

David Simmons

unread,
Apr 23, 2012, 11:28:31 AM4/23/12
to Clojure
Hi Tassilo

Perfect answer - the fog is definately beginning to lift!

Do you know why Clojure automatically dereferences functions but not
for other bound values?

cheers

Dave

On Apr 23, 1:36 pm, Tassilo Horn <tass...@member.fsf.org> wrote:

Meikel Brandmeyer (kotarak)

unread,
Apr 23, 2012, 11:37:46 AM4/23/12
to clo...@googlegroups.com
Hi,

it does not automatically deref the Var. Instead the Var delegates being called like a function to the value it's holding. If Clojure was automatically to dereffing a Var upon access, you wouldn't be able to use it as a value, because you'd always get its contents.

Kind regards
Meikel

Cedric Greevey

unread,
Apr 23, 2012, 11:41:57 AM4/23/12
to clo...@googlegroups.com
On Mon, Apr 23, 2012 at 8:36 AM, Tassilo Horn <tas...@member.fsf.org> wrote:
> It seems that Clojure dereferences Var's automatically, possibly multiple
> times, in case of function calls.

Multiple times confirmed:

user=> (defn foo [] "Boo!")
#'user/foo
user=> (type foo)
user$foo
user=> (def bar #'foo)
#'user/bar
user=> (type bar)
clojure.lang.Var
user=> (def baz #'bar)
#'user/baz
user=> (type baz)
clojure.lang.Var
user=> (type @baz)
clojure.lang.Var
user=> (baz)
"Boo!"

shortl...@gmail.com

unread,
Apr 23, 2012, 2:32:50 PM4/23/12
to clo...@googlegroups.com


Sent from my HTC

Cedric Greevey

unread,
Apr 23, 2012, 2:36:13 PM4/23/12
to clo...@googlegroups.com
On Mon, Apr 23, 2012 at 2:32 PM, shortl...@googlemail.com
<shortl...@gmail.com> wrote:

[in reply to my confirmation that vars referencing vars referencing
functions are still callable as functions]

> Sent from my HTC

Beg pardon?

David Simmons

unread,
Apr 23, 2012, 3:02:38 PM4/23/12
to Clojure
Cedric - apologies - fat fingers on my mobile phone!!

To both Cedric and Meikel - thank you both for your help.

I'm finding Clojure a great language to learn (if a little difficult
at first). It seems a much more consistent language than the others I
have studied which I think is fantastic.

Dave

On Apr 23, 7:36 pm, Cedric Greevey <cgree...@gmail.com> wrote:
> On Mon, Apr 23, 2012 at 2:32 PM, shortlypor...@googlemail.com

Cedric Greevey

unread,
Apr 23, 2012, 3:06:40 PM4/23/12
to clo...@googlegroups.com
On Mon, Apr 23, 2012 at 3:02 PM, David Simmons <shortl...@gmail.com> wrote:
> Cedric - apologies - fat fingers on my mobile phone!!

More likely, tiny keys. (Though how that generated a meaningful
English sentence that just happened to be completely off topic, I
don't know!)

> To both Cedric and Meikel - thank you both for your help.
>
> I'm finding Clojure a great language to learn (if a little difficult
> at first). It seems a much more consistent language than the others I
> have studied which I think is fantastic.

It's probably the homoiconicity at work. No hairy, ad hoc syntax rules
and few reader macros.

Reply all
Reply to author
Forward
0 new messages