Hacker Newsnew | past | comments | ask | show | jobs | submit | robto's commentslogin

This approach is really appealing to me, and it's similar to how I got my start as a software developer. I had applied for a job and been rejected, but they invited me to apply again in six months. And indeed, in six months I had learned enough and grown enough in to go from a marginal candidate to a good one. I was motivated to do it because it was a career change that had a lot of upside, and knowing that the door was potentially open encouraged me to persist.

Yeah, that's it, is it not? A tiny sliver of real hope in the otherwise blackness of rejection after rejection? If at all one hears back from the company, that is.

But also, sticking with it and making the retry happen---that was all you, robto. Our experience was pretty much that almost no-one we made our office-hours offer to, took it up.

Also, unrelated --- idle.horse --- fun domain! Is it an email carrier only, or does it have a future in public service, as a not so idle blog / site / memex content delivery beast too? :)


This is something I'm very interested in, and I've actually found it very difficult to buy these shapes. Do you have a link to a supplier? I've even approached ceramic studios about getting them custom made, but without any real interest.

Bonus points if you have a supplier for einsteins!


Oh it's been a while since I looked, one of the tile stores I used to go to in Montreal had them -- not as a set mind you, but as two different lines of tiles that happened to be the right proportions to reproduce the pattern.


Seems like it draws a lot of inspiration from EDN. Tagged literals, commas-as-whitespace (and optional), and anything-can-be-a-key are features I sorely miss when I have to go back to JSON.

Don't know how I feel about optional quotes around strings, that seems like a mistake. And having an immutable set literal would be nice as well.


Because I may not be the only one who was confused initially: I think EDN in this instance refers to the data serialization format (Extensible Data Notation) from the Clojure people, not to CBOR-EDN (Extended Diagnostic Notation), which also offers tagged literals and anything-can-be-a-key, IIRC.

Really unfortunate naming


I think the flocking behavior of birds is one of the most entrancing natural phenomena, it's great to see it play out in such an intuitive way here. Is a quadtree generalizable to three dimensions? This looks like so much fun, thank you for sharing, I'm looking forward to playing with this over the holiday.


Quadtrees and octrees are themselves quite deep research areas. If the acceleration data structures interest you, I highly recommend Hanan Samet's book "Foundations of Multidimensional and Metric Data Structures". It's from 2006, but is basically the bible for the field.



And the same approach of just splitting in half in every dimension at each tree level can extend to arbitrary dimension, but usually something else like a kdtree is used instead.


The general algorithm used here (of computing attraction and repulsion forces between pairs of particles) is very similar to that used in simulations of many interesting phenomena in physics. Start with Smoothed Particle Hydrodynamics (https://en.wikipedia.org/wiki/Smoothed-particle_hydrodynamic...) and then check out Lagrangian Vortex Particle Methods and other N-Body problems (https://en.wikipedia.org/wiki/N-body_problem).

And the algorithms to solve these quickly is another deep area of research.


I've been meaning to try this out, from my read it's a declarative way to get some structured concurrency. I work in a codebase that heavily uses core.async channels to manage concurrency and you really need to pay close attention to error handling. When you're spawning new threads you need to set up your own custom machinery to re-throw errors on a chans, close chans, and it looks like core.async.flow is a way to do all of this declaratively.

Just like `core.async` itself was a frontrunner of Virtual Threads on the JVM, I view `core.async.flow` as the Clojure version of the upcoming [0]Structured Concurrency JEP. I do wonder if it will use that under the hood once it becomes stable, the same way `core.async` is planning to move away from the `go` macro to just have it dispatch a virtual thread.

[0]https://openjdk.org/jeps/453


I don't think it would be feasible or wise to structure core.async to use Structured Concurrency, although Structured Concurrency is trying to tackle some of the same problems as flow but in a different way (more akin to data flow style concurrency).


We've been looking at virtual threads in a project at work and what we found is that it is quite difficult to adapt existing code to run with virtual threads.

For example, class initialization pins a thread so any singleton defined in the standard, recommended Java way (using a static inner instance of an inner class) can hang your program forever if the singleton definition suspends. And because they worked really hard on making async colourless, there is no way to know that a method call will suspend. This is a known issue with a workaround if the suspend is due to a network call,

https://bugs.openjdk.org/browse/JDK-8355036

which is useful for some applications (web servers). Figuring out that this is why my program was hanging required quite a bit of work too. We are still frustratingly far from the ergonomics of Go concurrency (all threads are virtual threads, hangs automatically panic).


Clojure's focus on immutable data and pure functions side-step a lot of the trickiest issues with virtual threads. It's often not hard to isolate the I/O parts of your program into flow processes at the edges that can be mapped to the :io pool using virtual threads.


The trickiest problems with VT aren't due to mutability. Mutability is problematic with any kind of concurrent programs.

The difficult problems are execution problems like pinning. There are plenty of existing concurrency libraries on the JVM (Cats Effect, clojure async, Kotlin coroutines, RxJava, quarkus, etc etc). The promise of VT is that you will no longer need those for scheduling and execution of work (whether that's tasks, fibers, coroutines, actors etc.) This only works if you use VTs throughout, not just on IO pools.


> can hang your program forever if the singleton definition suspends

I am no expert on the topic, but this seems like a very edge case scenario, that is not trivial to reproduce on even the linked bug ticket. Do you think it really is that big of an issue?


It's really not hard to reproduce,

- vt1 locks lock1

- vt1 suspends on lock2

- n VTs attempt to initialize a singleton that requires lock1, so they all suspend within pinning class init.

- you release lock2.

- all platform threads are pinned, so vt1 can't run and you hang forever.

There is no lock inversion and progress would have been entirely possible with platform threads, even with just one.

It happened on our system because we have parallel streams that all access the same singleton at the same time, which is fairly easy to do (you have lots of parallelism, you have a map operation that needs a value from your singleton and that's it.)

The solution is to never suspend while in a static block, but it's hard to generalize because... any method may suspend, and there is no way to know that it will because of colourlessness. And also the singleton pattern is common, often involve accessing expensive resources or IO (and suspending) and doing so with class init lock is recommended and common,

https://shipilev.net/blog/2014/safe-public-construction/#_sa...

In our case this involves scala's object {} which is a singleton defined using class init. Kotlin probably works the same way.


Thanks for the reply, I see!

Hopefully it will be solved, similarly to the other pinning issues then! Though wouldn't reserving a few platform threads solve the issue?


I think the RDF standards have produced many useful tools for those that work with graph data. And the W3C is a useful coordination place for new standards like Verifiable Credentials[0] and Decentralized identifiers[1] and JSON Linked Data[2], which are all being used in ActivityPub, Bluesky, and a lot of other decentralizing projects.

[0]https://en.wikipedia.org/wiki/Verifiable_credentials [1]https://en.wikipedia.org/wiki/Decentralized_identifier [2]https://en.wikipedia.org/wiki/JSON-LD


Clojure atoms use STM, though. I've been writing Clojure for almost a decade now, it's not that STM isn't great, it's just that immutable data will carry you a very long way - you just don't need coordinated mutation except in very narrow circumstances. In those circumstances STM is great! I have no complaints. But it just doesn't come up very often.


That’s incorrect. Only refs+dosync use stm. https://clojure.org/reference/refs

Not atoms.

From Hickey’s History of Clojure paper:

“ Taking on the design and implementation of an STM was a lot to add atop designing a programming language. In practice, the STM is rarely needed or used. It is quite common for Clojure programs to use only atoms for state, and even then only one or a handful of atoms in an entire program. But when a program needs coordinated state it really needs it, and without the STM I did not think Clojure would be fully practical.”

https://dl.acm.org/doi/pdf/10.1145/3386321

Atoms do an atomic compare and swap. It’s not the same thing.


Haha, I read The Joy of Clojure way back in 2013 and conflated the different reference types with STM. So thanks for mentioning that, I always thought it weird that you'd need STM for vars and atoms too.

That said, I have never used a ref, nor seen one in use outside of a demo blogpost.


Totally! They are rare. Cheers


PS I agree atoms and stm are both solid though — and that you can go a very long way without touching either!


I would say to the contrary it would come up all the time if the right idioms were in place.

For example, when it comes to concurrent access to a map the Clojure community generally forces a dichotomy, either stick a standard Clojure map in an atom and get fully atomic semantics at the expense of serial write performance or use a Java ConcurrentMap at the expense of inter-key atomicity (or do a more gnarly atom around a map itself containing atoms which gets quite messy quite fast).

Such a stark tradeoff doesn't need to exist! In theory STM gives you exactly the granularity you need where you can access the keys that you need atomicity for and only those keys together while allowing concurrent writes to anything else that doesn't touch those keys (this is exactly how e.g. the stm-containers library for Haskell works that's linked elsewhere).


One of the fun things about Clojure that reinforces this "trivially true" perspective is that maps and sets are functions:

    ;; "maps" the keys to the values
    (map {1 "a" 2 "b"} (take 5 (cycle 1 2))) ;;=> '("a" "b" "a" "b" "a")
    ;; acts as a predicate that tests for membership
    (filter #{"a" "b" "c"} ["a" "b" "c" "d" "e" "f"]) ;;=> '("a" "b" "c")
Once you get used to this idiom you naturally start thing of other functions (or applicative functors) the same way. The syntax sugar makes for some very concise and expressive code too.


I wonder if there's any chance of technology like Verifiable Credentials[0] getting any adoption because of these laws. I think there are legitimate use cases where you would want to say, "hey, some third-party authority can vouch for me that ____", and not reveal to the third party who's asking for verification and not reveal to the party requiring verification any other claim besides the specific one that they need (say, age in this case).

[0]https://en.wikipedia.org/wiki/Verifiable_credentials


What's insane is that, in France, we have France Connect, which is exactly what you describe: a third-party authentication platform maintained by the government.

Lately, a new law just passed to force porn websites to check the age of visitors. I would have been fine with an authentication going through France Connect:

- the gov knows which website you went to, just like your DNS provider would, but it doesn't which content - and the website knows which content you've watched but not who's watching.

Best of both worlds!

But no, we have to send a copy of our ID card to the website, which is INSANE because the website knows WHO you are and WHAT you're watching.


We need this in the US. Otherwise, once laws like this https://apnews.com/article/utah-app-store-age-verification-7... go into effect, 3rd party app stores, like apkmirror.com, etc. are going to need to pull out of the US unless there's a service like that in the country. It's starting with Utah, but many states and even the feds are planning similar laws.


What knock on effects do you see here, for state-led legislation about online privacy? Do we see privacy-conscious vs restrictive US states, and do folks in the (let’s say it, blue) states host US-centric Mullvads? Like out of state abortions.

Going further, how might this effect folks having “freedom is more important than safety” beliefs, given they reside in areas more likely to deny civil liberties-ish rights in the name of family values-ish rights, when this starts to really hit them where it hurts? Everything they do or say online becomes traceable to them, for a notoriously vocal-on-social media set.


It's mind boggling that governments don't offer that service for a lump sum per month


Is the Cybersecurity Fabric an open standard? I didn't see any licenses in the Github repository. Is Tidecloak just an implementation of an open protocol? Or is it entirely proprietary?


Tricky question, because the answer to this will evolve in time (as planned). First, thanks for pointing out the license issue on Github. We'll fix that right away. The Cybersecurity Fabric operates based on the Tide Protocol: our WIP open standard. TideCloak is exactly that: just an implementation of that protocol on a Keycloak IAM. The protocol is "source available" but "commercially restricted" - similar to the BSL modus operandi. It'll take us some time to properly document that protocol to a level adequate for release - but in the meantime, we'll provide office hours and direct interactions with the community to share that knowledge.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: