‹ BackHN Continuity

Thread

Effect 4.0

85 points · 64 comments · stevefan1999

Loading the complete thread in the background. This saved snapshot is available now. Refresh

  1. claude-ai · · focus · HN ↗
    Three clicks, no info what effect 4.0 is, except that it's AI-ready, safe, good, and re-built from the ground up. No idea what it actually is.
    1. verdverm · · focus · HN ↗
      fiber/effects for UI and event bus, eg. OpenCode's opentui and harness are built on this library, been using the 4-beta whilst hakimg on some OpenCode plugins
      1. claude-ai · · focus · HN ↗
        <a href="https:&#x2F;&#x2F;effect.website&#x2F;blog&#x2F;releases&#x2F;effect&#x2F;40" rel="nofollow">https:&#x2F;&#x2F;effect.website&#x2F;blog&#x2F;releases&#x2F;effect&#x2F;40 - nothing about what it is (linked page)

        Click on (docs), first paragraph:

        &gt; Welcome to Effect

        &gt; Effect is a TypeScript library for building production-grade software: typed error handling, structured concurrency, resource safety, and observability, all from one composable core.

        Click on &quot;Play&quot;:

        &gt; import { NodeRuntime } from &quot;@effect&#x2F;platform-node&quot; import { Effect } from &quot;effect&quot; import { DevToolsLayer } from &quot;.&#x2F;DevTools.js&quot;

        const program = Effect.gen(function() { yield Effect.log(&quot;Welcome to the Effect v4 Playground!&quot;) }).pipe(Effect.withSpan(&quot;program&quot;, { attributes: { source: &quot;Playground&quot; } }))

        NodeRuntime.runMain(program.pipe( Effect.provide(DevToolsLayer) ))

        ... and no idea what this is about

    2. slopinthebag · · focus · HN ↗
      it&#x27;s for people who want to write ocaml or rust, but in typescript for some reason
      1. nvme0n1p1 · · focus · HN ↗
        It does seem like they&#x27;re boiling the ocean, for... whatever reason programmers do these things.

        Rebuild JS&#x27;s core data structures: <a href="https:&#x2F;&#x2F;effect.website&#x2F;docs&#x2F;v4&#x2F;api&#x2F;effect&#x2F;Array" rel="nofollow">https:&#x2F;&#x2F;effect.website&#x2F;docs&#x2F;v4&#x2F;api&#x2F;effect&#x2F;Array

        Then rebuild the entire JS ecosystem on top of their custom data structures.

        And then the main heading on their home page is &quot;Reliable TypeScript for the AI era&quot;? Really? I&#x27;ll pass.

        1. maleldil · · focus · HN ↗
          It literally says:

          &gt; Works with JavaScript arrays

          1. nvme0n1p1 · · focus · HN ↗
            Yes but why? Why should I import a giant dependency to do this:

              a = [1, 2, 3];
              foo = effect.Array.append(a, 4);
            
            instead of using what&#x27;s built in to the language?

              a = [1, 2, 3];
              foo = [...a, 4];
            1. slopinthebag · · focus · HN ↗
              did you read the docs? it says

              &quot;Use when you need to guarantee a non-empty result after adding a required trailing value.&quot;

              ...whatever that means lol

              1. spaethnl · · focus · HN ↗
                The types allow you to very narrowly define functions so that you can, for example, require that a NonEmptyArray be passed. This helps to fulfill that requirement without casts.
              2. itishappy · · focus · HN ↗
                NonEmpty is a type that allows you to distinguish between:

                    a = [undefined];
                    res = a.pop() &#x2F;&#x2F; undefined
                
                    a = [];
                    res = a.pop() &#x2F;&#x2F; undefined
                1. skeledrew · · focus · HN ↗
                  As a Python person, that 2nd one looks like a bug. Expecting an exception there. Although also Python doesn&#x27;t have an `undefined`; `None` would have to suffice.
                  1. spaethnl · · focus · HN ↗
                    That 2nd one being a bug is exactly what the type system and NonEmpty types is designed to help prevent.
                    1. skeledrew · · focus · HN ↗
                      Not really. If you try to take something from an empty container (language or real life) then you should get an error&#x2F;issue. The container type doesn&#x27;t change when it&#x27;s empty, and the operation is just senseless; all that&#x27;s happening here is added mental gymnastics that makes code unintuitive to read. Checking if&#x2F;asserting a container isn&#x27;t empty is a straight forward `if cont: ...` or `assert cont` in Python, which anyone can just get.
                      1. itishappy · · focus · HN ↗
                        Right, you can attempt to take and potentially error, but if you already know that taking is possible you can skip the noise and simply return a result. Checking if your container is empty every time you remove an item is not free.
                      2. spaethnl · · focus · HN ↗
                        The type soft-enforces it immediately for everyone though.

                        Without the type there are a few possibilities: 1. I could forget the assertion and have buggy code without realizing. 2. I could ensure that all uses do the assertion. Even if we can statically know that it is empty. This costs us the check for every call of the function, and ends up being more code.

                        Alternatively I could statically know in advance. The code won&#x27;t let me `Array.pop` because that is invalid, so 1. I cannot make that mistake 2. It cost no runtime performance 3. It cost no extra code in a function.

            2. itishappy · · focus · HN ↗
              You wouldn&#x27;t. This isn&#x27;t an array library.
        2. slopinthebag · · focus · HN ↗
          part of it is because js is a throwing language, and since there are no &quot;checked&quot; exceptions they need to basically rebuild the universe in their paradigm.

          but they seem to want to rebuild everything, eg

          &gt; The Console service exposes common console methods such as logging, warnings, errors, groups, counters, tables, and timers. Because console access goes through a service, programs can use custom console implementations in tests or other environments. This module also includes scoped helpers that close console groups or timers automatically.

          yeah idk mate

          1. spaethnl · · focus · HN ↗
            This is super useful though. It allows you to swap out implementations for things like logging and monitoring. Not sure what the confusion is here.
            1. bbg2401 · · focus · HN ↗
              Petty aside: Several JS people I know who were previously quite down on using a dependency injection framework are now seeing the benefits after adopting Effect. The most egregious example being a colleague who considered the adaption of DI tooling to be a language-level defect. It’s now one of his primary selling points for Effect.
              1. slopinthebag · · focus · HN ↗
                i wouldn&#x27;t consider the opinions of people who consider themselves &quot;js people&quot; to be particularly interesting, considering the ultimate state of that ecosystem. i say that as someone who writes js professionally.
            2. slopinthebag · · focus · HN ↗
              you dont need an entire runtime to implement polymorphic console.logging. tbh the fact they want to implement the world to do this is more of an inditement against this approach than anything else
              1. spaethnl · · focus · HN ↗
                It isn&#x27;t a case of wanting to implement the world to do this though.

                Instead, it is a case of the active users of the library saying, &quot;Wow, the Effect way of doing this is so much nicer, can we have everything this way please?&quot;

          2. itishappy · · focus · HN ↗
            Console is the very core of what I expect an effect system to need to reimplement.

            Console is IO and IO is the effect.

            1. slopinthebag · · focus · HN ↗
              seems like bikeshedding to me
              1. ezst · · focus · HN ↗
                Not playing devil&#x27;s advocate or anything, but effect systems go beyond DI: it&#x27;s not just about passing around a capability, but managing its lifecycle in a referentially transparent manner, i.e. monads all the way down. It&#x27;s a real pain, but they set themselves up to bear the burden, so, good for the rest of us I guess?
    3. amelius · · focus · HN ↗
      It&#x27;s made with Npm, which makes me wonder if it&#x27;s really safe ...

      But I only read the news when it comes to npm, so maybe my fear is not justified.

      1. tiagod · · focus · HN ↗
        What do you mean by &quot;made with npm&quot;?
        1. amelius · · focus · HN ↗
          Uses npm for package management.
      2. jazzypants · · focus · HN ↗
        Almost every single JavaScript package is on NPM. Being on NPM does not automatically increase your attack vectors. The vast majority of the npm attacks have been &quot;Supply Chain Attacks&quot;[0] where an upstream dependency is injected with malicious code, then automatically downloaded and executed when users update a package.

        If you look at Effect&#x27;s package.json on GitHub[1], you&#x27;ll see that they have several &quot;devDependencies&quot;, but no regular &quot;dependencies&quot;. That means, unless you are working on the package itself, using it does not require downloading any other packages whatsoever. Thus, Effect is not susceptible to any of the issues that you have read about in the news. The only way malicious code could be transported through the package would be if the maintainers suddenly became evil.

        That being said, I don&#x27;t use Effect and I think it&#x27;s kind of overrated by the FP community. But, I appreciate the ideas behind it, and I felt the need to educate you about your needless fear of any library simply existing on NPM.

        [0] <a href="https:&#x2F;&#x2F;unit42.paloaltonetworks.com&#x2F;monitoring-npm-supply-chain-attacks&#x2F;" rel="nofollow">https:&#x2F;&#x2F;unit42.paloaltonetworks.com&#x2F;monitoring-npm-supply-ch...

        [1] <a href="https:&#x2F;&#x2F;github.com&#x2F;Effect-TS&#x2F;effect&#x2F;blob&#x2F;main&#x2F;package.json" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;Effect-TS&#x2F;effect&#x2F;blob&#x2F;main&#x2F;package.json

    4. spaethnl · · focus · HN ↗

      [dead]

    5. WalterGR · · focus · HN ↗

      [dead]

    6. miguel-muniz · · focus · HN ↗
      Sometimes I use the wayback machine to visit marketing pages before the advent of AI, so I can get a better understanding of what they actually do instead of just a bunch of AI jargon.
    7. vantassell · · focus · HN ↗
      I had the same thought, until I realized the posted link is for their 4.0 release rather than their homepage.

      Their main page makes the product pretty clear.

      <a href="https:&#x2F;&#x2F;effect.website" rel="nofollow">https:&#x2F;&#x2F;effect.website

      1. SwellJoe · · focus · HN ↗

        [dead]

        1. notpushkin · · focus · HN ↗
          I’ve had to click around a bit and I think this is a better summary: <a href="https:&#x2F;&#x2F;effect.website&#x2F;docs&#x2F;v4&#x2F;getting-started&#x2F;why-effect#the-effect-pattern" rel="nofollow">https:&#x2F;&#x2F;effect.website&#x2F;docs&#x2F;v4&#x2F;getting-started&#x2F;why-effect#th...

            import { Effect } from &quot;effect&quot;
            
            const divide = (a: number, b: number): Effect.Effect&lt;number, Error, never&gt; =&gt;
              b === 0
                ? Effect.fail(new Error(&quot;Cannot divide by zero&quot;))
                : Effect.succeed(a &#x2F; b)
            
            Effect.runSync(divide(4, 2)) &#x2F;&#x2F; =&gt; 2
          
          This seems to be similar in spirit to railway oriented programming (see e.g. <a href="https:&#x2F;&#x2F;returns.readthedocs.io&#x2F;en&#x2F;latest&#x2F;pages&#x2F;railway.html" rel="nofollow">https:&#x2F;&#x2F;returns.readthedocs.io&#x2F;en&#x2F;latest&#x2F;pages&#x2F;railway.html), but I’m not 100% confident here.
          1. exceptione · · focus · HN ↗
            [delayed]
            1. notpushkin · · focus · HN ↗
              Kinda like that, but with the error branch having a value too. I think Result is the common name for this monad:

                type Result e v = Ok v | Err e
              
              <a href="https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Result_type" rel="nofollow">https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Result_type
      2. pohl · · focus · HN ↗
        Still can’t tell if it’s a language, library or framework
        1. itishappy · · focus · HN ↗
          Have you tried reading the big bold text at the top of the page?

          &gt; Reliable TypeScript for the AI era

          It is a library.

          1. aand16 · · focus · HN ↗
            You forgot the &#x2F;s
          2. oliwarner · · focus · HN ↗
            I&#x27;m with the sibling. A library for what? UI, backend, graphing, visual effects? What does this replace?
            1. hexasquid · · focus · HN ↗
              &quot;typed error handling, structured concurrency, resource safety, and observability, all from one composable core&quot;
              1. oliwarner · · focus · HN ↗
                Reads like another gem:

                &gt; More over, whenever fluorescent score motion is required it may also be employed in conjunction with a drawn reciprocation Dingle arm to reduce sinusoidal depleneration. The Retro Encabulator has now reached a high level of development and it&#x27;s being successfully used in the operation of Millford Trunions. It&#x27;s available soon wherever Rockwell Automation products are sold.

                1. itishappy · · focus · HN ↗
                  Not understanding something is different from it having no meaning.
                  1. oliwarner · · focus · HN ↗
                    Absolutely, but there&#x27;s so little context offered to derive actual meaning. If you already know, it&#x27;s probably a lot easier.

                    And if multiple people are wondering what something fundamentally is, perhaps it&#x27;s the pitch, not the people.

            2. itishappy · · focus · HN ↗
              A library for effects. Algebraic effects, to be more precise.

              To be fair &quot;algebraic effects&quot; is part of my priors. If you don&#x27;t know what that is those specific words won&#x27;t help you, but the examples should!

          3. Incipient · · focus · HN ↗
            &gt;incredibly simple to build the API and a background worker process with Effect. I get logging, telemetry, error handling, concurrency, API doc generation, and more for free!

            But that can&#x27;t be a library? Must be a framework? (eg more batteries included)

            1. nateb2022 · · focus · HN ↗
              &gt; (eg more batteries included)

              That&#x27;s not the definition of a framework.

              You call a library. A framework calls you.

      3. airstrike · · focus · HN ↗

        [dead]

    8. 14u2c · · focus · HN ↗
      Not only that but the play tab is broken. The default example does not compile in their own playground. And I&#x27;m still not sure what this thing is.
      1. 0x20cowboy · · focus · HN ↗
        It’s got electrolytes.
    9. lenkite · · focus · HN ↗
      It is also has the painful AI generated corpo-speak all over its docs: bla-blah is XXX, not YYY, painfully-repeated ad-nauseam. Would it kill someone to delete this AI tick ?
  2. ruby14 · · focus · HN ↗
    It’s wild how easy it is to build robust systems with Effect.

    I’m working on a little social media web app and it has been so incredibly simple to build the API and a background worker process with Effect. I get logging, telemetry, error handling, concurrency, API doc generation, and more for free!

    I think this library gets somewhat maligned for being complex, which I don’t think is fair for how much it offers given how much more complex a an equivalent solution would be without Effect.

    With v4, I also don’t feel like I am even having to wrestle with TypeScript’s type system at all. I define some basic interfaces for my services and schemas for my data models and everything is just inferred through usage for the most part. It honestly starts to feel like I’m writing JavaScript for the most part.

    This library gets lots of comparisons to functional programming languages&#x2F;libraries, which is fair, but I think someone working in .NET&#x2F;C# would be feel right at home.

  3. 2001zhaozhao · · focus · HN ↗
    Is this like a spring boot for typescript or something like that? Looks kind of interesting
    1. theflyinghorse · · focus · HN ↗
      It&#x27;s like Scala and Spring Boot had a baby and the baby was in typescript. Super solid project great engineers.
  4. sibeliuss · · focus · HN ↗
    It is hard to understand why one would want to introduce this into their codebase given how functional javascript is right away. It lives in the spectrum of rxjs - super powerful, but is it necessary? Can all of those concepts be distilled down into what you would use on the day to day, with less concept density, and just as much functional goodness?
    1. itishappy · · focus · HN ↗
      Try it out! Translate a few of the privatives and then see what happens when you try composing a few different ones.
    2. steve_adams_86 · · focus · HN ↗
      I was skeptical but have come to find it indispensable. I absolutely love it for exhaustive handling of states and corresponding typed errors, schemas, and managing concurrency. It’s possible with other tools, but Effect offers much more than just that. It’s a lot of fun. There’s a learning curve, but once it clicks it’s pretty intuitive. It’s simpler than it looks.

      It has truly led to shipping more robust programs that are easier to debug. I don’t use it everywhere, but I don’t think twice with larger backend projects.

    3. vips7L · · focus · HN ↗
      Rx anything is an absolute nope for me after living in Rx hell for several years. It ruins error handling and stack traces and everything becomes an observable callback
  5. jauntywundrkind · · focus · HN ↗
    I can&#x27;t wait for Rust to someday have something even part way as clear at composing systems.

    Eventually I really hope we see programming languages that lean back in to what Erlang started more. This is a leap, but imo having inbuilt great patterns for system design would look a whole lot like Effect! Systems practically assemble themselves. There&#x27;s great powerful meaningful abstractions under foot.

    The only other meaningful effort I can call out is Clojure, which made a handful of good primitives. That community only really used atoms and defs, less refs (software transactional memory) and agents, is what I&#x27;ve been told.

    1. ezst · · focus · HN ↗
      Why not pick Scala (-native), or OCaml, or…
  6. chrysoprace · · focus · HN ↗
    Is there a way to implement Effect without it becoming a leaky abstraction that takes over your whole app? Presumably you&#x27;d have to create an entire abstraction layer with strict boundaries, such as nestjs does with RxJS Observables, but even that has problems with leaking Observables when you need to hook into the framework&#x27;s lifecycle.
    1. ruby14 · · focus · HN ↗
      Absolutely you can. Every Effect program has to be run via some call to a ‘runX()’ function that accepts your Effect program. And the call-site where you run it is the boundary of your Effect program so you can make your app as much or as little Effect as you want.
    2. ezst · · focus · HN ↗
      Thinking of it abstractly, Effects is a more generic version of the &quot;what color is your function&quot;¹ dilemma, and the way to make this kind of abstraction not &quot;color too much&quot; (i.e. not pollute the core language by wrapping everything in a monad that implements its own parallel runtime with exceptions, asynchrony, …) is an active research topic². Scala is advancing in this area by scoping effects in a manner that&#x27;s not too dissimilar to a generalized version of rust&#x27;s borrow-checker, and I&#x27;m very curious to see how that spans out.

      ¹: <a href="https:&#x2F;&#x2F;journal.stuffwithstuff.com&#x2F;2015&#x2F;02&#x2F;01&#x2F;what-color-is-your-function&#x2F;" rel="nofollow">https:&#x2F;&#x2F;journal.stuffwithstuff.com&#x2F;2015&#x2F;02&#x2F;01&#x2F;what-color-is-...

      ²: <a href="https:&#x2F;&#x2F;www.scala-lang.org&#x2F;api&#x2F;3.5.0&#x2F;docs&#x2F;docs&#x2F;reference&#x2F;experimental&#x2F;cc.html" rel="nofollow">https:&#x2F;&#x2F;www.scala-lang.org&#x2F;api&#x2F;3.5.0&#x2F;docs&#x2F;docs&#x2F;reference&#x2F;exp...

  7. kiliancs · · focus · HN ↗
    Effect is to TypeScript what TypeScript is to Effect. It just pays off. But most of the learning curve or the unfamiliarity with syntax and even concepts goes away with AI. In fact, the same reasons why it makes it good for teams makes it good for AI. When a team member or an agent use the Effect patterns, I know I there is a lot less they could have messed up.

    One issue with Effect is that it&#x27;s hard to intro because it does many things. But it does them well, and it does all of them because only a coherent system can deliver the promise of allowing you to write production-ready TypeScript.

    I&#x27;ll list some things:

    - Effects: how you describe programs. For some people it helps to think of them as promises on steroids. In addition to tracking the return type, they track the types of errors it could fail with, as well as its dependencies (see context&#x2F;layers).

    - Fibers: primitives for concurrency—but most of the time you don&#x27;t have to think about them because the `Effect` methods handle most common scenarios

    - Context&#x2F;Layers: type-safe dependency injection. Have your cake and eat it too. You define context interfaces, use them within effects, and TypeScript forces you provide implementations of those interfaces via layers. Layers can provide more than one context, and can also depend on other layers. Very powerful.

    - Schema: think Zod, but with the concept of codecs (to be fair Zod has this too), which means you define how things encode (e.g. what API takes and responds with) and decode (e.g. what my app works with). I love `Model`, which derives schemas for the API side and repo (db) side, so I can define a domain model declaratively with things like &quot;account number should be replaced with * except the last 4 digits in the API; it should be Redacted (wrapped, can&#x27;t leak to logs etc) within the app logic, and should be encrypted in the database&quot;.

    - Standard library: lots of things that should standard in JS&#x2F;TS and aren&#x27;t, or exist but are not coherent or play well together. When I don&#x27;t use Effect, I have to choose between doing things well or shipping (and suffering the consequences). And I don&#x27;t mean just strings, dates, decimals. I mean also queues, cache, etc.

    - SQL primitives to work with transactions, migrations, queries. There are interfaces on top of this for popular ORMs.

    - HTTP server; and ways to define your API with types and schemas, then implement it.

    - Telemetry, logging by default

    ...and I could go on. I am not looking back.

  8. artisin · · focus · HN ↗
    I was (still am) a huge fan of fp-ts [1], which, in effect, was rolled into the Effect-TS ecosystem. And I&#x27;m still bummed TS+ [2] didn&#x27;t work out, because I&#x27;ve never managed to love Effect-TS the way I loved fp-ts.

    Maybe it&#x27;s the lack of tacit function calling, the conventions, AI&#x2F;modern-marketing push, or simply the daunting scope and scale (even more so with v4).

    Still, despite my gripes, if you&#x27;re willing to spend the time and effort, it&#x27;s the safest and most elegant way to write TypeScript. Plus, it&#x27;s now dependency-free, and the increasingly good LSP&#x2F;editor support removes a lot of the friction that used to come with completions and diagnostics.

    [1] <a href="https:&#x2F;&#x2F;github.com&#x2F;gcanti&#x2F;fp-ts" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;gcanti&#x2F;fp-ts [2] <a href="https:&#x2F;&#x2F;effect.website&#x2F;blog&#x2F;ts-plus-postmortem" rel="nofollow">https:&#x2F;&#x2F;effect.website&#x2F;blog&#x2F;ts-plus-postmortem

  9. steve_adams_86 · · focus · HN ↗
    I’ve been using the beta on three separate projects for quite a while now and it has been totally pain-free. I mostly use the v3x core library (which has expanded to contain other libraries in v4) and Schema so I can’t speak to much outside of those, but I trust they’ve done a great job all around.

    I don’t see it mentioned here, but 4 also comes with a much simpler API in some modules. Schema is much better. It’s an exceptional update. I followed many of the video logs on YouTube and was impressed by the team. This is one of my favourite software projects, period. This rebuild is incredibly well done, and I hope a lot of people are willing to adopt it with the new LTS.

  10. techn00 · · focus · HN ↗
    Effect looks so cool, but the only thing that is off-putting (for me) is the DI. I don&#x27;t even mind the syntax.

    I just don&#x27;t like these DI systems that pull stuff &quot;out of thin air&quot; auto-magically instead of just passing arguments.

    1. kiliancs · · focus · HN ↗
      This was me in the past too. But Effect&#x27;s DI is only advantages, because it is all type safe, including that you _must_ provision the dependency. The result is all the benefits of prop-drilling (explicit) without its problems (now your whole execution tree must learn about this dependency in a leaf).

      Effect&#x27;s type-safe DI simplifies application architecture (you now have a clear algebra that is interfaces + layer composition), promotes important architecture principles (e.g. it&#x27;s a lot easier to compose within the application when components are not tangled because they have to pass &quot;ambient&quot; service props through), and as a result apps are a lot easier to maintain and evolve.

      This is the sort of guardrail that really matters in the age of AI, because AI can still mess things up, but the blast radius of messing things up locally is very different than sloppifying architecture—and makes the problem of slop itself more treatable.

  11. claytongulick · · focus · HN ↗
    I guess I&#x27;m old, and there&#x27;s a lot of grey in my beard but... whatever happened to just, you know, writing code?

    It&#x27;s so pleasant to just write code that does things.

    Code that you can put a breakpoint on to debug.

    Code that doesn&#x27;t go through a library abstraction, a framework, a philosophy, three AI agents and a cross compiler to run.

    I understand that maintainable code needs organization, but I think we go off the rails when the systems of organization dominate the work, and the actual execution logic seems secondary.

    1. kiliancs · · focus · HN ↗
      To me Effect is past those endless cycles and debates. It leaves you in control, and doesn&#x27;t take over, but it gives you primitives that are really needed. Primitives without which you can get by, but you end up paying in correctness, future issues, and reinventing the wheel to solve the problem (often incorrectly). In the JS world, this is one of the reasons we end up with hundreds of dependencies for a small project: besides the actual abstractions, you have all the plumbing between abstractions.

      Effect solves this elegantly.

      &gt; barely any time at all on solving the actual problem

      This is how we should measure things TBH. For me, Effect solves very real problems. As a Principal engineer, I sleep so much better overseeing many teams and agents releasing to production because of Effect.

      &gt; Code that you can put a breakpoint on to debug.

      This is a pain point for sure. For me, the tradeoff is clearly positive (because also the need for debugging that way decreases significantly with more declarative, type-safe, well-architected, telemetry-first code), but it is still very unfortunate.

  12. dantesays · · focus · HN ↗

    [dead]

  13. exceptione · · focus · HN ↗
    [delayed]
    1. itishappy · · focus · HN ↗
      The atom-react module is for interacting with React, and ScopedAtom is for scoping those interactions to specific subtrees, so the entire purpose of this particular example is to avoid passing state through many nested functions. Here&#x27;s the equivalent React code without Effect:

          import { createContext, useContext, useState } from &quot;react&quot;;
          import { renderToStaticMarkup } from &quot;react-dom&#x2F;server&quot;;
      
          const UserContext = createContext(null);
      
          function UserProvider({ value, children }) {
            const [name] = useState(value);
            return &lt;UserContext.Provider value={name}&gt;{children}&lt;&#x2F;UserContext.Provider&gt;;
          }
      
          function UserName() {
            return &lt;span&gt;{useContext(UserContext)}&lt;&#x2F;span&gt;;
          }
      
          function App() {
            return (
              &lt;UserProvider value=&quot;Ada&quot;&gt;
                &lt;UserName &#x2F;&gt;
              &lt;&#x2F;UserProvider&gt;
            );
          }
      
          renderToStaticMarkup(&lt;App &#x2F;&gt;); &#x2F;&#x2F; =&gt; &quot;&lt;span&gt;Ada&lt;&#x2F;span&gt;&quot;
      1. exceptione · · focus · HN ↗
        [delayed]
Open on Hacker News to reply ↗

Unofficial Hacker News client; not affiliated with Y Combinator.