On May 25, 2009, at 7:17 PM, Andrew Wagner wrote:

> Seems straightforward enough. My difficulty though comes in trying  
> to figure out how to write the winboard bit. I know how to do the IO  
> stuff, that's pretty trivial. But, let's say I'm ready to ask the  
> engine what move to make in a particular position. The engine itself  
> should provide a function that takes a position and returns a move.  
> But...and this is where my old OO mindset is probably kicking  
> in...there's no way to do something like engine.getMove(position),  
> and it does have "its own" functions.


If that's the only function, just pass it that function. But I don't  
think anyone would fault you for just making a class if you have more  
than one. Certainly if it's what you're most comfortable with.

If you really wanted to do something functional you could close over  
your state and return a dispatch function. For a trivial counter it  
might look something like this:

(defn make-counter
   [init]
   (let [counter (ref init)]
     (fn [method & args]
       (condp = method
        'count (dosync (alter counter inc))
        'reset (dosync (ref-set  counter 0))
        'set-to (dosync (ref-set counter (first args)))
        'peek  @counter))))

Then use it like this:

user> (def c (make-counter 0))
#'user/c
user> (c 'count)
1
user> (c 'count)
2
user> (c 'peek)
2
user> (c 'reset)
0
user> (c 'set-to 5)
5
user> (c 'count)
6

I don't think I'd really do that in practice though. If you need a  
dispatch function like that you might as well make a class. In  
Clojure, it would look something like this:

(ns Counter
   (:gen-class
    :constructors {[] []}
    :init init
    :state cnt
    :methods [[count [] Integer]
             [reset [] Integer]
             [setTo [Integer] Integer]
             [peek  [] Integer]]))

(defn -init []
   [[] (ref 0)])

(defn -count [this]
   (dosync (ref-set (.cnt this) (inc @(.cnt this)))))

(defn -reset [this]
   (dosync (ref-set (.cnt this) 0)))

(defn -setTo [this val]
   (dosync (ref-set (.cnt this) val)))

(defn -peek [this]
   @(.cnt this))


Using it would look like this:

user> (compile 'Counter)
Counter
user> (def c (Counter.))
#'user/c
user> (.count c)
1
user> (.count c)
2
user> (.count c)
3
user> (.setTo c 10)
10
user> (.count c)
11
user> (.reset c)
0
user> (.peek c)
0
user> (.peek c)
0
user>

It's more code, but it's also much more readable, accessible from Java  
(and other JVM languages) and might be closer to what you're having to  
do.

—
Daniel Lyons
http://www.storytotell.org -- Tell It!


--~--~---------~--~----~------------~-------~--~----~
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
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