
Show HN: Connective – Large-scale reactive programming in Javascript/Typescript - lorean_victor
https://connective.dev
======
lorean_victor
ok a bit of background:

I have been working on my off time for some time now to bring reactive
programming to the fore-front of web development, as I think it best captures
the essence of the logic in those domains, which is basically an event/data
flow graph. Current languages and tools are built around the traditional
sequential flow of a program, and this mismatch makes it pretty hard to
properly adopt the paradigm without proper libraries/tooling.

RxJS is one of the best such libraries, though it lacks some essential
features for being properly used at scale:

\- It models the flows with inverse event/data flow trees, which though an
improvement over the sequential flow still limits how larger flows are
described,

\- It does not provide any abstraction for re-use of reactive flows, which is
essential to large-scale codes based on the paradigm (imagine coding without
functions).

CONNECTIVE is a thin library on top of RxJS that addresses those issues. It is
designed to be complementary to RxJS, boosting its flexibility and scalability
without limiting its potential. You can read the following entry on the docs
section for more info about these issues and how CONNECTIVE addresses them:

[https://connective.dev/docs/connective-v-
rxjs](https://connective.dev/docs/connective-v-rxjs)

~~~
paulddraper
I've been using RxJS for a while, but I'm confused about this. I don't doubt
you are correct; I'm just having trouble understanding.

> It models the flows with inverse event/data flow trees, which though an
> improvement over the sequential flow still limits how larger flows are
> described,

What does this mean?

> It does not provide any abstraction for re-use of reactive flows, which is
> essential to large-scale codes based on the paradigm (imagine coding without
> functions).

Isn't this just functions? I pass my Observables as arguments and variables,
and use pipe() to create transforms.

\---

Do you have Connective vs vanilla RxJS example to demonstrate?

With RxJS your hello world is

    
    
        fromEvent(a, 'input').pipe(
          map(() => a.value),
          filter(name => name != 'Donald'),
          map(name => 'hellow ' + name),
        ).subscribe(msg => p.innerHTML = msg);
    

EDIT:

I see you have [https://connective.dev/docs/connective-v-
rxjs](https://connective.dev/docs/connective-v-rxjs)

I will look at that.

~~~
lorean_victor
> Do you have Connective vs vanilla RxJS example to demonstrate?

Yes, you can find them here: [https://connective.dev/docs/connective-v-
rxjs](https://connective.dev/docs/connective-v-rxjs)

> What does this mean?

It means you (typically) have a few observables being transformed into one
(the inverse-tree structure). Reactive flows are in their general-form a
directed graph, which can be described as a composition of multiple trees,
however that description distances the actual logical model and the
description, leading to harder-to-read code.

Additionally, the inverse-tree model of RxJS (mostly) enforces order of fully
defining the flow as well, which limits your ability of organization of larger
reactive flows, specifically across multiple modules (imagine a case where you
need to define the beginning and the end of the flow in one module and the
middle in some other modules, like a typical http server).

> Isn't this just functions? I pass my Observables as arguments and variables,
> and use pipe() to create transforms.

This goes hand-in-hand with the previous question: if all you need to do is to
transform some properly defined observables into one transformation
observable, then yes they are sufficient. On a more general form though, a re-
usable part of a reactive flow would be a sub-graph of a directed graph, which
can have multiple inputs and outputs. You can see examples of this across the
docs, specifically in the link I mentioned above, or these places:

[https://connective.dev/docs/node](https://connective.dev/docs/node)
[https://connective.dev/docs/composition](https://connective.dev/docs/composition)

> With RxJS your hello world is ...

yes naturally in simpler cases where none of the aforementioned apply, there
is no difference in using CONNECTIVE over RxJS. this is why CONNECTIVE does
NOT mask the full API of RxJS.

> I don't doubt you are correct; I'm just having trouble understanding.

Well I might as well be wrong actually, thats the main point of these
discussions and contemplations, so thanks for asking :)

------
iamleppert
The problem with these libraries are significant ramp up time. Unlike what the
authors are claiming it’s not because it’s a difficult or greatly different
mental model to grasp, it’s because the API is clunky and poorly designed.
You’ll notice most of the popular and highly successful abstractions all share
the common trait of being easy and quick to pick up.

It should be a red herring to anyone these days when they see demo code that
looks completely unintuitive which purports to make something easier. If the
author’s haven’t factored in ease of use and uptake it’s already failed at its
first principles.

~~~
lorean_victor
> The problem with these libraries are significant ramp up time. Unlike what
> the authors are claiming it’s not because it’s a difficult or greatly
> different mental model to grasp, it’s because the API is clunky and poorly
> designed.

Regardless of the quality of API design, reactive programming (and by
extension RxJS) does indeed require a different mental model, as it is a
different model for the flow of a program.

> You’ll notice most of the popular and highly successful abstractions all
> share the common trait of being easy and quick to pick up.

That is subjective. I remember how many people found node's async callback
style unintuitive and confusing on first sight, and I personally find (at
least the core abstractions of) RxJS pretty intuitive.

> If the author’s haven’t factored in ease of use and uptake it’s already
> failed at its first principles.

Yes this is part of the goal with CONNECTIVE, to bridge the gap between the
description of a reactive flow (the code) and the most intuitive way to think
about it (a directed graph), so that the end-result would be much more easily
readable and intuitive code. I would love to hear if you have any more
specific feedback on this front.

~~~
karmakaze
I don't believe this is the 'most' intuitive. A spreadsheet is a directed
graph but that's not how people think when they use it--they just write
function expressions.

Svelte 3 does a better job of making it intuitive.

[0] [https://svelte.dev/blog/svelte-3-rethinking-
reactivity](https://svelte.dev/blog/svelte-3-rethinking-reactivity)

~~~
lorean_victor
> Svelte 3 does a better job of making it intuitive.

It might just as well be the case. Svelte is going is towards traditional
reactive programming languages, which for example because of the implicit
change propagation, typically bare the possibility of glitches, which
translates into unreliability on the most basic level of the program. I do not
know how Svelte 3 handles glitches (or change propagation for that matter),
but am just mentioning this as a one of the hurdles of that approach that
actually makes it less intuitive (though definitely it looks more magical).

> A spreadsheet is a directed graph but that's not how people think when they
> use it--they just write function expressions.

That is true, though people also do not utilize spreadsheets to even one
percent of what is possible to do with them, mostly due to the fact that the
representation masks the directed graph and makes it harder for people to
think of a little bit more complex things they can achieve with it. Saying
this as a person who (with a friend) has created a full-blown CRM using google
sheets.

> I don't believe this is the 'most' intuitive.

I can't (and didn't) claim it is either. I just suspect it is a really
intuitive model since it reflects the actuality of what is being programmed.

EDIT: on closer inspection of Svelte 3's implementation of reactivity, it
seems that they are not actually implementing support for reactive
programming, just keeping the DOM reactive to variable changes in a transient
way. This of course means that it will (most probably) not result in glitches,
since its not true reactive programming.

On this front it is notable that:

1) CONNECTIVE (and RxJS) are general-purpose libraries, not just for front-
end, 2) I suspect that mere DOM reactivity of Svelte will also not hold up in
more complex front-end settings, where you would need (and benefit from)
proper reactive logic.

------
namelosw
This reminds me Cycle.js. I would definitely think stream paradigm is very
useful to front-end.

The essential difference in front-end, is the programmer is dealing with
continous, realtime signals, and transform it into the graphical interface.
This is very different from most request/response style back-end. And the
stream is obviously a proper abstraction for modeling this.

However, I found it's tedious to work with RxJS or other stream libraries, not
because the design itself, it's just JavaScript lack of flexible DSL machanism
like macro. If you invent a DSL for a stream flow diagram, you can get a lot
of very neat equations between source and sink, but for JavaScript it's very
hard to abstract away the stream context syntactically.

~~~
lorean_victor
> I would definitely think stream paradigm is very useful to front-end.

I think it is theoretically possible to mostly deprecate VDOM with this
paradigm, leading to better overall performance and control.

> The essential difference in front-end, is the programmer is dealing with
> continous, realtime signals, and transform it into the graphical interface.
> This is very different from most request/response style back-end. And the
> stream is obviously a proper abstraction for modeling this.

Even for the backend though, specifically for concepts like message brokers
(or any similar construct based on application) I would think the paradigm is
quite useful.

> If you invent a DSL for a stream flow diagram, you can get a lot of very
> neat equations between source and sink, but for JavaScript it's very hard to
> abstract away the stream context syntactically.

I personally tend to believe that the ideal DSL (representation) for flow
diagrams is a graph (as it encapsulates both the logical and the execution
flow), which means in the end of the day any textual representation would be
sub-optimal (as any textual representation of any directed graph is sub-
optimal and less intuitive compared to drawing the graph itself).

------
graphememes
My issue with these libraries is the overheads.

\- Steep learning curve for new team members \- More lines of code to do the
same logic chains \- Locked into a libraries way of doing logic chains

You can get the same functionality without the library in less lines of code,
in a clearer functional or OOP way.

Am I missing something? This is much harder to introduce to organizations /
teams.

~~~
lorean_victor
> More lines of code to do the same logic chains

this is typically untrue. the genesis of libraries like RxJS is encapsulating
repeated code responsible for properly handling async
resources/transformations. without them, you would either repeat similar code
everywhere, or end-up writing your own version for the organization. you don't
need to take my word for it though, try replicating some of the examples on
the website (or on learnrxjs.io) to see this for yourself.

> Locked into a libraries way of doing logic chains

this is a valid concern, though the other side of this coin is not using
anything like express, angular, react, etc as they all have the same effect.
the design of such libraries should typically be pretty flexible to be more
facilitating than restricting, and its always a bonus if they are smartly
restricting (discouraging programmers from making mistakes and taking away
cognitive load of making choices that can be mostly decided beforehand, etc).
core concepts of RxJS for example are so basic that there are serious ECMA
proposals to adopt them into the language itself (Observables), much like
Promises before them (which were initially promoted by libraries that are
still around).

> Steep learning curve for new team members

this is specifically true about libraries targeting reactive programming. the
issue is not actually with the libraries but with the paradigm itself, as it
requires a different mental model of the flow of the code. this is part of the
reason CONNECTIVE exists to begin with, to offer an interface reflecting a
more intuitive mental model of reactive flows compared to RxJS, though still
it would be a different mental model compared to traditional synchronous
programming.

this learning curve however is something that I personally believe is
unavoidable in the long run. you already need to adopt it if you want to be
competent at prominent frontend frameworks like React or Angular, the latter
of which incorporates and utilizes RxJS extensively and the former borrows a
lot of the concepts. we already had to go through such a curve with transition
to NodeJS for backend, where before you would mostly write fully sync one-
request at a time instance codes and compensate by paying extra for the
hardware, but now-a-days that extra learning-curve is no longer considered a
deterrent.

------
undoware
I just went away, learned all about RxJS, and then about Connective, and I
think I'm in love.

This is a simple, pure, and elegant way of expressing complex systems. The
site makes a whole lot more sense when you catch up with the reactive paradigm
and see what RxJS does and what Connective provides that it doesn't.

I'll use this for my next project.

~~~
lorean_victor
thanks a lot. if you found any issues and/or had any questions while using
this, there is a gitter chat room where you can ask them:
[https://gitter.im/connectv/community](https://gitter.im/connectv/community)

------
orastor
Not gonna lie I wish we kept politics out of software

~~~
cies
I don't think it is possible. And it's someone's right (freeze peach) to make
a mark on this.

I've love some of the texts books that has small hints of the authors
political attitudes hidden in the examples. It gives character to the work.

Especially in open source I believe this is important to have this freedom.
Companies usually do not openly express political prefs (unless it's widely
accepted, as in gay-pride rainbows when the fight for equality is largely
won). Many opensource projects are not run by corps, but by individuals: and
that individual decide to tag a message to the product he/she delivers.

This has always been done, it's form of activism, and I believe it is a good
thing. Otherwise we would only encounter political statements in the places we
expect it (media, which is largely paid for) and much of us have already
chosen to ignore.

My main point: please do not be dismissive of politics as that only helps the
lobbyists (and the corps/ultra-rich they represent), and at this point we need
to free "our" democracies (means: people rule) from them. Shutting people up
by telling them not to discuss politics is not going to help.

~~~
cies
> I don't think it is possible.

What I meant by this is that choosing an opensource license it to some extend
already a political act.

~~~
lorean_victor
well it used to be, but that battle seems to have been largely won on some
level too, at least all involved parties now realize the value of open-source
(though some may just treat it as a PR asset rather than a platform for
inclusive innovation and progress).

~~~
cies
I mean subtilities like going with a GPLv2 (+ commercial license), LGPLv2/3,
GPLv3, BSD-like, CC0 or WTFPL... Or a combination! There you are already cross
into politics IMHO. You made a statement, to a greater of lesser degree by
choosing one (or more) of the mentioned licenses.

------
maxbendick
It looks like you put a lot of thought into this!

Connective allows users to create graphs between sources and sinks flexibly
(i.e., not only source to sink ala typical RxJS), without needing to worry
about multicasting.

Is this a fair way to describe this library's benefit?

~~~
lorean_victor
the first benefit, yes (although I would say it is already two, the "graph"
and the "flexible connection").

the second one being offering abstractions for re-use of partial graphs.

and it is notable that though CONNECTIVE takes away the worry of multi-casting
in (hopefully) a lot of the cases, it is actually pretty conservative on that
front and will in a number of cases default to not-multicasting, which might
mean that you can get some unexpected behaviors if you are completely unaware
of the concept. the plan is to expand the situations that it will make a good
default decision for you on that front overtime based on how it is actually
used.

EDIT: also thanks, yes as I mentioned somewhere else I actually started doing
this for a super-efficient frontend framework (that effort epically failed),
so I ended up being extra careful about a lot design choices (and to be fair,
carefully delegating a lot of such choices to RxJS as it is a really
brilliantly designed library itself).

------
tkw01536
I was missing an example of an async operation with Connective. Like
fetch()ing something from an API based on a username.

~~~
lorean_victor
you can find one here:
[https://connective.dev/docs/invoke](https://connective.dev/docs/invoke)

it is not featured on the main page since the atomic process is not
essentially different (neither from RxJS nor from any other library you might
want to use to do that, though the ease of just plugging in any other library
for that perhaps is different from RxJS).

------
jehna1
I've been recently using @grammarly/focal for state management and reactive
flow programming.

It also uses rxjs behind the scenes, which I really like has gained some
ground with Angular lately.

~~~
lorean_victor
yes it really is an interesting project in this area as well, though it seems
to be mostly focusing on state-management and binding reactive flows to React
components and leaving the flow programming mostly to RxJS (though I have only
looked at the docs a bit and not used the library so I might be mistaken).
however I feel maybe with recent release of React Hooks popularity of this
library might fall, which is a shame (I definitely like the concepts much
more).

------
swyx
very nice and i wanted to say i appreciate your docs :)

is there a personal “why” story writeup somewhere? i dont have a need for it
but i’d love to learn more about what made you work on this

~~~
lorean_victor
do you mean "why I felt this was needed"? then this link should address your
question: [https://connective.dev/docs/connective-v-
rxjs](https://connective.dev/docs/connective-v-rxjs)

if you mean "how I got to doing this?" well I was thinking of writing a piece
on it, but short story is that I was trying to extend what I was working on
before (connect-platform.com) to front-end in a really efficient manner (as I
realized the paradigm shift on front-end means much less need for constant
performance overhead of mechanisms like VDOM) and hence ended up here.

and about the docs, thanks, I am perhaps going to also independently publish
the code responsible for generating it on github pages as an NPM package
alongside my next project.

------
whsheet
'large scale'

They need an editor for their marketing copy first.

~~~
lorean_victor
yeah its hard to hire people for one-person open-source projects.

~~~
whsheet
No need to get grumpy. The wording I've used is just a bit more polite than
pointing my finger on the one and only maintainer, you, telling his tonality
is totally off and might scare people away.

~~~
lorean_victor
That wasn't intended as a grumpy remark actually, sorry if it came off as
such.

And wait, I thought you were referring the '-' in 'large-scale' not the term
itself ...

~~~
whsheet
All good and sorry, maybe my initial comment was still offending.

However and what I meant is that your writing style, also looking in the
comments here, is for my taste a bit too fluffy, elaborative, zealous and
making it hard for the reader to grasp the essence of your statements quickly.
If you can’t win people with words your lib won’t have the chance get tried.

While I like new takes in frontend, the overall wording was the reason not to
read more about Connective but rather leave a snarky comment.

~~~
lorean_victor
> All good and sorry, maybe my initial comment was still offending.

No seriously I did not find it offensive even one bit.

> While I like new takes in frontend, the overall wording was the reason not
> to read more about Connective but rather leave a snarky comment.

And I'm sorry to hear that. I am aware of this and do consciously try to keep
it as simple and straight-forward as possible, though there is always room for
improvement. It would be really helpful if you could perhaps elaborate a bit
more on this, so I would know better on how and what to fix.

