https://ferd.ca/you-reap-what-you-code.html this is a really nice article. I can see many overlaps with Clojure-y things here (and some that are just things I learned through Clojure, rather than being actual Clojurey things) > If you're not able to replace everything, consider framing things as adding it to your system rather than replacing. It's something you add to your stack. This framing is going to change the approach you have in terms of teaching, maintenance, and in terms of pretty much everything that you have to care about so you avoid the common trap of deprecating a piece of critical technology with nothing to replace it. If you can replace a piece of technology then do it, but if you can't, don't fool yourself. Assume the cost of keeping things going.
I just read about cloudflare's Durable Objects (https://blog.cloudflare.com/introducing-workers-durable-objects/) β they seem very cool. It would be interesting to create an IRef
-able based on this.
it's really hard to do transaction safe refs like clojure has with distributed state
actors are much messier, but they are a better fit as an abstraction over distributed state
nah, atom like constructs using compare and set like operations are very doable in distributed settings
IRef
is kinda a boring interface in some ways
IAtom is the thing
more or less just IDeref
with callbacks
and IDeref
just lets you use @
to get the current state
so its not as if there is some grand abstraction that this can fit under right now
IAtom
IRef is all stuff I don't care about or use often if at all (validators, watches, etc)
I thought they specifically meant IRef - I agree that atom is doable, ref reaches for a lot more
IAtom is the good stuff
I also like IAtom2, the sequel
Apparently IAtom doesn't extend IDeref
oh god the what?
why does this exist
it's for swap-vals, etc.
@emccue clojure interfaces tend to work by composition not inheritence
I did not expect that to be real
The "woulda been nice to have had default methods" interface
anyways
Shopping cart: An online storefront could track a user's shopping cart in an object. The rest of the storefront could be served as a fully static web site. Cloudflare will automatically host the cart object close to the end user, minimizing latency.
Game server: A multiplayer game could track the state of a match in an object, hosted on the edge close to the players.
IoT coordination: Devices within a family's house could coordinate through an object, avoiding the need to talk to distant servers.
Social feeds: Each user could have a Durable Object that aggregates their subscriptions.
Comment/chat widgets: A web site that is otherwise static content can add a comment widget or even a live chat widget on individual articles. Each article would use a separate Durable Object to coordinate. This way the origin server can focus on static content only.
their use cases for this are interesting
its a mix between "per user caching" and "you can emulate live view!"
And I believe also the "go to some lengths to avoid breaking any existing 3rd party code that extended IAtom before" approach.
@andy.fingerhut I don't think adding methods to interfaces breaks Clojure code, only Java I think right?
barring aot
eh, clojure being dynamic means someone has dug into every corner of the internals
and AOT is still considered afaik
it doesn't break java code, it breaks the java compiler
Not sure -- couldn't it break someone who used deftype
to implement IAtom, but not the new methods in IAtom2?
no
@andy.fingerhut I think that keeps working, since you don't have to implement every method
I think you are able to leave off methods and it will just crash at runtime
deftype and the jvm itself are fine with missing methods for interfaces
javac tends to complain
that's what I meant with breaking Java code (for which you typically use javac to compile)
the java is source compatibility and java binary compatibility
I guess it's nice that it's backwards compatible, although I don't know a lot of examples in the wild that implement IAtom in Java. There could be.
Via http://grep.app I found this one: https://github.com/aaronc/freactive.core/blob/master/src/java/freactive/IReactiveAtom.java
They don't have to be open source, of course.
true that
This conversation brings up a common issue I have when thinking about Clojure interfaces β namely, which one do I want and what does it do?
Are there any good resources out there that go over Clojure core protocols and interfaces?
There's this one: https://github.com/Chouser/clojure-classes/blob/master/graph-w-legend.png
@him I did a little bit of hacking in order to generate an updated figure for Clojure 1.10.1 here: https://github.com/jafingerhut/clojure-classes/blob/master/generate/graph-1.10.1.pdf
Awesome! Maybe post in the issue for https://github.com/clojure/clojure-site/issues/17 ?
may be i should print out a poster-size version and put it on my wall π
or we should make a game out of this: given an object, visit all the implemented interfaces as quickly as possible!
lol -- gamification at work i guess :)
this reminds me a bit of: https://gist.github.com/ghoseb/2049970 it was in an old talk by ghoseb
it was about deftype including an example: https://www.youtube.com/watch?v=iBUthApQQw4
I added a comment to to the clojure-site issue here with the latest auto-generated graphs: https://github.com/clojure/clojure-site/issues/17
I did some more hacking on that code, and now there are instructions in the README to generate such a graph from the REPL, but maybe more useful than generating the fairly large graphs that it does by default, is that you can give it a list of one or more classes as input, and it will generate and draw the graph for only those classes and the superclasses (and interfaces they implement), not for all Clojure classes. Smaller graphs can be useful when you want to focus on part of the implementation. You can also use the code from within your own project, in case you want to make drawings for classes outside of Clojure's.
nice!
@him as an exploratory technique, I've looked at (supers (class x))
to see all the clojure interfaces something implements
then look at the methods defined by each interface to see which aspect of its behavior comes from each
Also there's this issue at the clojure-site: https://github.com/clojure/clojure-site/issues/17
I usually just browse the code on github and ascend upwards until I find what I need
There a whole section in Clojure Applied that covers this fyi
(and the ebook will be 40% off over Thanksgiving fyi)
this is the second edition right? I think I only have the first one
there's only one edition
if you've got the 2nd, please send it to me :)
This diagram is great
could probably use an update though π
They arenβt queryable through cljs.repl/doc and apropos right?
Github now has some code navigation features for Java code, which should make navigating through the interfaces a bit easier
http://sr.ht allows you to upload your own :) I've been wanting to write a clojure thing for it that uses kondo to allow navigation of clojure code on http://sr.ht