106 karma · joined May 22, 2013
I was looking for something like that and eventually found Crystal (https://crystal-lang.org) as a closest match: LLVM compiled, strong static typing with explicit nulls and very good type inference, stackfull coroutines, channels etc.
IMO the first and foremost principle of Functional Programming languages is that they are optimised around building programs in terms of function composition. And anyone who had to work with borrow checker and closures for 5sec knows, that this is not the case for Rust.
This was a thing around 2 years ago. Nowadays speeds is the same or in favor of Rust, depending on the benchmark in question.
Re. other purpose projects - Yjs/Yrs main target are sequential data structures (text, arrays), but it also has support for maps and xml-like elements. In general you can build most data structures with it. I agree that it would be nice to have some other applications in demos though.
[1] https://docs.yjs.dev/yjs-in-the-wild [2] https://github.com/yjs/yjs-demos
In practice, many CRDT libraries nowadays (eg. Yjs and Automerge) are using structures that don't come with interleaving issues.
Yrs developer here:
- Yjs/Yrs have support for formatting attributes[1]. The matter if format attributes conflict resolution behaves as user desired is a subject to discussion (which is a common thing re. CRDTs and their trade offs), but its behaviour is consistent, convergent and algorithm itself works fast. This feature is in fact used in many rich text editors using Yjs bindings.
- Embedding non-string elements in text is supported as well.
- While syntax trees are not supported out of the box (AFAIK this CRDT is still being researched), Yjs also support XML nodes with attributes and nested children, which may be used for similar effects in some scenarios.
The internals are still very hot and in a state of flux, as we 1st decided to go with porting the Yjs, then leave cleaning and optimizations for 2nd step after we have something, that's compatible with existing Yjs behavior.
AFAIK Facebook created GraphQL specifically for their gateway API - a service used as a facade between internal service mes(s/h) and their client - not for internal ones themselves. That's why things like schema stitching didn't came from FB - they weren't using it in that context.
[1](https://github.com/SyncFree/antidote/blob/842874ca5ecffe947e...)
- OData never got wider adoption outside (and even inside) MS. GraphQL is already adopted on every major platform.
- OData had shitton of documentation and format changes with every version. Backward compatibility not included. GraphQL has clear specification which is pretty stable since its first publication.
- OData queries had no validation. You could send almost every query just to get runtime response that your framework/library doesn't support that functionality - even if it was developed by Microsoft itself. On the contrary all major GraphQL server implementations have full feature support.
- Thanks to Introspection API GraphQL has self-descriptive metadata model, which is great for tooling and compile time query verification. Also versioning, schema and documentation are all included into GraphQL from start.
- And finally GraphQL focuses on exposing capabilities of your service into well defined format understood by frontend, not on exposing subset of your database to the user - like OData did.
- Ruby implementation can dig into Active Record to perform batching of the queries, that normally would be executed in parallel.
- JavaScript implementation may use DataLoader library to support the same batching behavior for basically any async (promise-based) operation. See this presentation, it shows how the issue look like and how Data Loader helps to solve it: https://www.youtube.com/watch?v=c35bj1AT3X8&t=15m42s
- Python and Elixir implementations can make use of information about query subsegments, so you can prefetch necessary data.
- F# implementation works in similar way to Elixir but it's not limited to analyse GraphQL query fragments, but can also perform live analysis of the user-defined resolve functions code to determine a tree of used F# objects and properties instead. This allow to diverge GraphQL domain model from the underlying database model.
- A lot of other libraries are dedicated to particular database or query language and map GraphQL schema directly onto database model, so GQL query is translated directly into underlying database query model (including joins).
How do classes make you nervous? Testing support is one of the strongest parts of akka (see Akka.TestKit) - you can even simulate things like networks delays or VM shutdowns.
> Persistence still confuses me after reading it 5 times.
Yes for people not familiar with concepts of eventsourcing, Akka.Persistence can be enigmatic indeed. But you're not forced to do eventsourcing when using Akka.