There's one other construct that may help you here: (defrecord Point [x y] (scale [this amount] (assoc this :x (* x amount) :y (* y amount))))
defrecord acts much like deftype, but creates a new copy of the record via assoc, you can also do stuff like: (:x (->Point 10 11)) defrecord creates a constructor function (type name prefixed by ->) and you can use normal get/assoc/dissoc to work with records as if they were normal structures. So yes, defrecord is probably the most idiomatic approach if you need the functionality of defprotocol. You can also use straight up maps to do much of this: {:type :point :x 10 :y 42} You have three choices then: 1) maps - easy to work with, slower polymorphic dispatch (via multi-methods) 2) records - slightly less easy to work with, faster polymorphic dispatch 3) types - hardest to work with (manual cloning), supports mutation, fast polymorphic dispatch. Often I suggest people try working only with hash maps and multi-methods first, then move on to the other approaches if performance is too low. Most of the Clojure data-structures are so fast I use those most of the time. As far as the rest of your questions go, I often prefix protocol functions with a dash to indicate they are internal. (-scale point 42). And you really don't have to type hint functions. That's really only if you are super concerned about performance. Type hinting signatures allows the compiler to remove boxing and that sometimes helps. Once again, write the code so it works, then make it fast. Timothy Baldridge On Thu, Jul 3, 2014 at 9:44 AM, SharpCoder <cannonicalco...@gmail.com> wrote: > Hello Timothy, > > Thank you for the response. I've given much thought to your examples and > it quickly became clear how relevant defprotocol and deftype is. I had no > idea Clojure provided a mechanism for strongly typed structures like that. > I've started re-designing my library around this concept and even with my > limited understanding, the code is becoming much cleaner and simpler! > > So thank you for that. > > I had a question about designing with defprotocol. While trying to > implement my protocol "Network", I was struggling with deciding what > signature to use. Is it better to write lots of functions that compute > stuff given a concrete input. Or it is better to write functions that > return "new versions" of the inputted data? I guess my question comes down > to how other people use libraries. Is there a definitive standard or guide > for structuring libraries in Clojure? > > One other question was whether methods can be marked "internal" within a > protocol? > > Thank you for your time. > -SharpCoder > > On Wednesday, July 2, 2014 9:17:25 AM UTC-7, tbc++ wrote: > >> defstruct is deprecated. You should use defrecord or deftype instead. You >> can define operations on these via defprotocol. >> >> And you can even type hint the members: >> >> (defprotocol IScale >> (scale [this ^double amount])) >> >> (deftype Point [^double x ^double y] >> IScale >> (scale [this amount] >> (Point. (* x amount) (* y amount)))) >> >> (scale (Point. 10 1)) >> >> Timothy >> >> >> >> On Wed, Jul 2, 2014 at 9:41 AM, SharpCoder <cannoni...@gmail.com> wrote: >> >>> As an exercise, I'm trying to port a library that I originally wrote in >>> C#. It's actually a Neural Network, so my imperative design was a pretty >>> straightforward tree-like structure of nodes that could manipulate state. >>> During my port to Clojure, I've been writing functions that take multiple >>> arrays (typically "graph of outputs" and "graph of weights"). Then I >>> remembered about structs, so I refactored my code to deal with a collection >>> of structs "node". A node contains a vector of weights and an output. In >>> this way, I am only passing around a single collection that can represent >>> my whole neural network. >>> >>> Now I'm running into the fact that I kind of need to update the >>> structure. So what I've implemented is essentially, each time you calculate >>> the network output - my code iterates over the list of structs and creates >>> new ones with the "updated" values. Performance is something that people >>> don't seem to talk about much with Clojure, but I'm kind of thinking my >>> approach with structs might not be the best one. >>> >>> My question is, am I approaching this incorrectly? I've seen a lot of >>> resources that deal with the syntax of Clojure but haven't found a good >>> guide on actual application design. My usage of structures seems natural to >>> me, but that makes me question it even more! >>> >>> For anyone interested, here is my code: https://www.refheap.com/87775 >>> I'm going to open source the library after many many iterations to >>> beautify it. I'm sure it's a bit too haphazard to make sense to right now... >>> >>> Thank you for your time! >>> -SharpCoder >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Clojure" group. >>> To post to this group, send email to clo...@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+u...@googlegroups.com >>> >>> 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 clojure+u...@googlegroups.com. >>> >>> For more options, visit https://groups.google.com/d/optout. >>> >> >> >> >> -- >> “One of the main causes of the fall of the Roman Empire was that–lacking >> zero–they had no way to indicate successful termination of their C >> programs.” >> (Robert Firth) >> > -- > 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 > --- > 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 clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- “One of the main causes of the fall of the Roman Empire was that–lacking zero–they had no way to indicate successful termination of their C programs.” (Robert Firth) -- 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 --- 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 clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.