newbie question about ns and :require

5 views
Skip to first unread message

Manfred Lotz

unread,
Jan 24, 2010, 10:28:16 AM1/24/10
to clo...@googlegroups.com
Hi all,
I'm stumbling about the very basics.

Calling clojure like this:

rlwrap java
-cp /home/manfred/clojure/clojure.jar:/home/manfred/clojure/clojure-contrib.jar
clojure.main


I try:

user=> (ns my (:require clojure.contrib.classpath))
nil
my=>

which to me looks fine.

But why does this fail?

my=> (classpath)
java.lang.Exception: Unable to resolve symbol: classpath in this
context (NO_SOURCE_FILE:2)

--
Hope it is not too much stupidity on my side,
Manfred

Gabi

unread,
Jan 24, 2010, 11:06:02 AM1/24/10
to Clojure
Maybe try
(ns my (:require [clojure.contrib.classpath :as cp]))
(cp.classpath)

Gabi

unread,
Jan 24, 2010, 11:36:02 AM1/24/10
to Clojure
Sorry, I meant (cp/classpath) ..

David Nolen

unread,
Jan 24, 2010, 1:12:55 PM1/24/10
to clo...@googlegroups.com
On Sun, Jan 24, 2010 at 10:28 AM, Manfred Lotz <manfre...@arcor.de> wrote:
user=> (ns my (:require clojure.contrib.classpath))
nil
my=>

which to me looks fine.

But why does this fail?

my=> (classpath)
java.lang.Exception: Unable to resolve symbol: classpath in this
context (NO_SOURCE_FILE:2)

require just brings the library in. If you want the symbols to be available without having to qualify them, use :use

(ns my (:use clojure.contrib.classpath))

.Bill Smith

unread,
Jan 24, 2010, 3:33:11 PM1/24/10
to Clojure
Manfred,

The (:require clojure.contrib.classpath) tuple tells the ns function
to load the clojure.contrib.classpath library if it has not already
been loaded. Clojure looks for clojure/contrib/classpath.clj (or the
equivalent class file) somewhere in your classpath, which in your
case would be inside /home/manfred/clojure/clojure-contrib.jar. The
library is loaded into the clojure.contrib.classpath namespace, so if
you want to reference something in the library, you need to precede
the symbol with the namespace name, e.g. (clojure.contrib.classpath/
WHATEVER). So that's one problem.

Here is the second problem. Coincidently, the function you want to
invoke is also called classpath, so to invoke it you need to do this:
(clojure.contrib.classpath/classpath). To call the classpath-
directories function in the classpath library, you do this:
(clojure.contrib.classpath/classpath-directories).

If you don't want to prefix every reference to classpath with
clojure.contrib.classpath, you can replace ":require" with ":use" in
your call to ns, like this: (ns my (:use clojure.contrib.classpath)).
The ":use" directive says "load the specified library if it hasn't
already been loaded, and then add its contents to my namespace". If
you use :use, you can call classpath like this: (classpath).

I apologize if that seemed overly verbose, but I hope it gets the
point across.

Bill Smith
Austin, TX

Justin Kramer

unread,
Jan 24, 2010, 3:28:16 PM1/24/10
to Clojure
You may find this ns cheatsheet helpful:

http://gist.github.com/284277

Justin

Meikel Brandmeyer

unread,
Jan 24, 2010, 11:07:23 AM1/24/10
to clo...@googlegroups.com
Hi,

Am 24.01.2010 um 16:28 schrieb Manfred Lotz:

> user=> (ns my (:require clojure.contrib.classpath))
> nil
> my=>
>
> which to me looks fine.

No news is good news.

> But why does this fail?
>
> my=> (classpath)
> java.lang.Exception: Unable to resolve symbol: classpath in this
> context (NO_SOURCE_FILE:2)

Because you used require. Try clojure.contrib.classpath/classpath instead.

You have the following possibilities to shorten that:

(ns my
(:require [clojure.contrib.classpath :as cp]))

… (cp/classpath) …

or (with :only listing everything you want to import)

(ns my
(:use [clojure.contrib.classpath :only (classpath)]))

… (classpath) …

Both of these are considered clean style. You can also include everything of a namespace with a pure :use (w/o :only) but be aware that that might do more than you want.

Sincerely
Meikel

Manfred Lotz

unread,
Jan 25, 2010, 11:08:01 AM1/25/10
to clo...@googlegroups.com
Hi,

On Sun, 24 Jan 2010 17:07:23 +0100
Meikel Brandmeyer <m...@kotka.de> wrote:


>
> > But why does this fail?
> >
> > my=> (classpath)
> > java.lang.Exception: Unable to resolve symbol: classpath in this
> > context (NO_SOURCE_FILE:2)
>
> Because you used require. Try clojure.contrib.classpath/classpath
> instead.
>
> You have the following possibilities to shorten that:
>
> (ns my
> (:require [clojure.contrib.classpath :as cp]))
>
> … (cp/classpath) …
>
> or (with :only listing everything you want to import)
>
> (ns my
> (:use [clojure.contrib.classpath :only (classpath)]))
>
> … (classpath) …
>
> Both of these are considered clean style. You can also include
> everything of a namespace with a pure :use (w/o :only) but be aware
> that that might do more than you want.
>

Thanks for showing those possibilities. Works now of course.

--
Manfred


Manfred Lotz

unread,
Jan 25, 2010, 11:10:26 AM1/25/10
to clo...@googlegroups.com
On Sun, 24 Jan 2010 12:28:16 -0800 (PST)
Justin Kramer <jkkr...@gmail.com> wrote:

> You may find this ns cheatsheet helpful:
>
> http://gist.github.com/284277
>
> Justin
>

A good pointer.


--
Thanks,
Manfred

Manfred Lotz

unread,
Jan 25, 2010, 11:12:47 AM1/25/10
to clo...@googlegroups.com

It was verboses but very helpful. Thanks for making the
effort to explain it to me.

--
Manfred

Steven E. Harris

unread,
Jan 25, 2010, 8:40:43 PM1/25/10
to clo...@googlegroups.com
Justin Kramer <jkkr...@gmail.com> writes:

> You may find this ns cheatsheet helpful:
>
> http://gist.github.com/284277

That is most helpful.

What's not helpful is the weird mix of lists and vectors used by these
forms. When I finally made it to :rename accepting a map, I had to take
a break.

--
Steven E. Harris

Raoul Duke

unread,
Jan 25, 2010, 8:47:12 PM1/25/10
to clo...@googlegroups.com
> What's not helpful is the weird mix of lists and vectors used by these
> forms. When I finally made it to :rename accepting a map, I had to take
> a break.

so, like, this means i /not/ the only one who finds the whole
(whatever you want to call it) include/import syntax kinda crazy?
phew.

Steven E. Harris

unread,
Jan 26, 2010, 10:28:04 PM1/26/10
to clo...@googlegroups.com
Raoul Duke <rao...@gmail.com> writes:

> so, like, this means i /not/ the only one who finds the whole
> (whatever you want to call it) include/import syntax kinda crazy?

I was expecting even more of a backlash from those who already "get
it".

For now, I only understand it as, "There are a lot of options and
whichever one you think sounds appropriate is probably the wrong
choice. Be prepared to try several times."

--
Steven E. Harris

ataggart

unread,
Jan 26, 2010, 11:52:27 PM1/26/10
to Clojure

On Jan 25, 5:40 pm, "Steven E. Harris" <s...@panix.com> wrote:

Which is why I stopped using parens altogether for the ns stuff. E.g.,
the cheatsheet using vectors:

(ns foo.bar
[:require clojure.contrib.math]
[:require [clojure.contrib math]]
[:require [clojure.contrib [math :as math]]]
[:require [clojure.contrib seq-utils [math :as math]]]
[:use [clojure.contrib math seq-utils]]
[:use [clojure.contrib [math :only [sqrt]]
[seq-utils :only [flatten]]]]
[:use [clojure.contrib.math :exclude [sqrt]]]
[:use [clojure.contrib.math :rename {sqrt ccm-sqrt}]]
[:import [java.util ArrayList HashMap]]
[:refer-clojure :exclude [print]]
[:refer-clojure :only [print]]
[:refer-clojure :rename {print core-print}])

Thus the only time you need to use a non-vector is the map for rename,
which makes sense to me.

Raoul Duke

unread,
Jan 27, 2010, 1:31:09 PM1/27/10
to clo...@googlegroups.com
> Thus the only time you need to use a non-vector is the map for rename,
> which makes sense to me.

now if i only knew when to use ' or : or nothing, and which in (ns)
vs. inline in the repl.

ugh.

Richard Newman

unread,
Jan 27, 2010, 2:27:53 PM1/27/10
to clo...@googlegroups.com
> now if i only knew when to use ' or : or nothing, and which in (ns)
> vs. inline in the repl.

Simple: ns is a macro, so you don't need to quote. use and require are
functions, so you need to quote their symbol arguments.

ns uses keywords to identify its directives (:use), and functions
(use) don't, because they're identified by regular symbols.

Raoul Duke

unread,
Jan 27, 2010, 2:32:08 PM1/27/10
to clo...@googlegroups.com
On Wed, Jan 27, 2010 at 11:27 AM, Richard Newman <holy...@gmail.com> wrote:
> Simple: ns is a macro, so you don't need to quote. use and require are
> functions, so you need to quote their symbol arguments.
>
> ns uses keywords to identify its directives (:use), and functions (use)
> don't, because they're identified by regular symbols.

ok, thanks, i will try to internalize that :-)

i am not somebody who can point to languages i have defined and
implemented, so i don't have any cred, but i think the requirement
that the programmer know such details (like i have to know what is or
is not a macro in the system at all times) is less than ideal for the
end-user-programmer.

sincerely.

Matt Revelle

unread,
Jan 27, 2010, 4:41:47 PM1/27/10
to Clojure
On Jan 27, 2:32 pm, Raoul Duke <rao...@gmail.com> wrote:
>
> ok, thanks, i will try to internalize that :-)
>
> i am not somebody who can point to languages i have defined and
> implemented, so i don't have any cred, but i think the requirement
> that the programmer know such details (like i have to know what is or
> is not a macro in the system at all times) is less than ideal for the
> end-user-programmer.
>
> sincerely.

In general, if you see a form that looks like it's a special language
and wouldn't evaluate its
contents before executing the form then it's a macro.

With clojure.core/ns, you can reason that in the form (ns foo), ns
must be a macro because otherwise
the evaluation of foo would cause an error (or in the case you had
defined a foo, you'd get a namespace named after
the contents of foo, not the symbol foo).

You can always check by examining metadata.

(meta (var clojure.core/ns))
;; or more succinctly,
(meta #'clojure.core/ns)

You'll see a key-value pair of {:macro true} in the metadata map.

Raoul Duke

unread,
Jan 27, 2010, 4:49:32 PM1/27/10
to clo...@googlegroups.com
On Wed, Jan 27, 2010 at 1:41 PM, Matt Revelle <mrev...@gmail.com> wrote:
> In general, if you see a form that looks like it's a special language
> and wouldn't evaluate its
> contents before executing the form then it's a macro.

but that is a chicken-egg thing where i have to experiment and fiddle
and then memorize special cases before i can get things working right.
in the mean time i'm facing a bunch of possible ways to do something
and most won't work (and some even don't work w/out giving anything
that is an error!) and my psyche has to go through a lot of the
programming language basically telling me "eff you, luser!".

which to me seems somewhat antithetical to didactic purposes. i'm much
more in the TOOWTDI camp than the TMTOWTDI when it comes to design.

sincerely,
$0.02 of a non programming language creator, only a simple user.

DanL

unread,
Jan 28, 2010, 2:50:07 PM1/28/10
to Clojure
Hello!

On 27 Jan., 22:49, Raoul Duke <rao...@gmail.com> wrote:


> On Wed, Jan 27, 2010 at 1:41 PM, Matt Revelle <mreve...@gmail.com> wrote:
> > In general, if you see a form that looks like it's a special language
> > and wouldn't evaluate its
> > contents before executing the form then it's a macro.
>
> but that is a chicken-egg thing where i have to experiment and fiddle
> and then memorize special cases before i can get things working right.
> in the mean time i'm facing a bunch of possible ways to do something
> and most won't work (and some even don't work w/out giving anything
> that is an error!) and my psyche has to go through a lot of the
> programming language basically telling me "eff you, luser!".

Well, there are some things that can quickly be identified as macros,
like the various def* or with-* forms. Besides, in every language
there are some things one will have to get used to and which may seem
odd at first sight. One major difference of languages like Clojure is
that (assuming a proper environment to work in) a quick check at the
REPL is only some fraction of a second away, and the few stumbling
blocks like #'and shouldn't be a real problem if you try to learn the
language seriously for more than one week.

> which to me seems somewhat antithetical to didactic purposes. i'm much
> more in the TOOWTDI camp than the TMTOWTDI when it comes to design.

What if the OWTDI starts to get in your way? Is there anyone capable
to define a OWTD which will fit your requirements in the future?

Regards

dhl

Raoul Duke

unread,
Jan 28, 2010, 3:39:52 PM1/28/10
to clo...@googlegroups.com
On Thu, Jan 28, 2010 at 11:50 AM, DanL <leid...@gmail.com> wrote:
>> which to me seems somewhat antithetical to didactic purposes. i'm much
>> more in the TOOWTDI camp than the TMTOWTDI when it comes to design.
>
> What if the OWTDI starts to get in your way? Is there anyone capable
> to define a OWTD which will fit your requirements in the future?

good questions, for sure.

Reply all
Reply to author
Forward
0 new messages