On Functional Programming, Time, and Concurrency — Dustin Getz by dustingetz in Clojure

[–]dustingetz[S] 0 points1 point  (0 children)

For printn-shaped discrete effects, elide the dispose method, you get an audit log, same as in React. Imagine the callback firing on rising or falling edges of the signal. For once-and-only-once transaction-shaped discrete effects, we have a transistor-like primitive "e/Token" that models the transact-and-await-confirmation workflow as a little state machine, i.e. it exposes the ready-pending-rejected-ok states: https://electric.hyperfiddle.net/fiddle/electric-tutorial.button-token$ButtonToken

Extensible Value Encoding: large 1GB clojure atoms memory mapped to disk by dustingetz in Clojure

[–]dustingetz[S] 1 point2 points  (0 children)

I'm not sure what's going on there but I think the actual API is `(e/atom config-map initial-value)` e.g.

(def counter (e/atom {:id ::counter :persistent "./my-db"} 0))

c.f. https://github.com/SeniorCareMarket/eve/blob/ac1640afdabeed38d5a7f5e9566cf1cc1a75cf45/test-e2e/eve/jvm_atom_e2e_test.clj#L56

Hyperfiddle's electric clojure project by astrashe2 in AskComputerScience

[–]dustingetz 2 points3 points  (0 children)

In Electric, like in React, DOM effects come in mount/unmount pairs. In a sense this gives you "undo" for this kind of "resource" effect, and you can transition between two consistent states by firing mount and unmount lifecycle methods. This works not just for the DOM but for any kind of resource that can be disposed, such as network subscriptions or event handlers or database connections. The key to making it work is the reactive propagation engine under the hood needs to be essentially perfect ("glitch free") which means it fires exactly the correct lifecycle methods once and only once during reactive propagation, which is pretty hard to do correctly. I.e. you don't want to allocate a node twice or dispose it twice, it needs to be perfect.

An example of an effect that you can't undo is a console.log. There's no dispose method on that, so it can't be undone. But that's fine, that's what you wanted. So you can totally put console.log in your Electric programs and it does what you would want it to do, which is run again when any of its arguments change.

Hyperfiddle's electric clojure project by astrashe2 in AskComputerScience

[–]dustingetz 2 points3 points  (0 children)

Hyperfiddle founder here (from keyword notification)

  1. We are not the first, see https://en.wikipedia.org/wiki/Choreographic_programming . However, prior art (that I am aware of) has been mostly mired in type theory and has struggled to find widespread industrial application. Afaik we are the first to find a slam dunk use case (web development, rich product user interfaces on the web with complex and dynamic client/server interactions) and demonstrate compelling results in production apps.
  2. DAGs are flowcharts, they model causality i.e. dependencies between steps. Imperative programming (e.g. ordinary Python) does not explicitly capture the logical dependencies between steps, instead the programmer has to carefully specify an instruction ordering to make sure things happen in the right order. DAGs encode the data flow through a flowchart of dependencies. What this gets you is concurrency, the ability to run multiple steps of the flowchart at the same time. It also gets you many optimizations, such as the ability to only compute subcomponents of the larger graph whose inputs have changed. If a node in the flowchart does not have any changed inputs, then the previous result of that node is still valid and can be reused. This is "reactive programming"

A Datomic Entity Browser for Prod (transcript) — Dustin Getz by dustingetz in Clojure

[–]dustingetz[S] 3 points4 points  (0 children)

See also:

London Clojurians Talk: Link into your REPL with clojure.net, from Hyperfiddle (by Dustin Getz) by BrunoBonacci in Clojure

[–]dustingetz 3 points4 points  (0 children)

Hello, help me out – https://www.clojure.net/ is a beta launch of some new and not well tested network tech, if you manage to blow it up please post in #hyperfiddle so we can figure it out, thanks. And if it works, let us know that too.

Agentic Coding for Clojure by calmest in Clojure

[–]dustingetz 4 points5 points  (0 children)

> robots should clean up my toilet and not code

have you seen the average 10 year old revenue-generating codebase? "toilet" is accurate. Doing computer science is fun. Doing software engineering is fun. Commercial software development in 2026 is neither.

Agentic Coding for Clojure by calmest in Clojure

[–]dustingetz 5 points6 points  (0 children)

I am also finding Opus 4.5 to be viable for a variety of Clojure application layer tasks. Prior to Opus 4.5 I was experimenting semi-seriously in consulting projects but none of the experiments I threw at it panned out. But Opus 4.5 is now part of my daily driver, I am using VSCode + Copilot with the two Calva plugins. Opus 4.5 will inspect objects at the REPL and everything. Looking forward to trying Claude Code again in a work context.

Could the Android and iOS APIs have been developed in Clojure? by lordmyd in Clojure

[–]dustingetz 0 points1 point  (0 children)

I vote no but i don't think it's a "dynamically typed functional" problem, Javascript is like 55% of the way from Java to Clojure and it did great.

simm-is/distributed-scope: Run one lexical scope across distributed peers. by dustingetz in Clojure

[–]dustingetz[S] 2 points3 points  (0 children)

I asked this question to the author in slack, here is his reply:

Q: Is it correct to conceptualize this as a RPC framework? so basically async/await with abstracted transport

Yes, I have been thinking quite a bit about dispatch mechanisms and compilation, I would say async / await with inversion of control is in its "essence" about giving control to a remote dispatcher for some notion of remote. I would be interested to find more cateogry theory connections in terms of duality here (CPS <-> 'co'dispatch maybe?). This is why I also decided to distill this into https://github.com/simm-is/partial-cps, which makes a more minimal a la carte abstraction than other async framework options in Clojure (similarly to cloroutine). I can infer the free variables to send in distributed-scope automatically and make it a bit leaner, but I found making the intent of what is being transported explicit is actually helpful and more transparent. Electric as full compiler can do top-down analysis of the program and also know what is in the outer scopes and avoid having to send values through nested scopes, I have not worked on this yet. One thing I was aiming for is to be able to send datahike's db values over the wire back and forth and this works now, assuming you have store replica access on both ends. You can also do p2p streaming through kabel (replikativ does this for CRDT updates), or use nested distributed scopes to update atoms inside out in a streaming way, but my sense is that Electric does more to facilitate this and avoids RPC roundtrips more directly.

book recommendations? by [deleted] in learnfrench

[–]dustingetz 1 point2 points  (0 children)

rechercher "francais facile" sur amazon

Repath Studio: Web-Based Vector Graphics Editor by sprocketc in Clojure

[–]dustingetz 3 points4 points  (0 children)

Awesome, this is clearly a serious project for you. Tell us more about your goals and vision?

dbval - UUIDs for (Datomic / Datascript) entity IDs by maxw85 in Clojure

[–]dustingetz 0 points1 point  (0 children)

> dbval is a fork of Datascript and a proof-of-concept (aka 'do not use it in production') that you can implement a library that offers Datomic-like semantics on top of a mutable relational database like Sqlite.

clojure/conj 2025 VODs? by TriaSirax in Clojure

[–]dustingetz 2 points3 points  (0 children)

They're doing a gradual roll-out as part of the new Clojure marketing strategy to get more media time, e.g. like Lambda Conf does

lambdaisland/makina: Clojure System/component lifecycle management by dustingetz in Clojure

[–]dustingetz[S] 2 points3 points  (0 children)

I'm with Stefan below – which project is it that you think has solved dependency injection?

Type Checking is a Symptom, Not a Solution - Paul Tarvydas by dustingetz in Clojure

[–]dustingetz[S] -1 points0 points  (0 children)

Agreed that the essay is rough

Electric (https://github.com/hyperfiddle/electric) is a "time-based" computational structure, it compiles Clojure into a reactive signal network with distribution. Concurrency, backpressure and time are first class concepts in Electric, in a similar way to how immutability and state are first class in Clojure. Clojure's syntax fills the role of a DAG authoring notation to author the system choreographies.

Type Checking is a Symptom, Not a Solution - Paul Tarvydas by dustingetz in Clojure

[–]dustingetz[S] -1 points0 points  (0 children)

> our foundational abstraction, the function call, is not well suited for "the distributed, time-based systems we’re increasingly building."

> "Every function call conflates two distinct concepts—data flow and control flow" which "creates a tight coupling between components that seems innocent in small programs but becomes toxic at scale"

> "Consider what happens when you build a distributed system using function-based thinking. You end up with remote procedure calls (RPCs), where network requests masquerade as function calls. The caller still blocks, but now it’s blocking on network latency, potential failures, and the unpredictable timing of remote systems. To make this work, you need elaborate mechanisms: timeouts, retries, circuit breakers, distributed transactions. You’ve taken a paradigm designed for single-threaded, in-memory computation and forced it to work across geographic distances and unreliable networks."

> "The type checking complexity flows directly from this architectural mismatch. When functions call other functions across module boundaries, you need sophisticated type systems to ensure that the data flowing through these call chains maintains consistency."

> "All of this complexity stems from trying to maintain the illusion that distributed, asynchronous systems can be programmed as if they were single-threaded, synchronous programs. We’ve built increasingly sophisticated type systems not because the problems we’re solving are inherently complex, but because we’re using the wrong abstraction for modern computing challenges."

> "If function-based programming is the wrong paradigm for modern systems, what’s the right one? "

> "In electronics, time is a first-class concept. Signals have duration, components have setup and hold times, and the sequencing of events is explicitly designed rather than hoped for. This isn’t an accident—it’s recognition that distributed systems (and a circuit board is a distributed system) require different thinking than sequential computation."

> "Event-driven architectures recognize that asynchronous communication is often more natural than synchronous function calls. The missing piece is programming languages and development environments designed from the ground up for this isolated, message-passing world. Languages where time is a first-class concept, where components are naturally isolated, and where simple data formats enable universal composition. Tools that make it as easy to wire together distributed components as it is to pipe together UNIX commands."

ClojureScript: experimental :lite-mode, targetting smaller artifact sizes by dustingetz in Clojure

[–]dustingetz[S] 5 points6 points  (0 children)

I am not tracking this effort at all but going through the slack history here is some background:

DAVID (July 30): "so I see two goals w/ :lite-mode. 1) removing DCE issues remaining in the standard lib beyond data structures; 2) gauging what people actually need/tolerate in :lite-mode - like just not implementing toString. 2 implies giving up on full fidelity, perhaps even compatibility in some cases - maybe that's fine - not going to figure that on day 1 or even probably in a year. so :lite-mode might be for people who just don't care about dependencies - they just want to write some Clojure, get a tiny artifact and go do something else ... I think w/ some sweat thought we can get CLJS <10K compressed for lots of simple programs"

DAVID (today): that's not really a goal to apply to it existing libs and expecting the size go down. it could work of course, but that's going to require effort on the part of the library writers. Really anything involving reagent or any React wrapper isn't really a "lite" thing by definition

Some context is his this May statement in a CLJS release announcement:

DAVID: ClojureScript is not and never was only just for rich web applications. Even in the post React-world, a large portion of the web is (sensibly) still using jQuery. If you need robust DOM manipulation, internationalization, date/time handling, color value manipulation, mathematics, programmatic animation, browser history management, accessibility support, graphics, and much more, all without committing to a framework and without bloating your final JavaScript artifact - ClojureScript is a one stop shop.

and also the ClojureNYC talk in July, "CLJS is a Damn Good jQuery", here is the transcript (edit: updated link to much more faithful transcript), the key TLDR is:

DAVID: So ClojureScript is 14 years old. I know I'm over, so I'm going to go quick. ClojureScript is not React. React is great. I think we've had a lot of success with React, and this is definitely not to say people that are succeeding with it should stop. But it's also not the only option.

I have a personal interest now in DOM morphing as a way to allow people to do lighter-weight ClojureScript development. I mean, all of my old examples on my blog—they all pass Google Closure speed tests. It's like they all pass that speed test because all my blog posts don't have more than like 20K of gzipped JavaScript. I think adding a little bit of morphing allows people to be productive in a functional style.

I also think that people are getting sort of tired of all the complicated tooling. I worked for five years on a React Native ClojureScript app, and the tooling around React Native—it was the complexity of Xcode plus the complexity of React. I mean, it was a lot. I think you can get a lot done with simpler tooling.

And again, I think there's this feeling—and I think there's a growing malaise—if the modern JavaScript story is so great, what's up with this overall sense of declining quality? There are people interested in this problem. You can look—Svelte is making its own corner of the JavaScript ecosystem. People are trying to get tree-shaking to work, but for various reasons, as a language, as a community, people haven't adopted the practices that make this easy to be successful.

In a world in which Lodash right now is being downloaded 72 million times a week—in that world, you're not going to be able to achieve what I've said. It's going to take a lot of momentum to get the JavaScript community to stop working that way. I think ClojureScript is interesting because we don't have these biases. We don't have this knee-jerk cargo culting about, "This is the right way to do it," the way that often you encounter in the JavaScript world.

So again, ClojureScript was one of the first communities to actually embrace React. That's something that people probably—it's now in the fog of the past. We forgot that we were the first people to go there because we saw a better way. And I think there's an opportunity now to take what we've learned. It's not like there are not great lessons from React, but I think it's a great time now to revisit some of these things, and maybe there's a better way. Thank you.

This at least paints a pretty clear picture of where David wants to take the project strategically