On Fri, Jan 21, 2011 at 9:49 AM, Aaron Bedra <aaron.be...@gmail.com> wrote: > On 01/21/2011 09:22 AM, Laurent PETIT wrote: > > 2011/1/21 Aaron Bedra <aaron.be...@gmail.com> >> >> On 01/21/2011 12:51 AM, Ken Wesson wrote: >>> >>> On Fri, Jan 21, 2011 at 12:40 AM, Alex Baranosky >>> <alexander.barano...@gmail.com> wrote: >>>> >>>> I've wanted to have private defs. For defn, I just us defn-. But there >>>> is >>>> no def- >>>> >>>> So I just use: >>>> >>>> (defmacro def- [name& decls] >>>> (list* `def (with-meta name (assoc (meta name) :private true)) >>>> decls)) >>> >>> There's a (defvar- ...) in clojure.contrib. Why there's nothing like >>> this in core remains a mystery to me. :) >>> >> You can also do >> >> (def foo {:private true} (...)) > > With def, it will be : > user=> (def ^{:private true} foo "ba") > #'user/foo > user=> (meta (var foo)) > {:ns #<Namespace user>, :name foo, :file "NO_SOURCE_PATH", :line 4, :private > true} > user=> > > It's with defn that you can use a map at a certain position: > user=> (defn foo {:private true} [] "bar") > #'user/foo > user=> (meta (var foo)) > {:ns #<Namespace user>, :name foo, :file "NO_SOURCE_PATH", :line 7, > :arglists ([]), :private true} > user=> > > > Doh! I'm full of typos this week. Do a combination of what I meant and > what Laurent said and you'll be in a good place.
It's still odd that defvar- isn't in core. Explicit metadata is clunky compared to defn-. Another thing -- defn docstrings. It would be nice if: 1. You could optionally put a docstring after the value of a normal def -- (def foo 17 "seventeen"). 2. A function body that starts with a string and isn't only the string is treated as if the string were a docstring, so (defn foo "Docstring -- works currently" ([x y] (+ (* x x) y))) and the imo tidier with only one arity (defn foo [x y] "Docstring -- works currently" (+ (* x x) y)) would be equivalent. (defn foo "Docstring -- works currently" [x y] (+ (* x x) y)) should probably also work (it currently doesn't -- the function works but the docstring disappears). Obviously (defn foo [] "Hello, World") would still have to return "Hello, World", hence the requirement that the defn body discards the string rather than returns it. 3. Multiple string literals in a row could be used. (defn foo "Docstring line 1 Docstring line 2 Lines 3 and on ..." ([x y] (+ (* x x) y))) has lines 2 and up begin with a lot of spaces. If these are kept, it will print as Docstring line 1 Docstring line 2 Lines 3 and on ... If they are not, then a docstring containing ... Example usage: (mymacro foo [a 17 b 32] (dosync ... (blah blah ...))) is going to lose the indents in the example lines. And of course (defn foo "Docstring line 1 Docstring line 2 Lines 3 and on ..." [x y] (+ (* x x) y)) is butt-ugly. (defn foo "Docstring line 1" "Docstring line 2" "Lines 3 and on ..." [x y] (+ (* x x) y)) if it worked would avoid that trilemma; docstring lines would start with only the leading spaces actually intended to be included in the text, so the entire tool chain could preserve them and get the desired results. If combined with 2 above, this would mean that any function whose s-expression was (defn symbol vector string-literal string-literal ... string-literal at-least-one-more-thing) would have the chain of string literals treated as docstring lines, with the at-least-one-more-thing as the body. Anything from the first non-string-literal on would be the body; if there was nothing in there but string literals after the argvec the final string literal would be taken as the return value rather than a doc line. Note: the docstring literals under this proposal will tend to not contain newlines. (interpose \newline string-literal-seq) should therefore be used to combine the literals into the docstring. 3 can be applied to the hypothetical def docstrings as well: (def name val line1 line2 ... linen) would be equivalent to (def ^{:doc (interpose \newline [line1 line2 ... linen]) name val) Another thing that could be useful: if the entire s-expression (def ...) or (defn ...) has metadata, merge it in, and if there's more than one meta, merge rather than replace. This would allow a style that didn't cause longer documentation strings to separate the function name from the body, and where indent is less of an issue: ^{:doc "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."} ^{:private true :tag String} (defn foo ...) It'd also be less awkward when setting flags and hinting return type. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@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+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en