8000 Create a record for maze · Issue #14 · codecation/maize · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Create a record for maze #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
r00k opened this issue Mar 6, 2014 · 2 comments
Open

Create a record for maze #14

r00k opened this issue Mar 6, 2014 · 2 comments

Comments

@r00k
Copy link
Contributor
r00k commented Mar 6, 2014
(defrecord Maze [doors walls visited ...])

Might clean up the code a bit to have an explicit record. Shouldn't require many changes, since records can do almost everything maps can, but are significantly more performant, and help document what your data looks like.

If we go this route, I'd like to experiment passing the entire maze structure to all fns, with each fn destructuring out the pieces it needs.

@chrishunt
Copy link
Member

If we go this route, I'd like to experiment passing the entire maze structure to all fns, with each fn destructuring out the pieces it needs.

YES. We are doing this already in a lot of places. I'd like to see this too.

@chrishunt
Copy link
Member

So... I tried to see how this would look in a first pass by just sticking everything into a defrecord

My first thought for the make-maze constructor was to provide defaults in the parameter list like we are currently doing in search-maze

(defrecord Maze [size paths current-path visited walls doors update-channel
                 search-algorithm possible-paths-fn finished-fn])

(defn make-maze [{:keys [size paths current-path visited walls doors
                         update-channel search-algorithm possible-paths-fn
                         finished-fn]
                  :or {search-algorithm depth-first
                       possible-paths-fn shuffled-possible-paths
                       update-channel (chan (dropping-buffer 1))
                       paths [[[0 0]]]
                       visited #{}
                       doors #{}}}]
  (Maze. size paths current-path visited walls doors update-channel
         search-algorithm possible-paths-fn finished-fn))

I'm not a fan of this though because we duplicate our parameter list 4 times. It's not very pretty at all.

I tried to clean this up by merging any options we provide with a set of defaults, but this looks dumb because Maze. cannot be initialized with a map. We also can't splat in Clojure. We end up initializing Maze. with a ton of nils and merging in our parameters:

(defrecord Maze [size paths current-path visited walls doors update-channel
                 search-algorithm possible-paths-fn finished-fn])

(defn make-maze [options]
  (let [defaults {:search-algorithm depth-first
                  :possible-paths-fn shuffled-possible-paths
                  :update-channel (chan (dropping-buffer 1))
                  :paths [[[0 0]]]
                  :visited #{}
                  :doors #{}}]
    (merge (Maze. nil nil nil nil nil nil nil nil nil nil)
           (merge defaults options))))

Because JavaScript is hella janky and doesn't enforce arity, we can acutally get away with not passing all the nils into Maze. and we get something that looks pretty good.

(defrecord Maze [size paths current-path visited walls doors update-channel
                 search-algorithm possible-paths-fn finished-fn])

(defn make-maze [options]
  (let [defaults {:search-algorithm depth-first
                  :possible-paths-fn shuffled-possible-paths
                  :update-channel (chan (dropping-buffer 1))
                  :paths [[[0 0]]]
                  :visited #{}
                  :doors #{}}]
    (merge (Maze.) (merge defaults options))))

I still don't like this solution though because we get a warning when compiling and it flat out doesn't work in Clojure.

WARNING: Wrong number of args (0) passed to Maze

The only decent solution I've been able to find is exactly like the first example we have above, but creating a defrecord+ macro to make it look a bit prettier:

(defrecord+ Maze
  [size nil
   paths [[[0 0]]]
   current-path nil
   visited #{}
   walls nil
   doors #{}
   update-channel (chan (dropping-buffer 1))
   search-algorithm depth-first
   possible-paths-fn shuffled-possible-paths
   finished-fn nil])

What are your thoughts on this? Is there another convention for class defaults that you've seen somewhere? The macro seems to make the most sense, but I feel like I might be missing something here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants
0