Code as data is the mantra. Functions and closures as data. So why not objects as data? What I propose is nothing new, but perhaps a new style.
Making objects from map structures is simple enough in Clojure. And easy enough to put functions in a map. So why not closures? A closure in a map is a lot like an object method, hmm?
I found clojure components to be inspirational. But as light-weight as they are, components are still too heavy-weight to be objects. But a simple map seems ideal. And with only a map instead of a record or deftype, composition is simplicity itself. But the key idea here comes from clojure components: contents of the map should be configuration parameters or architecture, but not state. Put state in an atom and then (optionally) put the atom in the map. But once an object is formed, the contents of the map should not change. There should be no need to update a reference to this map.
Below is what I am calling a Clojure Object. Like a Java object, the method holds both data and methods (closures). Note that, because we are using closures, local data can be accessed without having to be put in the map. For example, the file-channel variable is not accessed via the map and need not have been added to the map.
Bill
(ns aatree.db-file
(:require [clojure.tools.logging :as log])
(:import (java.nio.channels FileChannel)
(java.nio.file OpenOption StandardOpenOption)))
(defn db-file-open
([file opts]
(db-file-open (assoc opts :db-file file)))
([opts]
(if (not (:db-file opts))
(throw (Exception. "missing :db-file option")))
(let [file (:db-file opts)
^FileChannel file-channel
(FileChannel/open (.toPath file)
(into-array OpenOption
[StandardOpenOption/CREATE
StandardOpenOption/READ
StandardOpenOption/WRITE]))
opts (assoc opts :db-file-channel file-channel)
opts (assoc opts
:db-close
(fn []
(try
(.close file-channel)
(catch Exception e
(log/warn e "exception on close of db-file")))
(dissoc opts :db-file-channel)))
opts (assoc opts
:db-file-empty?
(fn []
(= 0 (.size file-channel))))
opts (assoc opts
:db-file-read
(fn [byte-buffer position]
(.read file-channel byte-buffer position)))
opts (assoc opts
:db-file-write
(fn [byte-buffer position]
(.write file-channel byte-buffer position)))
opts (assoc opts
:db-file-write-root
(fn [byte-buffer position]
(.force file-channel true)
(.write file-channel byte-buffer position)
(.force file-channel true)))
opts (assoc opts
:db-file-force
(fn []
(.force file-channel true)))]
opts)))
--
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.
You can tell I'm still new to clojure. The composition should have been written like this:(-> opts (db-file-open) (db-cache-start) etc)
--
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.
You received this message because you are subscribed to a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/N-UG4jh8FDY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.
The reason for having this "type of object" at all is that I was going to have 3 copies of the same code. Which I find to be a bad thing.
On Nov 23, 2015 6:34 AM, "Bobby Bobble" <bpb...@gmail.com> wrote:
>
> let's not forget that Clojure's datastructures are objects. They respond to messages like seq, first, rest etc (which requires a bit more complexity than what Clojurians hail as "just data", which would be like 1010101111110101011111000110000011...what Clojurians really mean by that term is something like "uniform access to objects")
Hmm. If by "object" you mean entity, thing, value, etc. - i.e. mathematical structure - then I'd agree, but in my view Clojure does not involve OO "objects" in any way, _conceptually_. "This function is defined on that type" != "that type 'responds to' this function" .
>
> (Clojure's vocabulary is not to be questioned...why say "conflate" or "confuse" when you can say "complect" to reinforce in-group membership ?) /rant
THANK YOU! I can't count the number of times I've had to restrain myself from an apoplectic rant about this hideous non-word. What is wrong with "complicate" FFS?!
>
> anyway to the point, it depends what you mean by "objects".
>
> What you propose is to use maps as a kind of namespace for functions. It's a good idea. I use this pattern too. Really, namespaces should be maps...actually I think there was a project called Kiss to that end.
To the OP's original point: you can view functions as data, but I find myself moving toward a view of data as functions. E.g. it's as nullary fns.
>
> But real OO, as realized by Smalltalk and Self is about messaging, not objects.
Thank you again. Objective C is another good example. Dunno why they called it OO in the first place.
AFAIA there's no way in Clojure to represent "the invocation of a function on a thing" the way you can represent "the sending of a message to an object" in Smalltalk.
Not quite sure what you mean, but with stuff like core.async and protocols it's possible to support an explicit msg - passing idiom in Clojure. But I think I agree with you. It would be something you build on more primitive notions.
Gregg
On Nov 23, 2015 4:23 PM, "Gregg Reynolds" <d...@mobileink.com> wrote:
>
>
> On Nov 23, 2015 6:34 AM, "Bobby Bobble" <bpb...@gmail.com> wrote:
> >
> > functions. E.g. it's as nullary fns.
Sorry, "ints", not "it's ". How I hate spell-checkers!!
> (Clojure's vocabulary is not to be questioned...why say "conflate" or "confuse" when you can say "complect" to reinforce in-group membership ?) /rant
THANK YOU! I can't count the number of times I've had to restrain myself from an apoplectic rant about this hideous non-word. What is wrong with "complicate" FFS?!
> (Clojure's vocabulary is not to be questioned...why say "conflate" or "confuse" when you can say "complect" to reinforce in-group membership ?) /rant
THANK YOU! I can't count the number of times I've had to restrain myself from an apoplectic rant about this hideous non-word. What is wrong with "complicate" FFS?!
Confusion is somewhat orthogonal to complexity as it is more to do with the _understanding_ of the thing.
--
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.
As in quantum entanglement? :-)