I don't know if this is considered good Clojure, but you could define a
print-method within a macro to set up the normal string representation for
the partial function:
(defmacro partial* [fname arg0 & args]
`(let [pf# (partial ~fname ~arg0 ~@args)
cpf# (class pf#)]
(defmethod print-method cpf# [o# w#]
(if (nil? '~args)
(print-simple (str "(partial " '~fname " " (pr-str ~arg0) ")") w#)
(print-simple (str "(partial " '~fname " " (pr-str ~arg0) ~@(map
#(str " " (pr-str %)) args) ")") w#)))
pf#))
A transcript of some quick examples:
user=> (def p6 (partial* + 1 2 3))
#'user/p6
user=> p6
(partial + 1 2 3)
user=> (p6 7)
13
user=> (def re-find-foo (partial* re-find #"foo"))
#'user/re-find-foo
user=> re-find-foo
(partial re-find #"foo")
user=> (re-find-foo "abcdefooghi")
"foo"
On Friday, April 25, 2014 9:01:37 AM UTC-7, Matthew DeVore wrote:
>
> Hi,
>
> There has been one thing bugging me for a long time that seems worth it to
> fix, and I was wondering if anyone else has had the same problem. I have
> enjoyed using Clojure's REPL and embracing a Clojure-style data model for
> my app, where everything is a glorified map or vector and there are no
> private fields. I even have a simple dump feature that tells me the entire
> state of my app <https://github.com/google/hesokuri> that was
> ridiculously easy to implement, and that takes advantage of the lack of
> black box data structures.
>
> One thing that doesn't really fit in this paradigm is (ironically)
> anonymous functions with closures. For instance, (partial + 42) returns an
> anonymous function, and in the REPL or an app dump, it looks hideous:
> #<core$partial$fn__4228 clojure.core$partial$fn__4228@1ee1dea2>
>
> So I've avoided anonymous functions in my app except when they exist
> transiently, and don't appear in the dump (for instance, in (map #(str %
> "!") foo)). But sometimes I just can't avoid a long-lived anonymous
> function practically. The best solution I've come up with is to transform
> anonymous functions when preparing the application dump. (See the
> implementation<https://github.com/google/hesokuri/blob/b60cb7222cfdd672e394ef6f22b80c94278fe3a0/src/hesokuri/see.clj#L35>)
>
> This makes (partial + 42) look like this:
>
> {:fn-class clojure.core$partial$fn__4228,
> "arg1" 42,
> "f" {:fn-class clojure.core$_PLUS_}}
>
> Which isn't great (I'd like to have filenames and line numbers for each
> anon fn, and a nicer name for clojure.core/+), but it's a big improvement.
> The function's JVM class and the closured values are revealed. It would be
> nice to implement this natively. Having only passing familiarity with the
> Clojure code base, to solve it I think one could:
>
> - give anonymous functions a .getClosure method which creates a view
> of the closure on-demand
> - (optional) change their .toString implementation to include this
> information
> - add logic to clojure.pprint to use the .getClosure method (I guess
> "(defmethod clojure.pprint/simple-dispatch clojure.lang.AFunction etc...)"
> ?)
>
> Another feature that would go nicely with this is smarter equality
> semantics for anonymous functions, so that any two anonymous functions
> generated at the same point in code with equal closures are equal. This
> means if I have a function like this:
>
> (defn exclaimer [bangs] #(apply str % (repeat bangs "!")))
>
> then the following would be true: (= (exclaimer 10) (exclaimer 10)),
> making functions behave a lot more like values. I would love to have this
> particular feature too, although I'm having trouble coming up with a
> non-contrived example.
>
> I'd like to hear some thoughts on this. Thanks!
>
> Matt
>
>
>
>
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.