FAQ
Just a simple toy project I made moments ago...
https://github.com/eduardoejp/jormungandr

--
--
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+unsubscribe@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+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

  • Mikera at Feb 11, 2013 at 2:15 am
    Nice, I have been looking for something like this to experiment with.

    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)

    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. You could also potentially use any associative data
    structure as your object type. You could also potentially have special
    handling for null object values, default implementations in case of missing
    methods etc.

    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. You could use a macro to declare the
    function, and possibly even a default value, e.g.

    (def mymethod
    (prototype-fn [obj arg1 arg2]
    :default (do-something-with arg1 arg2)))

    When would expand into something like:

    (defn mymethod [obj arg1 arg2]
    (if-let [method (:$mymethod obj)]
    (method obj arg1 arg2)
    (do-something-with arg1 arg2)))

    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.....)
    On Monday, 11 February 2013 04:21:58 UTC+8, eduardoejp wrote:

    Just a simple toy project I made moments ago...
    https://github.com/eduardoejp/jormungandr
    --
    --
    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+unsubscribe@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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Eduardoejp at Feb 11, 2013 at 11:19 pm
    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.
    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.

    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.

    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+unsubscribe@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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Mikera at Feb 12, 2013 at 2:23 pm
    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+unsubscribe@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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Eduardoejp at Feb 13, 2013 at 2:44 am
    I wonder what are the specific advantages of putting the objects first /
    making them functions?

    There wasn't any specific advantage. I did it because I could and I thought
    it was an interesting approach.
    I didn't just want to create Yet-Another-OO-System. I wanted it to be
    different.

    Alternatively, I made like 1~2 years ago another object system called
    Fenrir (you'll find it on my GitHub account). That one is class-based and
    depends on hash-maps and multimethods. I didn't just want to make the
    prototype-based version of it.
    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.

    Regarding mutability: It's true, but it doesn't mean I should make it easy.
    I'm not religious about FP, but I find it helps me write very clean, simple
    and reusable code, so I'm kinda biased towards it.

    Using records would kinda defeat the point of creating an OO system in the
    first place. Why build an OO system on top of another?

    However, I get the point that people might want options. I'd still wait
    until I meet an option that I could believe was really valid.
    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.....

    The library was originally meant to be just something I did "for the lulz"
    and then forgot about it. If people actually want to take it seriously,
    then I guess it has perfect sense to extend it. I thought a bit about what
    you said and think some "sugar" could be added to make it more pleasing to
    use.

    HOWEVER, I will make the following disclaimer:
    As something that came out of my desire to experiment, I will not develop
    it further to make it more usable to others. If anything, I'm going to
    stretch and twist it as far as reason allows me to see "what can be done",
    more than "what needs to/should be done".

    In other words: it is an experiment, first and foremost.

    Anybody comfortable with this can hop in, but I need to provide the
    disclaimer so nobody gets the wrong idea.

    --
    --
    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+unsubscribe@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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupclojure @
categoriesclojure
postedFeb 10, '13 at 8:22p
activeFeb 13, '13 at 2:44a
posts5
users2
websiteclojure.org
irc#clojure

2 users in discussion

Eduardoejp: 3 posts Mikera: 2 posts

People

Translate

site design / logo © 2022 Grokbase