This is pretty much what I'd had in mind.  I don't see how the text of
the Exception is set by the macro, but it'd be really spectacular if
the message were more clear.  Is that message coming from the defvar
form?

On Oct 6, 6:14 pm, "Stephen C. Gilardi" <squee...@mac.com> wrote:
> On Oct 2, 2009, at 10:29 AM, Mark wrote:
>
> > Is there a way to make a declaration in Clojure that cannot be rebound
> > later?  Ideally, I'd like something that fails if I try to do this:
>
> > (def myname "mark")
> > ; ...more code, elided...
> > (def myname "Mark")
>
> Along these lines, I was thinking of adding defconst to  
> clojure.contrib.def. It's like Common Lisp's defconst, but the fact  
> that its value isn't allowed to change is enforced:
>
> (defmacro defconst
>    "Defines a var with a constant value and optional doc string. Any  
> attempt
>    to redefine, bind, or set! the const to a different value will  
> throw an
>    exception."
>    ([name init]
>       `(do (set-validator! (defvar ~name ~init) #{~init}) (var ~name)))
>    ([name init doc]
>       `(defconst ~(with-meta name (assoc (meta name) :doc doc)) ~init)))
>
> It does allow a redefine, binding, or set! to an equal value mainly as  
> an artifact of its implementation, but also because such a "change"  
> would be harmless to the semantics of it being constant.
>
> user=> (defconst pi (* 4 (Math/atan 1)))
> #'user/pi
> user=> pi
> 3.141592653589793
> user=> (binding [pi 3] (prn pi))
> java.lang.IllegalStateException: Invalid reference state  
> (NO_SOURCE_FILE:0)
> user=> (binding [pi pi] (prn pi))
> 3.141592653589793
> nil
> user=> (binding [pi pi] (set! pi 3))
> java.lang.IllegalStateException: Invalid reference state  
> (NO_SOURCE_FILE:0)
> user=> (defconst pi 3)
> java.lang.IllegalStateException: Invalid reference state  
> (NO_SOURCE_FILE:7)
> user=> (def pi 3)
> java.lang.IllegalStateException: Invalid reference state  
> (NO_SOURCE_FILE:10)
> user=> (defconst pi (* 4 (Math/atan 1)))
> #'user/pi
>
> I'd appreciate hearing any suggestions for improvement or other  
> feedback.
>
> --Steve
>
>  smime.p7s
> 3KViewDownload
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to