Good stuff, just what I was looking for, can't wait to try...
sent from my mobile device
> --
> 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
> [fs "0.2.0-SNAPSHOT"] is out
A SNAPSHOT is "out"? Please don't do this. If it is a release, get rid
of the SNAPSHOT. :(
First, I suggest that you look at the standard clojure.java.io package for some useful functions that are already in Clojure 1.2. In particular, you could use io/file instead of (File. xxx) in your code to add some flexibility to the kinds of things that can be treated as a "file". I think io/file could replace your fs/join. Also, io/copy is very flexible so it's worth a look, too.
Second, fs is using a singe segment namespace. I remember that there have been some cautions against doing that. (But not everyone agrees.) My understanding is that it's best for Java interop to have a multi-segment namespace. (Reference links below.)
> A lib name is a symbol that will typically contain two or more parts separated by periods.
http://groups.google.com/group/clojure-dev/browse_frm/thread/00b1c6971c3b3394
Chas Emerick wrote:
> First, namespacing is good. Your foobar library won't have the same name as my foobar library -- and while you might think "who else would put code in the same oddly-named namespace as mine?", it's a big world out there and an ounce of prevention is worth a pound of cure. More strictly speaking, one cannot use any class in the default package from any Java class that is in a package. That is the practical issue that leads to default package use being nonexistent in the Java space. And, you may not care about Java interop now, but either (a) you might later, or (b) your users might, now. Finally, gen-class will simply not work (last I checked) from a single-segment namespace.
Best Regards,
Steve Miner
steve...@gmail.com
Back in the days of Cobol, before it got renamed to Java,
we used to construct hierarchical databases. For those who
don't know about them, they would specifiy the path to every
element in the database in the name of the element. Thus, you
would say
world.country.company.site.disk.dbname.dept.bldg.aisle.office.person
or some such.
It was argued that this was necessary to ensure that
you always got a unique element and that programs would not clash.
It was also very efficient since the worldwide path to a point
was always unique (as opposed to the horribly inefficient idea
of using table and relational algebra to look up stuff at runtime!
Why the ambiguity will cause world confusion and the runtime will
be impossibly long! Just write out the long name! Sigh.)
There are a couple of items worth mentioning. First, notice
that everything is fine until the world changes. Now there
are hardcoded legacy assumptions built into the name (e.g.
the person is in a different building so we have to reformat
the database to pay them). Consider that the Java naming
convention does that... java.sun.com ... who is "sun"?
I never heard of them.
Second, but similar, should I name my classes java.daly.tim.freesource?
Suppose I get married and change my name? Suppose someone with a
similar name writes a package. Does my son have to write
java.jr.daly.tim.freesource?
Third, suppose I refactor my program. Now I have to rename every
class to fit the new hierarchy. But that will break old programs
that use my package. Who could possibly want to refactor deep
enough to shuffle classes?
Fourth, this hierarchical thinking strongly encourages making
functions that are class-specific. Thus you find that java has
hundreds of sorts, one per class.
Fifth, one writes the long.drawn.out.name to satify the
compiler's inability to find anything despite the class name
being unique. In fact, the compiler is insisting that your
class name match the name of the file and it STILL insists
that you use unique names so it doesn't have to search the
filesystem. The side-effects of this are that your class hierarchy
is rigid (see refactoring above), the name assumes a hierarchical
file system, and the ultimate issue... the user has to use an IDE
to find something simple as a sort.
Sixth, programs rarely need to deal with the whole world.
Why would you have qualifiers on a per-company basis just
to guarantee uniqueness of the name of your sort function?
In lisp one ends up with hundreds of functions in the same
namespace. Because the functions are not type-specific
they tend to be very broad and general. It is rare to have
more than one sort and people don't generally write sort
functions since they are too standard.
A simple namespace qualifier, like fs, is sufficient to
handle large, general purpose packages which contain functions
to handle file systems.
Since lisp uses naked functions there is no natural map from
functions to filenames.
In sum, I'm suggesting that it isn't very lispy to use
hierarchical namespace naming conventions.
Tim Daly
> > Second, fs is using a singe segment namespace. I remember that
> > there have been some cautions against doing that. (But not everyone
> > agrees.) My understanding is that it's best for Java interop to have a
> > multi-segment namespace. (Reference links below.) http://clojure.org/libs
>>> A lib name is a symbol that will typically contain two or more parts separated by periods.
>> http://groups.google.com/group/clojure-dev/browse_frm/thread/00b1c6971c3b3394
>>
>> Chas Emerick wrote:
>>> First, namespacing is good. Your foobar library won't have the same name as my foobar library -- and while you might think "who else would put code in the same oddly-named namespace as mine?", it's a big world out there and an ounce of prevention is worth a pound of cure. More strictly speaking, one cannot use any class in the default package from any Java class that is in a package. That is the practical issue that leads to default package use being nonexistent in the Java space. And, you may not care about Java interop now, but either (a) you might later, or (b) your users might, now. Finally, gen-class will simply not work (last I checked) from a single-segment namespace.
> As a greybeard in the game, this all sounds so familiar.
> The point of this post is to suggest that Clojure should
> NOT adopt java naming conventions.
...
> Since lisp uses naked functions there is no natural map from
> functions to filenames.
>
> In sum, I'm suggesting that it isn't very lispy to use
> hierarchical namespace naming conventions.
Just to clarify my position (it's funny to see one's self quoted out of the blue from an old thread!), I'm not at all suggesting "java naming conventions" when it comes to namespacing. (Although I'd note that Clojure *is* a fundamentally hosted language, and so certain idioms do flow from that host; CamelCase naming conventions for records, types, and protocols comes to mind.) No one wants to work with com.foo.bar.baz.factory.factory.factories.Factory, etc.
While there is no natural mapping between functions and filenames, surely there's *some* mapping for every project that won't run afoul of the real issues that truly can crop up with single-segment namespaces[1] but still feels natural to you. Functionally logical grouping of code never goes out of style. I'd humbly submit that single-segment namespaces are a non-solution to any naming problem you'd like to solve (outside of maximal concision perhaps, which I'd suggest is a low-value problem).
Cheers,
- Chas
[1] If you really, really don't care about host interop, and you never, *ever* will, and you're a maestro at naming projects (yup, I'm looking at you, Phil! :-), then maybe single-segment namespaces are OK. Even then, it's worth noting that even e.g. leiningen, robert hooke, etc. don't use single-segment namespaces.
> Just to clarify my position (it's funny to see one's self quoted out of the blue from an old thread!), I'm not at all suggesting "java naming conventions" when it comes to namespacing.
By the way, I didn't mean to put Chas on the spot. Google led me to what seemed like a good quote, and I thought he deserved the credit. Please take that as a compliment.
One suggested compromise (from the old thread) was to use a short first segment so that your namespace is technically multi-segment (good for Java interop), but still short enough to be esthetically pleasing. For example, clj.foo instead of plain foo. Seems like a good compromise to me.
Now, one could say that the problem is in the Clojure compiler. Maybe single segment names should be explicitly disallowed. (They're bad, don't do that.) Or maybe the compiler should silently prepend "us.technomancy." to single-segment namespaces to make the world safe for Java interop with minimal danger of conflicts. That would make everybody happy. :-)
Cheers,
Steve
> On Jan 13, 2011, at 3:16 PM, Chas Emerick wrote:
>
>> Just to clarify my position (it's funny to see one's self quoted out of the blue from an old thread!), I'm not at all suggesting "java naming conventions" when it comes to namespacing.
>
> By the way, I didn't mean to put Chas on the spot. Google led me to what seemed like a good quote, and I thought he deserved the credit. Please take that as a compliment.
I did, thanks. :-)
> One suggested compromise (from the old thread) was to use a short first segment so that your namespace is technically multi-segment (good for Java interop), but still short enough to be esthetically pleasing. For example, clj.foo instead of plain foo. Seems like a good compromise to me.
That seems perfectly fine, as long as the prefix or suffix isn't "standard" -- otherwise, for purposes of runtime differentiation, such namespaces are functionally a single segment. i.e. if the standard is clj.foo or baz.core, then someone else's clj.foo or baz.core will conflict just as well.
FWIW, I use "cemerick" as a prefix for all personal stuff (though I do little programming that is both personal and significant enough to warrant worrying about namespaces). I assume that everyone has their preferred irc/IM/email handle; using it as a prefix seems reasonable to me, anyway.
If your name changes, then modifying some namespaces is surely not the most difficult part of that process!
- Chas
First, I suggest that you look at the standard clojure.java.io package for some useful functions that are already in Clojure 1.2. In particular, you could use io/file instead of (File. xxx) in your code to add some flexibility to the kinds of things that can be treated as a "file". I think io/file could replace your fs/join. Also, io/copy is very flexible so it's worth a look, too.
Second, fs is using a singe segment namespace. I remember that there have been some cautions against doing that. (But not everyone agrees.) My understanding is that it's best for Java interop to have a multi-segment namespace. (Reference links below.)
there is also this:
In sum, I'm suggesting that it isn't very lispy to use
hierarchical namespace naming conventions.
First, I suggest that you look at the standard clojure.java.io package for some useful functions that are already in Clojure 1.2.
It isn't nearly as big a deal as you think it is. I'm guessing you have a single file called 'fs.clj' with the namespace 'fs', right?mkdir src/fs/mv src/fs.clj src/fs/core.clj
and then edit the file and change the namespace to fs.core.
Why is that such a big deal?
I understand that you're coming from Python, but Clojure isn't, and never will be Python. If you came from COBOL would you want to write your code in all caps? Nobody is asking you to do this for fun. This is a Clojure idiom that everybody uses, and it isn't only for you but for users of your code.
>> It isn't nearly as big a deal as you think it is. I'm guessing you have a
>> single file called 'fs.clj' with the namespace 'fs', right?
>>
>> mkdir src/fs/
>> mv src/fs.clj src/fs/core.clj
>>
> and then edit the file and change the namespace to fs.core.
>
> I know it's easy to do, I just don't think I should do it.
>
More power to you, I personally don't particularly care about Java
interop (pretty sure Java has enough file system utilities) and I'd
rather not type ".core" all over the place. If it wasn't for the soft
paternalism of lein I wouldn't user .core at all.
>
> I'd appreciate some comments about need functionality, bugs, code reviews
> and such.
>
I have one question, is there any documentation available for the
functions provided by fs? I would love a place where I could go to scan
the available functions, other than the source code.
Thanks -- Eric
This is a retarded 'convention', and it isn't really much of a
convention at that. Just because Clojure itself has a 'core.clj',
doesn't mean everyone else needs one now too. I blame Leiningen's
defaults. For counter-examples, take a look at clojure-contrib. The
only core.clj in there is for proposed additions to clojure.core
itself.
If I were writing a library 'flub', I'd expected the main file the
user is expected to :use to be named flub.clj and supporting files to
be flub/SOMETHING.clj. If I wanted to make sure it was disambiguated,
say if I intended it as a library and not a stand-alone application, I
might call the namespace PREFIX.flub and PREFIX.flub.something, where
PREFIX is something one might reasonably expect to be unique, e.g.
bpsmithmannschott.flub.
// Ben
Am 19.01.2011 um 21:24 schrieb B Smith-Mannschott:
> This is a retarded 'convention', and it isn't really much of a
> convention at that. Just because Clojure itself has a 'core.clj',
> doesn't mean everyone else needs one now too. I blame Leiningen's
> defaults. For counter-examples, take a look at clojure-contrib. The
> only core.clj in there is for proposed additions to clojure.core
> itself.
Hmm… Wasn't the „main“ reason of technical nature? Namely classes in the default package? Which cause problems in Java world?
Sincerely
Meikel
I have one question, is there any documentation available for the
functions provided by fs? I would love a place where I could go to scan
the available functions, other than the source code.
> I'd appreciate some comments about need functionality, bugs, code reviews and such.
Thanks for this useful library. Some suggestions:
-I'd rather (copy-tree src dest) worked like "cp -R src dest" (including when dest doesn't exist) rather than "cp -R src/* dest/".
-It would be nice if functions that create files or dirs (like mkdir and touch) returned the new object's path, to allow chaining.
-I'd rather (copy-tree src dest) worked like "cp -R src dest" (including when dest doesn't exist) rather than "cp -R src/* dest/".
-It would be nice if functions that create files or dirs (like mkdir and touch) returned the new object's path, to allow chaining.
-I'd rather (copy-tree src dest) worked like "cp -R src dest" (including when dest doesn't exist) rather than "cp -R src/* dest/".
(defn extension [file]
(when file
(let [base (fs/basename file)
dot (.lastIndexOf ^String base ".")]
(when (pos? dot)
(subs base (inc dot))))))
Steve Miner
We are planning to use this file system utilities, and we need a function to get file extension. Currently we're using apache common for that, but we want to get rid of apache common altogether. Can you add this functionality to the fs.clj? Thx
The dirname testcase fails on Window. Does it make sense that even if it's running on window it should still pass? In another word, don't you think that it should not convert the separator implicitly?
(dirname "/a/b/c") should return "/a/b/" on both win and unix
In fact, this is not limited to Java. '/' is a path separator on equal
footing with '\' on Windows (short of UNC paths, regrettably). This
fact is often obscured by applications that make use of some ad-hoc
path mangling and implicitly assume '\' as the only path separator.
Interesting read:
http://en.wikipedia.org/wiki/Path_(computing)#MS-DOS.2FMicrosoft_Windows_style
Yes, working around this issue is discussed in the Wikipedia article I
linked to.
> I had real-world
> problems with this when trying to run a Rails app on Windows, because of the
> issue discussed here: http://www.ruby-forum.com/topic/50137
Mhh, that sounds dire, especially this comment:
"However, the Unicode Win32API -- which will be used in the future --
does not accept /."
Thanks for bringing it up.