Nested (defn)

90 views
Skip to first unread message

Michael Reid

unread,
Sep 10, 2008, 11:33:16 AM9/10/08
to clo...@googlegroups.com
Hi folks,

There was a thread a little while back
(http://groups.google.com/group/clojure/browse_thread/thread/8c4bea21298693ca)
about implementing true data hiding by nesting defns under a let,
e.g.:

(let [hidden-ref (ref 10)]
(defn get-secret [] @hidden-ref))

This was mentioned to be bad style. If this is the general consensus,
what suggestions do you have if you want to write a macro which
generates a Java class using (genclass) and also generates default
implementations for some getter and setter methods?

For example, I want to write a macro that transforms:

(defbean MyBean :myint 0, :mystring "default")

into something like:

(gen-and-load-class "MyBean" ...)

(defn MyBean-getMyint [this] ...)
(defn MyBean-setMyInt [this value] ...)
(defn MyBean-getMystring [this] ...)
(defn MyBean-setMystring [this value] ...)

However, in order to do this, the macro needs to expand to something like:
(do
(gen-and-load-class "MyBean" ...)

(defn MyBean-getMyint [this] ...)
(defn MyBean-setMyInt [this value] ...)
(defn MyBean-getMystring [this] ...)
(defn MyBean-setMystring [this value] ...))

In my case I've been wrapping this in a (let) as there are some locals
that I need to setup in order to fill in the templates for the getters
and setters.

I'm wondering if there is a different way, in light of the dislike for
placing (defn) in a nested structure instead of the top-level.

Thoughts?

/mike.

Rich Hickey

unread,
Sep 10, 2008, 12:11:42 PM9/10/08
to Clojure


On Sep 10, 11:33 am, "Michael Reid" <kid.me...@gmail.com> wrote:
> Hi folks,
>
> There was a thread a little while back
> (http://groups.google.com/group/clojure/browse_thread/thread/8c4bea212...)
There's nothing wrong with this. Any macro that needs to emit more
than one def is going to have to emit them in a do or let.

The general admonition against non-top-level defs is to guard against
their use as a form of assignment to global vars. From the docs
(http://clojure.org/special_forms) :

"Using def to modify the root value of a var at other than the top
level is usually an indication that you are using the var as a mutable
global, and is considered bad style."

That's not what you are doing. You are using def appropriately, which
is to _establish_ root bindings, not modify them.

Rich
Reply all
Reply to author
Forward
0 new messages