HNHacker News
TopNewBestAskShowJobs

lorean_victor

118 karma · joined December 5, 2018

submissionscomments
lorean_victor··on Can we get more decentralised than the Fediverse?
Yes it is a big hurdle. However, I think content discovery is generally a big part of any content platform, way broader than discovering "who have reacted to my content". Now if you want to solve the problem of content discovery in a broader sense, then you have already fixed this particular shortcoming of pull-model as well. If a service that can inform you about new posts with a particular hashtag, it most probably can also tell you about reactions to a particular post.

And yes, I do realise that such services will tend to not be really decentralised (similar to the relationship of websites and search engines). But that means the downside is not that you don't get such discovery, but that you'll be reliant on more centralised services for such discovery, whereas in the fediverse you would be less reliant on such services for finding out who has commented on your post (though it will, as you've mentioned still not be enough).

lorean_victor··on Show HN: Imperative Reactive Programming in JavaScript
[Yeah me too, but nevertheless, I thought this result might be interesting to some people so it doesn't hurt sharing it]

Thanks a lot! Yeah the original idea was from "rxjs-autorun" basically, and I think the idea got subsequently incorporated into SolidJS (if I'm not mistaken). Here basically I wanted to test effect of some additional constraints on the idea, specifically the interaction with async contexts which was missing before, which turned out pretty interesting.

I personally prefer a functional style as well, but time and again have been forced to isolate and heavily explain such FRP code in team projects to accommodate for other teammates who might not feel comfortable with the style. This is why this thread of "flattening" reactive programming into a more imperative style has been fascinating me for quite some time now.

Looking forward to hearing your feedback on how it will turn out in your project!

lorean_victor··on Show HN: React without the magical anti-patterns
An example of using local state is on the first page (the last example). It might seem unfamiliar because it does not use components, and that is simply because "local state" in Callbag-JSX is simply a "local variable" in JavaScript, which can be defined in any scope.

As for components: you are correct, there are no examples of components on the first page. There is one in "Getting Started", but that is a pretty simple one with the state defined outside of the component. That said, "components" in Callbag-JSX are just functions, "stateful components" are functions with closure. Though perhaps I should elaborate on that further.

lorean_victor··on Show HN: React without the magical anti-patterns
For context: this Callbag-JSX, a dead-simple, super predictable front-end library that closely resembles React in style. The core idea is to use explicitly reactive literals (in this case, callbags) and just allow embedding them in DOM (that is described by JSX, hence the name). This means:

- The library doesn't do much. There is no VDOM, DOM reconciliation, etc. Its a JSX-compliant wrapper for DOM APIs, that also supports reactive elements.

- The library is extremely predictable. A component is just a function. It will be called exactly once, when you call it (i.e. when you write <MyComponent/>). You can "use state" anywhere in the code, not just in "Components". There are no weird rules (such as React's hook rules).

- The end result is surprisingly similar to React in style and convenience. That said, some stuff get more explicit. Where in React you would write `{x + y}`, here you need to write `{expr($ => $(x) + $(y))}` because `x` and `y` are now explicitly reactive literals and not plain JS variables.

- Bonus for those who like reactive programming: you can use transforms (such as debounce, throttle, flattening, etc) easily on your states, as all of this comes from an independent specification for reactive literals (callbags specification).

- Also bonus: Since it doesn't do much, Callbag-JSX doesn't have much code and so is faster and more light-weight than Angular or React. That said, if performance is your primary concern, there are other options out there.

lorean_victor··on Show HN: Codedoc: Easily create beautiful docs/wiki for your software projects
Thanks a lot!
lorean_victor··on Show HN: Connective – Large-scale reactive programming in Javascript/Typescript
you can find one here: 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).

lorean_victor··on Show HN: Connective – Large-scale reactive programming in Javascript/Typescript
I fully agree, the (meta) point here being a reflection on the environment where quoting wikipedia's description of a disney character can legitimately feel politically charged and facetious.
lorean_victor··on Show HN: Connective – Large-scale reactive programming in Javascript/Typescript
> 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.

lorean_victor··on Show HN: Connective – Large-scale reactive programming in Javascript/Typescript
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
lorean_victor··on Show HN: Connective – Large-scale reactive programming in Javascript/Typescript
yeah thats an "artistic" choice ;)
lorean_victor··on Show HN: Connective – Large-scale reactive programming in Javascript/Typescript
that is an interesting thought. I have not worked with Rx.NET, whats specific features does `ObsevableCollection<T>` have?
lorean_victor··on Show HN: Connective – Large-scale reactive programming in Javascript/Typescript
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).
lorean_victor··on Show HN: Connective – Large-scale reactive programming in Javascript/Typescript
is this a good thing or a bad thing? like is it "The API looked pretty normal and understandable to me..." or is it like "The API does not seem to have anything special at all, why does this exist"?
lorean_victor··on Show HN: Connective – Large-scale reactive programming in Javascript/Typescript
I would beg to differ. The FRP aspect of a spreadsheet is not the aspect that is widely used. It is actually a pretty uncomfortable one for even many programmers, though for really simple cases it is possible to get used to it. Actually, for example imagine how powerful the extent of the FRP in something like Google sheets is, IF it was such a shining beacon of easy learning curve I would bet that it would be a really popular programming tool for at least organizational automation software, which it is not.
lorean_victor··on Show HN: Connective – Large-scale reactive programming in Javascript/Typescript
Well pipe(), despite being a great extensibility tool, is not a "flow-reuse" abstraction, as it (mostly) just works as a transformer of (mostly) one observable into another. a reactive flow is a directed graph in general and an inverse-tree in RxJS.

of course you can simply re-use parts of the inverse tree using functions from multiple observables to one, and the main issue for this is basically the inverse-tree model limitation, as can be observed in appearance of convention-breaking and uncomfortable pipes such as partition.

lorean_victor··on Show HN: Connective – Large-scale reactive programming in Javascript/Typescript
> 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.

lorean_victor··on Show HN: Connective – Large-scale reactive programming in Javascript/Typescript
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 ...

lorean_victor··on Show HN: Connective – Large-scale reactive programming in Javascript/Typescript
yeah its hard to hire people for one-person open-source projects.
lorean_victor··on Show HN: Connective – Large-scale reactive programming in Javascript/Typescript
> 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).

lorean_victor··on Show HN: Connective – Large-scale reactive programming in Javascript/Typescript
> 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.

lorean_victor··on Show HN: Connective – Large-scale reactive programming in Javascript/Typescript
I also wish we kept politics out of common first names. The Donald referenced here is a mischievous and temperamental white fella (with orange bits here and there) with semi-intelligible speech who most of the time ends up messing what he gets into and thats why we need to keep him out:

https://en.wikipedia.org/wiki/Donald_Duck

lorean_victor··on Show HN: Connective – Large-scale reactive programming in Javascript/Typescript
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).

lorean_victor··on Show HN: Connective – Large-scale reactive programming in Javascript/Typescript
> Do you have Connective vs vanilla RxJS example to demonstrate?

Yes, you can find them here: 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/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 :)

lorean_victor··on Show HN: Connective – Large-scale reactive programming in Javascript/Typescript
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).
lorean_victor··on Show HN: Connective – Large-scale reactive programming in Javascript/Typescript
> 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.

lorean_victor··on Show HN: Connective – Large-scale reactive programming in Javascript/Typescript
do you mean "why I felt this was needed"? then this link should address your question: 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.

lorean_victor··on Show HN: Connective – Large-scale reactive programming in Javascript/Typescript
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

lorean_victor··on The Problem of Async Programming, and a Crazy Idea for Solving It
first off, many thanks for the feedback.

> - Syntax is slower to write. Copying and pasting is a non trivial operation. In order to benefit for the clean representation of the process, you need to spend a good amount of time ordering the boxes around. The representation can be misleading (wires crossing, overlapping boxes)

copying can be made much easier. on these kind of features, we are acting on user feedback to prioritize. but since this one specifically is one that my co-founder has been bugging me since the day he joined, I don't think it'll be too much down the pipeline.

also, automatically re-ordering the boxes to get the flatest version of the graph (which seems to correlate to the "cleanest code") is something on our mind, which would alleviate that issue.

> - Very low density of information per pixel compared to any textual language (if no zoom feature). Any long name that has to be rendered on screen become fugly. Since we tend to order the boxes in a process from left to right, only the equivalent of a single line of code can be represented on the screen at once when displaying the names of variable and functions.

that is partly by design to encourage modularizing. on that front, we have gone for possible overshooting and then slowly tuning towards the optimal point.

> - Functions / sub diagrams generally sit in their own separate window (or worse, file). This discourage making functions, to a degree depending on how good/bad the UI is. Getters and setters in OO visual code are a pain.

is that because of the increased inefficiency of switching between sub-diagrams? if that is the case, thats also a user feedback that has been on our radar for sometime and will probably tend to it soon-ish.

> - Execution order is not guaranteed to be sequential, so no try/catch structure. Error handling has to be explicit. Witch mean dragging along an additional error variable all over the place.

actually it does not need to be sequential for proper error handling. each node in the graph is equipped with its own error-handling, i.e. if an error is somehow thrown during its execution the node will report it properly, which has in many cases led to faster detection of error-sources in the context of the projects we have done with CONNECT up until now. still, admittedly the error-handling system needs to become more robust, and all of this is basically only referring to errors that you wish you would catch and fix during development phase. for errors that should be handled on runtime, yes they need to be somewhat dragged along, which I do not necessarily see as a bad thing, as it forces you to explicitly choose the corner-cases that might occur and need to be handled in runtime. this separation actually helps completely avoid using one big 'try/catch' that would blind you to 'bugs' that should not make it to runtime in the first place.

> - The graph representation doesn't translate well into source control and diff tools.

that is true as mentioned in the article as well. we've tried to make it really human-friendly, however we have plans for further tooling specifically on that front.

> - If you need to fire an arbitrary number of parallel stuff at runtime, you still need a "call this asynchronously" structure.

that is true unfortunately. personally I am still thinking on how to represent such dynamic branching within the graphs without causing more confusion. since this is also a corner case, we have kept it on the drawing board until a proper solution is found.

lorean_victor··on The Problem of Async Programming, and a Crazy Idea for Solving It
ok imagine doB() is a function that loads a record from the database and doD() is for example a password hash matcher (really imperfect example, just trying to get the point across). You might want to use both doB() and doD() in other contexts as well, so basically it is not the case that you would want to execute doD() always after executing doB(), neither is it the case that executing doD() always requires executing doB() beforehand. It just happens that in a specific case you would want to execute doB() and then pass its result to doD().
lorean_victor··on The Problem of Async Programming, and a Crazy Idea for Solving It
The "crazy" label is merely a hint to the inherent resistance of most programmers towards "visual" tools, disregarding them for reasons not-withstanding in this case. yet here it seems like actually the "visual" way is the approach with more fine-control and detailed (and maybe sometimes more complex as you embrace the async nature further). It was by no mean an indicator of any of this being a "new" or "novel" idea.

p.s. while it originally used to be acyclic graphs, I had to relax that constraint due to people's request.

← PreviousPage 2 of 3Next →