borar

borar

@borar.bsky.social

83 followers56 following181 posts

borar reposted

Another approach for early returns in #fsharp, but specifically for Async computations: gist.github.com/Savelenko/5e...

gist.github.comAsync with early return capability CE for F#Async with early return capability CE for F#. GitHub Gist: instantly share code, notes, and snippets.
romain-deneau.bsky.social@romain-deneau.bsky.social

C# developers use early return to avoid nesting. #fsharp doesn't have that โ€” so guard logic keeps adding indentation levels. ๐Ÿ“ New article: how a tiny custom computation {} CE brings early exits back, without giving up functional style. ๐Ÿ”— romain-deneau.hashnode.dev/a-real-world...

I think #eventsourcing is a bit of a misnomer resulting in much noise and confusion. I've always used the terms "record" and "journal" and propose "record storing" (RS) instead.

While I understand the good intentions behind such reocurring statements, I am less careful and "politically" balanced: #fsharp is absolutely inherently better. The "needs" are irrelevant, objective properties are what matters in engineering. Just like precise power tools vs manual mediaval tools.

This post is unavailable.

The "needs" are indeed relevant when we deal with different categories of applications: F# is not better for systems or embedded or game programming, Rust, C, etc. are better. But F# and C# are the same category so the "needs" are the same.

Functional programming and its idioms are the most fitting and sensible interpretation/realization of #eventsourcing. Fold multiple composable values of types provided by the layered model, alongside the use-case specific version, apply model logic, store a new record. "Aggregates" are a mistake.

I think I understood the popularity of "modern" as a term. It embodies the implicit and unconcious understanding that most of the (visible online) software industry is a web of ad-hoc, anti-fundamental knowledge, hype-driven, half-assed ideas which break easily. Then its on to the next "modern".

My 5c about this, as always somewhat heretical. "Bounded context" is vague and not really interesting/useful. Vertical slice architecture is not an architecture, but a principle *within* an architecture. In particular, in the Onion architecture (my default). #DDD ๐Ÿ”ฝ

Tomasz Ducin@ducin.dev

Fellow #DDD folks out there, Can someone explain to me what is a _practical_ difference between a vertical slice and a bounded context?

View full thread

Every vertical component has its own data access interfaces (remember, Onion), URL handlers, data access implementation, tests, etc. Vert. components can also share types and functions from "common modules" which are at the "base" of the vert. components. For example the common User type. ๐Ÿ”ฝ

Persistence is also, in general, shared. Some DB tables can be used by multiple components, some are specific to one. With #eventsourcing the journal and the record type is shared.

My 5c about this, as always somewhat heretical. "Bounded context" is vague and not really interesting/useful. Vertical slice architecture is not an architecture, but a principle *within* an architecture. In particular, in the Onion architecture (my default). #DDD ๐Ÿ”ฝ

Tomasz Ducin@ducin.dev

Fellow #DDD folks out there, Can someone explain to me what is a _practical_ difference between a vertical slice and a bounded context?

A vertical slice, which I usually call a vertical component, is a cake piece going through all layers of the Onion. It is a mini application on its own, in a way, focusing on a set of related use-cases. Not too fine-grained, for example all use-cases of user management is one vert. component. ๐Ÿ”ฝ

All use-cases for stock management of scheduling are two other vertical components. Multiple vertical components can have their own models of the same domain notion, tailored at their purpose. A User type appears everywhere, but is more extensive/different in the user management vert. component. ๐Ÿ”ฝ

Only if you are making a fat client and the back-end is merely a thin layer between it and the DB and other infra.

Kilian Valkhof@kilianvalkhof.com

In functional teams, back-end implements for front-end. In dysfunctional teams, front-end implements for back-end.

Maybe thou pure just followeth m, returneth to sanity of m.

gabby@fullmoon.id

I don't know who needs to hear this, but: MaybeT . pure . Just =<< m โ€ฆ is the same thing as: return =<< m โ€ฆ which is the same thing as: m

Working on refining my #eventsourcing design/template for #haskell applications. Using GADTs we can turn on or off optimistic concurrency check using "global" journal versions. Depending on the on/off setting, the "concurrent change detected" outcome becomes impossible and need not be handled.

Streams per entity are fundamentally in conflict with the basic essence of #eventsourcing. The essence being that we can compute *anything* by folding all records. Counter-example: find all customers in a system where each customer has a dedicated journal/stream by customer ID.

By continuing this reasoning, "closing the books" is also fundamentally in conflict with the essence of #eventsourcing. If we "close" a journal with some summary datum D, but need to compute D' one second later or one year later due to nee requirements, the closing was pointless. ๐Ÿ”ฝ

D cannot contain enough information to fold *anything* from the "replacement stream" which comes after the closed stream and new records. Unless D itself is... the complete stream we are closing. Which makes closing trivially absurd. So again, this conflicts with the basic premise of #eventsourcing.

Is the cabal 'data-files' machinery useful for static files needed by a Haskell Web application, for example CSS, JS and similar? What are best practices for "packaging" together the latter and the build product of cabal? A build system on top of cabal? #haskell

Beyond basic programs, HM-like type systems can be quite mysterious and awesome. The definitions and types of the #purescript functions below look strange at the first sight. I wonder how IWSAMs will fare when ported to #fsharp.

Some heated discussions below. I am working with something similar right now. In 2013 I made an in-house message broker at work with my own algorithm for historical + real time event stream generation. We are still using it now. ๐Ÿ”ฝ

Vaughn Vernon@vaughnvernon.bsky.social

This weeks' Design Accelerator: Why I Hate the Outbox Pattern and Why You Should Hate It Too Watch now: youtu.be/3nZLU3b47iU

View full thread

Either implement distributed transactions (actually communication between Windows DT managers) "manually" or provide transactional event logging in some other way. We went with the latter, introducing a new client library with, you guessed it, the outbox mechanism. It works well. End of story.

Some heated discussions below. I am working with something similar right now. In 2013 I made an in-house message broker at work with my own algorithm for historical + real time event stream generation. We are still using it now. ๐Ÿ”ฝ

Vaughn Vernon@vaughnvernon.bsky.social

This weeks' Design Accelerator: Why I Hate the Outbox Pattern and Why You Should Hate It Too Watch now: youtu.be/3nZLU3b47iU

A killer feature was not only "temporal subscriptions" with a stream transparently transitioning from replaying historic data to real-time events, all per subscriber, but also transactional event logging. The broker could participate in the distributed transaction with a source application! ๐Ÿ”ฝ

Very soon after my initial version a colleague extended the broker with multiplex streaming and multiple nodes. This has worked all these years quite well. However, .NET (Core) dropped (good) support for distributed transactions and we were left with a choice. ๐Ÿ”ฝ

Another suspicious property of aggregates is that they (I think) collapse the application and model layers of the application. If an aggregate is essentially the scope/boundary of everything which is allowed to happen (consistently) within a use-case, then it means that the model layer ๐Ÿ”ฝ

View full thread

Next potential problem of aggregates: they discourage proper modeling. Aggregate thinking pushes the programmer to lump together numerous entities (abstractly speaking) just for the sake of "consistency". This means an application often gets a single big en "universal" representation of ๐Ÿ”ฝ

... each domain entity and their related but not intrinsic entities. For example: a person together with thei favorite color, a department necessarily always with all the employees, regardless of the use-case. A component with its price always attached to it, etc. This is anti-modular.

Another suspicious property of aggregates is that they (I think) collapse the application and model layers of the application. If an aggregate is essentially the scope/boundary of everything which is allowed to happen (consistently) within a use-case, then it means that the model layer ๐Ÿ”ฝ

View full thread

Consequently, if each aggregate is essentially a use-case-as-class/object, it is easy to make the mistake of also doing the I/O inside of that object. Which collapses the architecture even further. Commands and domain events are a manifestation of that.

Another suspicious property of aggregates is that they (I think) collapse the application and model layers of the application. If an aggregate is essentially the scope/boundary of everything which is allowed to happen (consistently) within a use-case, then it means that the model layer ๐Ÿ”ฝ

... the model layer implements use-cases instead of the application layer. A model layer should instead be just a library of building blocks, (re)combinable for various use-case. The (re)combination should happen in the application layer, interspersed with I/O (infra).

I am following the Lit tutorial. It is striking how the combination of reactice properties, declarative event listeners and the properties object inside of the web component class are essentially like a Halogen component! #purescript

I studied Web components for the first time and succeeded in using Shoelace with PureScript Halogen. Somehow working with "raw" HTML seems too low-level now, a step forward. #purescript #shoelace