I had a quick experiments with some of these idea in case there is interest:
https://github.com/mikera/clobber The key difference in this approach is that the functions go first, and work as regular functions. If you get a chance take a look and let me know what you think. On Tuesday, 12 February 2013 07:19:17 UTC+8, eduardoejp wrote: > > Hi, Mikera. > > Thanks for the feedback, it was a very interesting read. > > > Nice, I have been looking for something like this to experiment with. > Glad to see someone else who likes to experiment with weird code :P > > However, I must admit that I made it mainly as a toy project, with no > serious intent for actually using it (I actually try to avoid OO as much as > possible, since I don't see it as a good solution to most problems). I just > wanted to see how feasible it was to implement an OO system on top of > functions. However, reading what you wrote gave me some ideas, so I might > work on it more and see where it takes me. The implementation itself has > only ~70 LoC, so it turned out to be pretty easy to do. > > > Suggestions on syntax: It would be much nicer to use and more idiomatic > if the method name came first, e.g. > > (method some-object arg1 arg2) > > The idea was for objects to be functions, which means they have to go > first. Having the methods be keywords and not other functions also gave it > a sort of message-passing feel that is kinda nice. > I wonder what are the specific advantages of putting the objects first / making them functions? > > > This would bring many benefits: you could use the standard "->" syntax, > you can "apply" a method, it will fit much better when composed with > Clojure library functions etc. > > Being able to use Clojure's "->" macro would have been real nice, but > having the objects be functions made it impossible. It's just a sad reality > I'll have to live with. > > > You could also potentially use any associative data structure as your > object type. > > There are only two alternatives to regular Clojure maps when it comes to > associative data structures. One is vectors, but I'm not sure what the > semantics of using vectors as the storage unit would be. The other is > allowing custom "map-like" datatypes made by users. However, one fear I had > was allowing people to use mutable implementations (like a KV cache, for > example), which would have messed up the functional feel of the library. > Hmmmm difficult to stop people using mutable stuff if they are determined enough. But I think the most common use case would be with defrecord - which is immutable just like a regular Clojure map. > > One idea I had was also to create an object datatype that implemented the > interfaces to behave like a map and a function. That way people would have > been able to use assoc & dissoc, for example. However, wanting to keep > things minimal and to rely only on regular functions, I discarded that > option. > > > You could also potentially have special handling for null object values, > default implementations in case of missing methods etc. > > The idea for the missing methods is quite nice. I'm thinking maybe a way > could be added to the library to create hooks into several "life-cycle > events" of the objects. > You could have hooks for calling functions: > + That way you could implement before|after|around mixin functionality. > + You could also have method-missing code to work by doing that. > > You could have hooks for reading/writing attributes: > + That would you could have setter-like validation of changes. > + You could also implement virtual-slots with it, reading from fields > that are actually calculated on-the-fly. > > > This suggests to me that it would be a better design if each method was > defined as a function that looked up the specific implementation in the > prototype object and called it. > > Obviously, this means that you need to explicitly declare prototype > methods. > > But I think this is a good idea anyway: it ensures a bit more discipline > and testability (which is often the biggest problem in prototype-based > systems.....) > > That is something that can certainly be done, but I'm not sure if the > library should implement it. > What I mean by that is this: the implementation is meant to provide the > bare minimum you need to build everything else you need on top. > That functionality can easily be built on top without needing to modify > the OO system itself; so although it would be cool to have that, I don't > think the library should concern itself with providing it. > Hmmm I think that to be useful, a hypothetical library in this space needs to provide all the "standard" functionality that people are likely to want. Otherwise they will just be forced to reinvent the wheel, which doesn't help anyone..... > > Regarding the discipline and testability: I really like to strive towards > those two things, but thinking about incorporating those changes kinda > makes me feel like we're back in the class-based OO world. Not because we > have actual classes around, but because providing so much specification > code feels like we have supplanted classes with some sort of implicit > quasi-class-like OO specification, and I'm not sure if that would play so > well with the dynamicity that the library strives to achieve. > -- -- 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/groups/opt_out.