Adopting Effect at Zendesk with Attila Večerek
#1: Adopting Effect at Zendesk with Attila Večerek
In this episode, Attila Večerek, Tech Lead and Staff Engineer at Zendesk, joins our host Johannes Schickling to discuss how Zendesk incrementally adopted Effect in a polyglot environment with a large codebase.
In this episode, Attila Večerek, Tech Lead & Staff Engineer at Zendesk, joins our host Johannes Schickling to discuss how Zendesk incrementally adopted Effect in a polyglot environment with a large codebase.
Effect is an ecosystem of tools to build production-grade software in TypeScript.
Song: Dosi & Aisake - Cruising [NCS Release]
Music provided by NoCopyrightSounds
Free Download/Stream: http://ncs.io/Cruising
Watch: http://ncs.lnk.to/CruisingAT/youtube
- (00:00) - Intro
- (03:13) - Being an engineer at Zendesk
- (06:05) - Challenging the status quo
- (13:10) - Introducing TypeScript at Zendesk
- (20:22) - Adopting fp-ts
- (25:19) - The transition from fp-ts to Effect
- (31:00) - DX adopting Effect
- (37:15) - Implementing a Kafka consumer with Effect
- (42:18) - Dependency injection
- (48:33) - The power of TypeScript & Effect
- (53:03) - Onboarding developers to Effect at Zendesk
- (01:15:37) - Excitement for Effect Cluster
- (01:19:30) - Outro
Transcript
00:00like the dependency injection,
00:02like dependency management as well.
00:04It's just so great with Effect.
00:07I feel like I'm much more
00:09incentivized to write unit
00:11tests and I don't know how other people
00:13think about engineers at companies like
00:16Zendesk and like Facebook and Google, like big companies
00:21like how they
00:22deal with these things
00:23on a day-to-day basis.
00:24In the end, like it doesn't matter
00:26how skillful or experienced you are.
00:29It comes down to incentives all the time.
00:31Like you do things that you
00:33are more incentivized to do.
00:35So, If a language or a framework or a library
00:39makes something really easy to do,
00:42you will do it regardless, whether it's
00:44the right thing to do
00:45or the wrong thing to do.
00:49Welcome to "Cause & Effect," a podcast
00:52about Effect, the TypeScript library,
00:53and ecosystem helping engineers build
00:56production-ready software.
00:58I'm your host, Johannes Schickling, and I've
01:00been building with
01:01Effect for over four years.
01:03With this podcast, I want to help others
01:05understand the benefits
01:07and powers of using Effect.
01:09In this episode, I'm talking to Attila
01:11Večerek, a tech lead at Zendesk
01:14and long-term user of Effect.
01:16In this conversation, we talk about the
01:18challenges of building production-grade
01:19software in TypeScript
01:21and how Zendesk ended up adopting Effect
01:23in one of their main products,
01:25serving millions of users every day.
01:28Let's get into it.
01:29Welcome Attila to the very first episode
01:32of the Cause & Effect Podcast.
01:34How are you doing?
01:36Thank you.
01:37Thank you, Johannes.
01:37I'm so happy to be here.
01:39Uh, I'm doing pretty well.
01:40Thank you.
01:41How about you?
01:42I'm doing fantastic.
01:43Really looking forward to doing
01:45this podcast and to
01:46do it together with you
01:47since I think we've been in
01:49touch now for quite a while.
01:50We met like half a year ago, also
01:53for the first time in person at the
01:55first Effect Conference in Vienna.
01:58And yeah, really excited to do this
02:00together and share more
02:02your story of like
02:03discovering Effect and using Effect.
02:05So you're using Effect at Zendesk, but
02:08would you mind giving a quick
02:10introduction of who you are?
02:13What is your role at Zendesk?
02:14What have you done before?
02:16And then we can dive deeper.
02:19Sure thing.
02:19Hey everyone.
02:20My name is Attila, Attila Večerek and
02:22I've been at Zendesk
02:25for almost seven years.
02:26It's going to be seven years
02:27exactly this year in October.
02:29Currently I'm a tech lead at a
02:32team in the Guide organization, which
02:35is responsible for the
02:38help center part of Zendesk.
02:41So, if you see any help center
02:43articles or community
02:45and stuff like that,
02:47that's, that's what I do.
02:48And most recently I also got the
02:51responsibility of re-vamping
02:53our customer satisfaction feature.
02:55which is one of our most used
02:57features besides like the core product,
02:59which is ticketing itself.
03:01And yeah, I'm very excited about that.
03:03And that's actually the feature
03:05which is built using Effect.
03:08That sounds awesome.
03:09Yeah.
03:09I'm excited to hear more about that and
03:11go in depth, but would you
03:13mind describing a bit more of, given
03:15that, there are, I think,
03:17several thousands of engineers at Zendesk
03:19and not all code there is written
03:22with Effect, that might change at
03:24some point, but would you mind giving
03:27a quick overview of, what it means to
03:30be an engineer at Zendesk?
03:31So Zendesk is really large, we
03:34have many sub orgs and, or
03:37departments and each of them, even at the
03:40team level, like there are huge
03:41differences, we're truly a polyglot
03:44company when it comes to languages
03:46and different kinds of tech stacks.
03:48I still think most of our code is
03:51still written in Ruby.
03:53The company started with
03:54Ruby and Ruby on Rails specifically.
03:57We have two large Ruby monoliths.
04:00both of them I have to
04:01interact with from time to time.
04:03That's, that's always
04:03an interesting
04:05experience, especially
04:06when you've been working with Effect
04:08for a while and then you have to go back
04:10to Ruby and like, Oh, okay.
04:12Things are a little bit different here.
04:14But besides Ruby, there's also like a
04:16ton of Java, some Scala, some
04:20Golang, yeah, and obviously
04:22TypeScript mostly for
04:23front-end, but, we
04:24have also some companies that we acquired
04:27who brought in a lot
04:28of backend TypeScript.
04:30And yeah, we have some, some of the
04:32TypeScript on the
04:33backend in Guide as well.
04:36So it sounds like Ruby has always
04:39been the majority of code and still is.
04:42Is there any technology, any
04:43language that you feel like is really,
04:46on its way in and might replace Ruby
04:49as the primary
04:49language maybe at some point?
04:51That's really hard to tell.
04:52I don't think Ruby will go away ever.
04:56These huge monoliths, they're here to
04:59stay with us for
05:00until Zendesk will exist.
05:02I'm pretty sure of that.
05:04We had some initial thoughts of breaking
05:07the monoliths down, but it's really
05:09hard to justify these efforts, when
05:11it comes to product and, and like the
05:14business needs of the company.
05:16So for all the startups out there,
05:19like if you start with a technology
05:21and you become like large company and
05:23really largely successful, all the
05:26tech that, that you accumulate for all
05:28those years, that's going to probably
05:29stay there for, for a while.
05:31So yeah, maybe, maybe think about twice
05:34about what you start with.
05:36Not all this tiny decisions, but like the
05:38major ones, it's, it's good
05:39to put some thought into it.
05:41Oh yeah, for sure.
05:42But I mean, Zendesk is a very,
05:45profitable and very great company.
05:48So I suppose it wasn't
05:49the worst stack decision.
05:51If it led Zendesk to this point
05:53today and given that you, are also
05:57now leaning more into TypeScript, I think
06:00there there's, you can probably use the
06:02best tools for the appropriate jobs.
06:05But speaking of TypeScript, I think this
06:07is one example of like a theme
06:10that I'm noticing, which is that you seem
06:12to challenge the status quo a bit.
06:15when it comes to engineering
06:16within Zendesk where you see, okay,
06:19this is how things are done.
06:20And then, you seem to, send some
06:23ways to do things possibly better.
06:26And this is, I think we're using some
06:28colleagues, if I understood
06:29correctly have, at some point looked
06:32at TypeScript and said, actually,
06:34this is a bet worth making.
06:36Can you share that anecdote?
06:37Yeah, sure thing.
06:38So maybe just to understand for maybe
06:41people who are not familiar
06:42with Ruby on Rails, Ruby is a
06:44dynamic programming language.
06:46It's great for really one
06:49engineer or tiny teams that know the code
06:53base by heart, it makes
06:55them really efficient.
06:56So productivity wise,
06:57it's, it's terrific.
06:59So starting with Ruby for Zendesk was
07:01definitely a good bet.
07:03It allowed them to have like a
07:05velocity in the beginning that was
07:07absolutely crucial to become successful.
07:10But you know, working with a dynamic
07:13type language, especially like
07:16with a heavy OOP focus where you have
07:19lots of like design patterns.
07:22I'm not sure if you have worked with
07:24teams where people would argue
07:26like, Oh, you know what, for this
07:28feature, we should
07:29use this design pattern.
07:31And then the other side would be arguing,
07:33no, no, no, uh, look at,
07:35switch your mentality.
07:36Like, you have to look at the problem
07:38this way and then they
07:39bring up adapters and whatnot.
07:41And DDD and all these things.
07:43At a certain scale, it becomes fighting
07:46an uphill battle all the time because you
07:49have to be fully aligned with all
07:51the people who work on the code base.
07:54You have to agree on these things.
07:56Like what are the design
07:57patterns that we are introducing?
07:58Okay.
07:59Are we shifting to a
08:00different design pattern?
08:01Are we re-architecting
08:02redesigning our modules?
08:04Are we taking out and
08:06extracting reusable modules?
08:08And how do we do that?
08:10Are we doing some, you know, some
08:12module boundaries within rails and
08:14use rails engines or some other ways of
08:16enforcing these module boundaries?
08:18So all of these decisions, like you
08:20really have to pull the same rope in the
08:23same direction and then it's good.
08:25But at some point, now let's say you have
08:27this huge monolith, which we have,
08:29and you have 50 people or even hundreds
08:31and thousands of
08:32people contributing to it.
08:34Having this alignment across the
08:36entire organization is really hard.
08:39So what you end up having is a mixed bag
08:42of things and, you know, parts of
08:44the repo, use one design better.
08:47Another part uses another one.
08:49And then there's this new design better
08:51that you're pushing for some
08:52modularization and
08:54then that's a migration.
08:56And then there's tons of migrations going
08:58on at all time, like five, 10, 15
09:02different types of
09:03migrations in a code base.
09:04And then let's say you're a contributor
09:06who just wants to implement like a tiny
09:09bit of a feature, which is necessary in
09:11that repo so that the other service can
09:15communicate with it.
09:16I don't know.
09:16You, let's say you want to emit some
09:18events from
09:19the main monolith and then over
09:21Kafka or over whatever message bus so
09:24that you can consume
09:25those events in your microservice.
09:28Well, suddenly you'll see five or six
09:30different examples of how to emit
09:32domain events, or Kafka.
09:34So what do you do then?
09:36How do you find the people, that know
09:39what's the current status quo, or
09:42will you just blindly pick the one that
09:45is the most prominent?
09:46I mean, that's, there's no problem going
09:48with that route either, because if it's
09:51the most prominent thing and let's say
09:53it's something that
09:53we're moving away from.
09:55You can just commit to that and it will
09:57be moved away from with the rest.
09:59But then, you know, if you pick something
10:01in between, then that also brings the
10:03risks that the people who are doing that
10:05migration will just
10:07have bigger and bigger
10:08headaches because now they need to
10:10migrate different kinds of ways of doing
10:13things into this one,
10:14one way of doing thing.
10:15so these are the biggest problems
10:17that I see with Ruby, alignment,
10:20constantly fighting an uphill battle.
10:23You introduce a new feature, but at the
10:25same time you introduce a bug because
10:27you miss something and there's constant
10:29action at the distance.
10:30You change one part of the application,
10:33which has some
10:33unforeseen or unpredictable
10:35effects on another part of the
10:37application because
10:39everything is reusing everything.
10:41That makes a lot of sense.
10:42So it rather sounds like you're,
10:45you're running into some like social
10:47alignment issues where you just have so
10:50many engineers, like an all probably very
10:52brilliant and with like the best
10:54intentions trying to design it with their
10:57understanding of the world.
10:58But if you have thousands of engineers,
11:00this can lead to some, some very wild
11:04different directions and to enforce that
11:06alignment, I think if
11:08you're, if you don't
11:09have a types type system at your
11:11disposal to help with
11:13that, to be even aware of
11:15like, Hey, here's like some divergence.
11:17We're unopigniated maybe, or we
11:19tolerate both, but even to have some
11:21visibility into this and
11:23help drive the alignment.
11:25I think this is where a
11:27type system can help a lot.
11:28And I suppose that is what's what has
11:30made you so interested in TypeScript.
11:33Yes, absolutely.
11:35So that, that was one of the biggest
11:36driving forces behind the
11:38adoption of some language
11:40that is statically typed.
11:42it has tons of
11:43benefits, not just like this alignment.
11:45Very recently, I just actually had to
11:47go into one of these large Ruby
11:49monoliths and there's a feature flag
11:52that I introduced and some different
11:54behavior for when the feature flag
11:56is enabled and now this feature flag has
11:59been rolled out fully
12:00for, for some months now.
12:03So I was looking into removing the,
12:06if.else branch for the feature flag
12:09to keep only the logic that's basically
12:12used now that it's fully rolled
12:14out and by removing that one line of
12:17code, I broke like
12:19hundreds of unit tests.
12:21Because the unit tests had no idea that
12:24there was like a dependency on some HTTP
12:28call somewhere down the line.
12:30So now I have to find like a place where
12:32I can maybe permanently mock this call to
12:37a specific endpoint for all the
12:39tests forever, because I
12:41cannot pinpoint like the
12:42hundreds of different places
12:44where this is exactly called.
12:46So I have to mock it
12:47like on a general level.
12:49So, so these are also kinds of issues
12:51that you bump into
12:52and using languages and
12:54frameworks like this which is going
12:56to be another segway into Effect, I guess,
12:58later on with the
13:00dependency injection.
13:01Yeah, most certainly.
13:03So it sounds like you're building
13:05production grade software at scale at
13:09Zendesk in many different flavors,
13:12many different technologies, but at some
13:14point you've introduced TypeScript and
13:17that's the foundation for the services
13:19and products you're building.
13:21What was that that journey like?
13:24So you now have a type system to help
13:26with many things, but I suppose it still
13:29has not given you the silver bullet that
13:32makes it super easy to build production
13:34grade software.
13:36So what are some of the challenges you
13:38were still facing and possibly still
13:40face today and were
13:41you reaching for Effect?
13:43So if I have to reflect back on the
13:45time when we were introducing TypeScript
13:47at guide for the first time, I think
13:49obviously what we wanted to avoid where
13:51all of these problems that come with, uh,
13:53shared monoliths. We just wanted some
13:56some service, which is nicely isolated
13:58and we have our own
14:00deployment schedule, which
14:02is basically on demand.
14:03We don't need to deploy it on a
14:05weekly or biweekly cycles.
14:08And then of course the maintenance,
14:09improvements,
14:10because now you have a type
14:11system, so if you make a change in one
14:13place, the compiler
14:15will aid you in updating
14:18all the other call sites.
14:20So that, that was
14:21obviously one thing.
14:22But we also wanted to make sure that
14:25we don't get into these like reliability
14:27issues that we were having with the box.
14:29So like type safety was
14:31really important for us.
14:33Then we're looking into how to, because
14:36there are many different ways how you can
14:38write TypeScript, right?
14:39Like you can be really
14:40lenient and allow any.
14:41Right.
14:42You can typecast here and there.
14:45The language is quite flexible.
14:47You can use as much type safety as
14:49you want, or you can
14:51go towards the other end
14:52of the spectrum and use like the most
14:55brutal compiler
14:57options that are out there
14:59and make it super, super type safe.
15:02And then you even start thinking about,
15:04okay, how do we do
15:04end to end type safety?
15:06Right.
15:06Because there are certain things that
15:08come out of your system.
15:10Like on these boundaries of your system,
15:12you have a HTTP request coming in.
15:15Maybe HTTP request going out.
15:17Kafka message coming in.
15:19Like you need to parse these and at
15:22the inbound of your system, you have to
15:26be able to work with
15:27it with a static type.
15:29Right.
15:30So, so how do you do all of these things?
15:32Rolling it manually is really tedious
15:34with all the type checks at runtime.
15:38Especially if you have like really
15:39complex objects it
15:41is really hard to do that.
15:43So obviously you can compose like start
15:45at the leaves and then
15:46build up all of these,
15:47but that's a lot of work.
15:48So we started looking into other,
15:51like maybe even, even other programming
15:54paradigms like with, with Ruby, like of
15:56course there's like a
15:57ton of OOP stuff, but
15:59then with TypeScript, we were realizing,
16:01oh, okay, maybe we can actually leverage
16:04like, some functional programming
16:05concepts to build
16:07more composable software.
16:09Because one TypeScript
16:10service was not our goal.
16:13We were already thinking in multiple
16:15TypeScript services and in the end it did
16:17become reality and then we wanted to
16:19share code in between them.
16:21And then how do you do that?
16:22Well, we came up with a mono repo of
16:26different libraries that we can use that
16:29implement like Zendesk concerns, things
16:32like sharded database
16:33clients that know how to
16:35connect to our sharded database and yeah,
16:39many, many other
16:40libraries like this, these
16:42internal ones, these
16:43productivity booster ones.
16:44So we started implementing those and then
16:47we're like, okay, but
16:48they are like different
16:49libraries like suddenly they have this
16:52library has this API.
16:53This library has another one.
16:54I want to use them in combination.
16:56And then you think about how to
16:58hype all the APIs
16:59in the way that they
17:00nicely flow.
17:02So that's when one of my colleagues found
17:04fp-ts and that sounded really great.
17:07Obviously it had a huge
17:08learning curve for us.
17:10None of us were really much into
17:12functional programming.
17:13I only remembered some stuff from
17:15university, but definitely
17:17have it, haven't had like
17:19hands-on experience and then learning fp-ts
17:22like people who
17:23learned it, they probably
17:24know how hard it is because you don't
17:27have like real documentation.
17:29You have like API
17:30interface documentation.
17:32What gave you the confidence to take the
17:35leap of faith to go
17:36to reach for fp-ts and
17:38make that the
17:39foundation for your libraries?
17:41Um, desperation.
17:44I don't know.
17:46I was just really, I think we all just
17:48wanted to avoid another monolith.
17:52And obviously we, we cared a lot about
17:55these tiny libraries
17:57that were meant to be
17:58shared across the different services and
18:00different services need to do different
18:03things, right?
18:04Like they're in a different domain. So it's really hard to
18:06predict what API is the right one.
18:09So as long as we can stick to something
18:11and make it
18:11composable, that should work for
18:15most of the cases.
18:16I mean, that was at least our idea.
18:18The execution was rough.
18:21We were iterating
18:22on this group of
18:23libraries and we followed,
18:25versioning a strategy that would version each library.
18:30At the same time.
18:31So even if we make a change in one
18:32library, we would bump
18:33the version of all the
18:35libraries just to make it easier for the
18:38consumers to understand what version of
18:40one library works with another.
18:41So we opted for this and then the
18:45iteration was so fast on these APIs.
18:48We just kept in introducing breaking
18:50changes all the time because we
18:51discovered new and new ways
18:54of using these libraries.
18:58And so within the span of three years, I
19:00think we went from
19:01version zero to version
19:0327. Our consumers were
19:05not happy about this.
19:06Let's just say this. Right.
19:09So I suppose fp-ts at that point was
19:11already quite the pill to swallow for
19:14you all where you convinced yourself to
19:16do it, but then to have other API
19:18consumers that did not intentionally say
19:21like, yes, we want to bring in fp-ts
19:23into our life, but that's just the way
19:25how you offered it to them.
19:28That was probably even, even trickier.
19:31So, but that's what you started out with.
19:33And I suppose you, you chose that for
19:35the, for very
19:36understandable reasons, such
19:38as the dream of composability and code
19:41reuse and making all your systems more
19:45resilient, but it came at a price of
19:48like a rather esoteric flavor,
19:50particularly for the ones who were not
19:54getting up in the morning saying, yes,
19:56I want to do functional programming, but
19:58you just want to do proper programming,
20:01uh, maybe in TypeScript.
20:03So, and if I understand correctly, this
20:06is where you have been kind of like
20:09running into growing pains of fp-ts and
20:12building larger systems out of this.
20:14And at some point you found Effect.
20:18So tell me about that.
20:19Oh yeah.
20:20So that, yes.
20:22So basically with this fp-ts we
20:24were trying to build
20:25something similar to Effect.
20:27We wanted to have a system which allowed
20:30our consumers to
20:32do proper dependency
20:33injection with all the config that we
20:36provided so that when they start their
20:38program, like if the config is wrong, it
20:41will just not deploy.
20:43We want it to eliminate as
20:45many foot guns as possible.
20:47Obviously resource management was
20:49another big thing that
20:50we were looking into.
20:51Like how do you properly handle like all
20:54the interrupt signals coming from
20:56Kubernetes when it's trying to kill
20:59or restart your container.
21:00These things.
21:02They require a lot of effort and they're
21:06not easy things to do, especially if you
21:08want highly composable solution.
21:11So I think one of my colleagues,
21:13was my partner in crime when it came
21:16to introducing fp-ts to the
21:20organization at
21:20large, he found Effect.
21:23I don't know how he found it, but he
21:24found it and it was maybe in 2021.
21:28I don't remember.
21:29I'm so bad with years, especially because
21:31it was like the pandemic there.
21:33And suddenly like two
21:35years felt like one or half.
21:40But around the time, it was weird.
21:43Time flow flew, flew differently.
21:46But he did found it and it wasn't
21:48like we were jumping on it immediately
21:50because at the time there wasn't really
21:54such a huge buzz around it.
21:56Like it is nowadays.
21:58Also
21:58didn't have a stable API.
22:02So we were for about at least a year, we
22:05were mostly observing Effect from the
22:06sidelines, we didn't talk to also no
22:08documentation at that point yet.
22:11Yeah, exactly.
22:12It was just another fp-ts for us
22:15from the sidelines looking at it, but
22:17it looked way better than fp-ts it
22:20looked like, okay, this is not just
22:23abstractions, this is
22:24also some implementation.
22:26Finally, something that
22:27makes our lives easier.
22:29It's like a general programming
22:30framework, how to build like resilient
22:32services and all the dependency injection
22:37resource management,
22:39configuration management,
22:41building the layers of dependencies.
22:43That's all taken care of for you.
22:45So, so that looked really promising.
22:49And as I mentioned, like for a year, we
22:51were just looking and watching,
22:53Effect and its development.
22:55And then later when it felt like, okay,
22:58now, now it seems like it's, it's
22:59like stabilizing
23:00around some sort of an API.
23:03We still don't really agree with some
23:05namings, of some concepts, which
23:08then also changed name and everything.
23:10And now it's like much, much better.
23:12But we were, that that's, that's when
23:14we started to seriously
23:16consider adopting
23:17it on some, some project.
23:20We didn't really know
23:21which project should it be.
23:22We didn't really want to go right into
23:25the migration of an existing fp-ts
23:27project, because we
23:28didn't know how to do it.
23:30It was a little bit weird because
23:32from fp-ts we had all these reader
23:34task, eithers, and we, we could
23:37intuitively see how it would map to an
23:39Effect, but we didn't quite understand
23:41how, how it would work with our flavor
23:45of fp-ts if you know what I mean?
23:47Like we built those abstractions for
23:49managing dependencies and
23:52resources and whatnot.
23:54Like how would that, how would we make
23:55the step from that to Effect?
23:58So what we ended up doing in the end, my
24:01team got this opportunity to rebuild
24:04the existing customer satisfaction
24:06feature and we are making
24:08it like more flexible, like it's almost
24:11on our end in the backend,
24:13we treat these customers satisfaction
24:15surveys as, as generic surveys,
24:18because like, what is the customer
24:19satisfaction survey?
24:20It's like you ask a bunch of questions
24:22and one question has to be how satisfied
24:25you are about whatever you're measuring
24:28against in our case, like satisfaction
24:30about how your ticket was
24:32handled by the support agent.
24:33But in the end, it's just a survey.
24:35It's a bunch of questions and different
24:37types of questions and whatnot.
24:38So it looked like a perfect opportunity
24:41for us to try Effect.
24:44Especially because there were, there
24:46was already like Tim Smart's
24:48SQL package, SQL effect, which is like
24:51the predecessor of effect SQL.
24:53So that, that was really good because our
24:55service needs to,
24:57interact with the database for sure.
24:59So, so that, that gave me
25:00a lot of confidence there.
25:02obviously, and now
25:03we're using Effect SQL.
25:04I'm trying to like being lockstep
25:08with all the development
25:09with Effect itself, the core
25:12library, and then also like all the
25:14satellites that the level
25:16one and layer one abstractions.
25:19So it sounded like this was like the
25:21initial prototype where you gave Effect
25:24or like the initial trial project where
25:26you went from observing the Effect
25:29development to actually getting your
25:31hands dirty and seeing, okay, is this
25:34fulfilling all of our dreams, how
25:36our world already got better through
25:38fp-ts but we've introduced a couple of
25:40like new problems and maybe some of our
25:42teammates or some of the other teams, uh,
25:45have a hard time with it.
25:46And that could be addressed by Effect.
25:48And so now you've adopted it.
25:50How did that go?
25:50How quickly were you up and running?
25:52How quickly were you productive?
25:54And, uh, also very
25:56importantly, what did other teams think?
25:59So before I actually get into that, let
26:01me just tell you that for us getting rid
26:05of fp-ts or moving towards something else
26:07is, was existential.
26:09Like there was no universe where we would
26:12be able to push for fp-ts, at
26:15least in our usage of fp-ts in a way we
26:19did at a larger scale.
26:21Like if we wanted this TypeScript service
26:23framework to fly and be useful for not
26:27just our two teams that used it, but also
26:30outside of our org for all the TypeScript
26:33native teams, who we acquired
26:35through the business deals and stuff.
26:37We really had to get rid of it.
26:38We had to find like an alternative and
26:40unfortunately there was like no real
26:44alternative, beside Effect.
26:46But I'll get into why this is
26:48actually a pretty good alternative also
26:50for teams that only
26:52use native node JS TypeScript.
26:55But yeah, so, after I
26:58tried Effect for the first time, so I
27:00think it was last year in June that I
27:04made the first Effect commit ever at
27:07Zendesk, getting up and running was
27:09fairly easy because I could get a
27:11skeleton of an application using our fp-ts
27:15based service framework.
27:17And then, yeah, I think one important
27:19thing that I need to mention is that,
27:22we're mostly building these services
27:24on graph QL and then we have graphQL
27:26Federation, so yeah, like lots of
27:29microservices, each owning their own
27:31domain and we call them sub graphs and
27:33then they compose into a super graph through
27:36the Apollo
27:36Federation solution.
27:38So this survey service
27:39was just another sub graph.
27:41So once I got to the point where I could
27:43start implementing the resolvers for the
27:47different graphQL objects and
27:49mutations and queries and whatnot, um,
27:51I was already, at that point I could
27:54finally use Effect.
27:56So I was using Effect in the beginning
27:58only at the resolver level of my
28:01application.
28:03So, so that went pretty well.
28:05Startup was very easy.
28:06And then obviously like I created like an
28:09application skeleton that I'm familiar
28:11with, and then the resolvers were Effect.
28:14And that nicely adapted into the
28:17promise based resolver because with
28:19an effect, you can run it as a promise.
28:21So that was perfect.
28:22And then after that, it was just
28:24like, okay, let's, let's start with this.
28:26Let's start with a simple Effect.
28:28Let's start with a dummy resolver.
28:30And then next step was
28:32let's add some validation.
28:33So we brought in Effect Schema and yeah,
28:36now that I mentioned Effect Schema,
28:37I think that's probably the
28:39best gateway drug into Effect.
28:41Like everybody needs input validation.
28:45Everybody that it's almost impossible to
28:48imagine a piece of software, like a,
28:51you know, an HTTP service that doesn't
28:54need input validation unimaginable.
28:57Yeah, I definitely agree.
28:58I mean, this is where, why Zod as a
29:00standalone library is also getting so
29:02popular, but I think people
29:05will see that their
29:06requirements will grow beyond just input
29:08validation where you maybe need to run some
29:12effectful
29:13code, like some, some
29:14code that can't go wrong,
29:16et cetera, as part of this validation,
29:17but then also critically, not just
29:20parsing and validating the code, but at
29:23some point you might also want to
29:25re serialize it as you, you don't just
29:27receive data, but you want to ship it
29:30over the wire to another
29:31service or to your front end.
29:33And then you're scratching your head
29:35because, okay, you have now this beautiful
29:37sod system that can validate and parse
29:40data, but now you want to go the other
29:42way around and that is impossible.
29:45And if you use a whatever, like you've
29:48created a class, a user class that you
29:50parse things into, and now you have your
29:52data expressed through like those
29:54classes or more complex data structures.
29:58And you want to call
29:58JSON.stringify on it.
30:01And suddenly stuff blows up.
30:03And this is where Effect Schema comes
30:05in and I completely agree.
30:07This is going to be my primary bet for
30:10what will be the, the main gateway
30:12drug that brings people to Effect.
30:14And it's has gotten so nice.
30:17I think this is where in the past where
30:18you've been using fp-ts
30:20you've probably used io-ts
30:21Effect Schema is written by the same
30:23person, but I feel like
30:25It's a new incarnation, of the
30:28same person who just made everything
30:29so much nicer to use so
30:31much easier to understand.
30:33So yeah, huge fan of that part.
30:35Absolutely.
30:36Same.
30:37I'm a huge fan of Giulio who does
30:39all of this, this work.
30:40It's just amazing.
30:41-big shoutout to Giulio. -yeah, absolutely.
30:46fp-ts and io-ts helped us so much in the
30:48beginning and now seeing him also do all
30:50of the work, for Schema at Effect and
30:54doing a lot of Effect documentation
30:55work as well, it's just, uh, yeah, it's,
30:58it's amazing to see that.
31:00So sounds like last year, last summer
31:02you've written your first Effect code at
31:05Zendesk, and I think you've been
31:08by the end of that year, you've been
31:10getting to a point where it could be
31:12rolled out and we've been just chatting
31:15before where you mentioned that this year
31:17it's getting released in GA.
31:19So, I suppose across like all
31:22production traffic, et cetera.
31:24So how's that gone?
31:26And how did your team like it?
31:28How, how was your experience?
31:30Yes.
31:31So my personal experience was, was great.
31:33Let's start with me and
31:34then we can go to the team.
31:36And then we can go
31:36like outside of the team.
31:40Yeah, I was taking
31:41really baby steps with effect.
31:42So after input parsing and
31:45validation the next big step was to
31:48interact with the database, obviously
31:50relying just on SQL effects was not
31:53enough because we have
31:55a sharded database.
31:58We have like this big shared sharded
32:00database instances that every
32:03application interacts with.
32:04So we had to write like a wrapper,
32:07for SQL effects that would read
32:09the configuration, create one SQL
32:12pool per shard node.
32:15So basically one for a writer, one for a
32:18reader, and then we would have like this
32:20big collection of writers and readers
32:22group by shards, and then every time a
32:26request comes in, we would have to figure
32:27out what is the shard ID reaching to the
32:30collection handle like short shard not
32:33found errors and stuff like this.
32:35Finally getting the shard, getting the
32:37pool for the writer or the reader
32:38that you currently need at the
32:40point where you need to
32:42like call the database.
32:43And then that's when we get the SQL
32:46effects, like the SQL client from the
32:48library at the time, like the pool is
32:51basically provided by that.
32:52And then that was great.
32:54once we got there, because then we
32:56could persist events.
32:58So one thing that I want to mention is
33:00like, we use event sourcing where exactly
33:04this two way bi-directional schemas,
33:07work really well, because on
33:10one hand, like when the request comes in,
33:13we do the input parsing and then that
33:17input represents almost the exact
33:21payload that we then write to the
33:24database which represents our event.
33:26So once we did the parsing, obviously we
33:29need to serialize it into, into a
33:32string that we can then push into a,
33:35into a text column in SQL.
33:38So yeah, that was a big thing.
33:40And then obviously the next step
33:42after the database client, there was
33:44like the HTTP layer where we might
33:47need to call like different HTTP
33:49services, especially around the feature
33:52flags and stuff like that.
33:53So yeah, really baby steps.
33:54And then eventually we added some
33:56level of observability,
33:59logging, tracing metrics.
34:01In the beginning.
34:02It wasn't really anything sophisticated.
34:04We were relying mostly on the data dog,
34:06tracing library defaults, which
34:08provided some level of detail.
34:12It didn't work very well.
34:13We didn't get very detailed traces,
34:15but it was good enough to see some
34:17traffic and what's going on at the, maybe
34:20let's say the GraphQL level.
34:22So everything that is an Effect,
34:24obviously we couldn't get any visibility
34:26into that, but then we switched to
34:29Otel eventually, and then things
34:30improved from there and then as the more
34:34I learned about Effect, the closer
34:36I was getting to turning the application
34:39into an end to end Effect.
34:42And today it's like fully Effect.
34:44So it's effect from top to bottom.
34:46Right.
34:46And I think this is a pattern that I've
34:49seen a lot both in the apps that I've
34:52been building and where I take, I've
34:53taken my first steps with Effect, but
34:56also in what I see how other people are
34:59approaching effect is like how
35:01nicely it can be adopted incrementally.
35:03Where if you think about your program as
35:05a tree, you can very easily start
35:09at like any layer of the tree, really
35:12like at any position, you can start
35:14out with the leaves and
35:15write those as effects.
35:17And then at some point, just run them as
35:20promises and assuming your, your other
35:22code is already like promises or
35:25async await based, you can just call your
35:28new effect code as good old promises.
35:32Or you can do it on the other way around.
35:35And at the root of your program, you
35:37can rewrite some
35:39parts that are maybe more
35:41for governing and overseeing the
35:43execution of your program.
35:44You can rewrite that with Effect, for
35:46example, request handlers, but then,
35:49still call out to promises and everything
35:51else of your program is still promises.
35:54Or you can do it somewhere in the middle
35:55and say, okay, at some point we're like
35:58in async await, we're going to rewrite
36:00some part in with effects, but then the
36:03stuff way further down,
36:05we'll call again as promises.
36:07And so you can mix and
36:08match as much as you want.
36:10But what I've typically seen is that
36:13people get very
36:14productive very quickly
36:15with like some incremental adoption.
36:18And then they see
36:19like, Oh, wait a second.
36:20That part is still not as nice.
36:22And that is some of the
36:23leftover promise code.
36:25And then in no time
36:27that's rewritten to effect as well.
36:29I think what is typically
36:31the case is the more
36:32you rewrite to effect
36:33that kind of collapses the amount
36:36of code typically like by half and
36:39shines a very bright light on some of
36:42the holes that you haven't yet
36:43covered such as error handling very
36:46often, like Effect kind of shows
36:48you a mirror and say like asks you like,
36:50Hey, here stuff could go wrong.
36:52Right.
36:53What have you done so far about it?
36:54Not really much.
36:56And so it forces you to do the right thing
36:59That sounds very familiar.
37:00What you've described.
37:01Absolutely.
37:02Writing Effect has
37:03a lot of knock on Effect.
37:06Pun not intended. On how you write
37:09maintainable code on a day to day basis.
37:12Things like obviously the error
37:13handling it's amazing.
37:15Very recently I implemented a Kafka
37:19consumer with
37:20effect, um, using Kafka JS.
37:23So I just wrapped Kafka JS in an Effect,
37:25API and then had like an
37:28abstraction for a consumer and then
37:30obviously the consumer can consume
37:32things, um, either message
37:34by message or in batches.
37:35So I just needed a message by message,
37:38type of consumption.
37:41So that's what my abstraction does.
37:44It creates a consumer and you pass in
37:46like the effect that hand a function
37:48that returns an effect that handles like
37:50the incoming message, the payload.
37:53It was just really beautiful to see
37:55how the different error cases
37:57all bubble up to the very root of
38:01your message handler.
38:03And then in Kafka, like when you consume
38:06the messages, it's super important to
38:08make a decision at that point.
38:10Like, do you drop the message
38:12or do you retry reprocess it?
38:14Right.
38:14You need to be able to make this decision
38:17for every single error case.
38:19And you know, you just have effect dot
38:21catch tags and then you have like a big
38:24dictionary, like a big, big object
38:26containing the tag of
38:27the error on the left side.
38:30And the error handling basically die
38:33or, or succeed with some error
38:36logging or whatever.
38:37So if you die, Kafka
38:38will reprocess the message.
38:40If you, if you succeed and you log it,
38:42well, you can either put it into
38:45like a dead letter queue or something.
38:47If you want to keep
38:49those messages around.
38:51But if that's not necessarily
38:53important because
38:54it's like time sensitive
38:55and if you don't process it now, then it
38:58doesn't make sense to process it like
38:59five days later, then you
39:01just discard the message.
39:03And before I would normally implement
39:06Kafka consumers like in Ruby or maybe in
39:10fp-ts, it was also, it was better, but I
39:14don't think I had it to this level
39:16of granularity because what we ended up
39:18doing in fp-ts was taking like the
39:21shortcut route where we would just return
39:23a generic error interface.
39:25Just to have like, yeah, you
39:26know, it can error, but we didn't know
39:29what kind of error later on as I got
39:31better with fp-ts, then obviously you
39:33would have different types of errors,
39:34which would also compose.
39:36but I haven't written a Kafka
39:38consumer with that,
39:39approach in fp-ts,
39:41but with Effect, it was just like so easy
39:43and it's so useful because you don't
39:47think about all these different kinds of,
39:51ways your program can fail.
39:54And my consumer is very simple.
39:57It receives a message.
39:59It parses it.
40:00writes an event and
40:02then calls another service.
40:03So basically three things, but there's
40:07like 15 or 20 different ways it can fail.
40:10And it's just like, wow, now I know
40:12everything every single way, how it can
40:14fail
40:15so what took me the most
40:16time was thinking about whether to
40:20discard or reprocess the message in the
40:22whole implementation
40:23proportionally the most time,
40:25but that makes a lot of sense.
40:27And I think that makes a difference
40:28between resilient and
40:30non-resilient software.
40:33I think a lot of TypeScript programmers
40:35are blissfully ignorant of the
40:40unhappy path of a program, but this is
40:44what ultimately makes your users very
40:46unhappy if stuff goes wrong.
40:49and a lot of times that is completely
40:51unrelated to whether
40:52the user has done something wrong as
40:54whether your servers have a bad day or
40:56whether you've migrated some infra and
40:58like some things is like hitting capacity
41:02or you're just hitting a blip somewhere
41:04and things go wrong and a user gets like
41:08an endless spinner or gets like undefined
41:12is not a function in their face.
41:14This is where like some backend
41:15engineers haven't done their homework.
41:17And I get it.
41:19It's really tricky.
41:21If you, if you're just like dealing
41:23with like catch error and then
41:26you have an any or unknown
41:27thing and what do you do with it?
41:29Yeah, maybe you bubble it around, maybe
41:32you log it, but to work with it as
41:36nicely as like structured type data that
41:39you return from a function, that's what
41:41you get with Effect and
41:42you can handle it so nicely.
41:45That was actually fun to
41:46deal with the non happy path.
41:48Yes.
41:49And I think you
41:49touched upon it very well.
41:51It's fun.
41:52You don't feel like it's something that
41:56you have to do, but the language or the
41:59library like doesn't really provide a
42:01good way for you to manage.
42:02And then it's like just a headache.
42:04It's really fun.
42:05To handle these cases in Effect.
42:08And it just has such a great effect on,
42:12on your reliability, on the
42:16reliability of your software.
42:18The other thing that I noticed was also
42:22in terms of
42:23maintainability and testability,
42:25like the dependency injection,
42:27like dependency management as well.
42:30It's just so great with effect.
42:33I don't have to worry
42:34about mocking things extensively.
42:38I just build a fake dependency and
42:41provide that instead of, instead
42:43of the real one, the live one.
42:44And I feel like I'm much more
42:48incentivized to write unit
42:50tests and I don't know how other people
42:53think about engineers at companies like
42:57Zendesk and like Facebook and Google,
42:59like big, big companies, like how they
43:02deal with these things
43:03deal with these things
43:03on a day-to-day basis.
43:06In the end, like it doesn't matter
43:07how skillful or experienced you are.
43:11It comes down to incentives all the time.
43:13Like you do things that you
43:15are more incentivized to do.
43:17So if a language or a framework or a
43:21library makes
43:22something really easy to do,
43:24you will do it regardless, whether it's
43:27the right thing to do
43:28or the wrong thing to do.
43:29It's just like this.
43:30I don't know if there's like a law or
43:32this, but it's
43:33definitely a psychological effect.
43:36This, this is one of my favorites
43:38paradigms or
43:39guidelines in programming
43:42or in life, in principle,
43:45which is like make the right thing easy.
43:48And that is, I think Effect makes
43:51some really hard things
43:54that are the right thing
43:56as easy as they can be.
43:58And so easy that it's fun doing things
44:02like error handling or structuring
44:04the hierarchy of your program in a
44:06nice way, in the as nice way as you could
44:10possibly do it in TypeScript, that's a
44:12huge lift and that's
44:13what Effect enables you.
44:15And I think sounds
44:16like dependency injection.
44:17That's probably if you're in your Effect
44:20adoption journey, that typically happens
44:22sort of like maybe in the second week
44:25when you're using Effect
44:26after you've like rewritten
44:27a whole bunch of like
44:29promise code, et cetera.
44:31Maybe you've now like finally cleaned up
44:33some of your tech depth
44:34around error handling.
44:36And then you realize, okay, there's still
44:38like some
44:38global state we mutate
44:40to kind of pass things around, or we just
44:43have like this big blob of
44:45like properties we're
44:46like kind of pulling
44:47through like all of
44:49our function vacations.
44:50Or maybe we have this like monster
44:52monstrous context object,
44:55which maybe has a whole bunch
44:57of like, either it's untyped or it has a
45:00whole bunch of like
45:00nullable properties and you
45:02kinda pray that it's there.
45:04That's like all like CME principles.
45:07I'd argue this, the most principled
45:08approach about that is
45:10like having like a bag of
45:12properties that you just like lift
45:14through your function
45:15calls, but Effect gives you
45:17the best of both worlds.
45:18It gives you a very principled approach
45:20and a very convenient approach.
45:22And I think dependency
45:23injection has a kind of a bad rap.
45:26I've used it in
45:27various programming language.
45:28I've used it like a lot
45:29of in PHP in the past.
45:31I've used it like in GoLang and
45:34other programming languages.
45:35It never, it felt like, okay, this is how
45:39things should kind
45:40of, there is a solution
45:41somewhere there, but all the solutions
45:43I've used so far where
45:45it kind of like had such
45:46big foot guns that at some point I said
45:48like, okay, no, I've hurt myself too much
45:50with that.
45:51I'll do it manually.
45:53And I think Effect finally gives you the
45:55cake and lets you eat it.
45:57And I think that's
45:58really hard to explain.
46:00And I think you have to build a little
46:01thing, refactor it and
46:03like, then throw in a
46:05little bit of like type save context,
46:06which is all there is to it.
46:08Really.
46:09It's like react context,
46:10but type save and much nicer.
46:12So that's, I think something you have to
46:14try for yourself to
46:15see that how nice it is.
46:18But I agree.
46:18This is one of the best things about it.
46:20Yeah, absolutely.
46:22And why does it have a bad rep
46:24if I think
46:25about it, I think it's
46:26again, comes down to incentives.
46:28If the language makes it hard to do
46:30dependency injection,
46:32because it's never just a
46:33singular case, like, Oh, I'm going to do
46:35dependency injection on this function.
46:37And this one function will be, you know,
46:40they're written the right way.
46:41Well, you know, your program usually has
46:44a certain depth, like there's like a
46:46function and then that function calls out
46:48that of other functions.
46:49Those functions call out other functions.
46:51And then the dependency needs to travel
46:53all the way down because it's
46:54called somewhere at the leaf.
46:56For example, a database call is made
46:58somewhere at the leaf of our program and
47:01wiring through all these layers and then
47:04adding the dependency in the list of
47:07arguments all the time.
47:09Well, I'm not surprised
47:10that people get tired of it.
47:12And I started thinking about it a few
47:14weeks ago, you know, like, what are these
47:16approaches?
47:17And I started calling them just
47:19internally for myself,
47:22my own, for my own sake.
47:23Like there's this explicit dependency
47:25injection where you like to do all the
47:27wiring and like yourself.
47:29Then there's some languages like Scala,
47:31which somehow give you like some, some
47:35language features, which allow you to
47:37implicitly wire through it.
47:40You need to have a big brain for that.
47:42And it feels a little bit magical, right?
47:44This implicit dependency injection.
47:47I don't know if it's
47:47through traits or something.
47:48I'm not a big Scala user,
47:51but I did see some, some of it.
47:53And then you have Effect, which is like,
47:56it's somewhere in the middle.
47:58Like it's, it's kind of implicit, but
48:00it's also very explicit in a sense.
48:02Like you, you do declare, you see where
48:05you inject the dependency by providing
48:08the implementation.
48:09And then you also see the place where
48:11you're calling the functions and the
48:14stuff that's on the dependency because
48:17you have to yield it or yield star.
48:20So it's, it's kind of implicit because
48:22you don't have to wire it manually.
48:25You just use it at the, at the, at the
48:27site where you need it.
48:29I think it's the best of both worlds in a
48:31very similar way.
48:32How I think TypeScript is the best of
48:35both worlds where it very elegantly
48:38does type inference in
48:40most places where you can.
48:42a lot of static languages,
48:44like ask you to write type annotations
48:47everywhere, and that I think also causes
48:51like some fatigue when
48:53you use a typed language.
48:55And I think TypeScript makes it so nice
48:57that you can get away with
48:59like just type annotations in
49:00the minimum amount of places.
49:02Sometimes even for argument types, if you
49:05have a default value, for example.
49:07So most things where possible can be
49:10inferred and that's totally fine.
49:12And so think about the context, the type
49:15dependencies of an Effect of a
49:16function, think about it the same way like
49:18if it's
49:19used, it can be inferred.
49:21If you return something from a function
49:23that looks like an object with a property
49:27user, then the type can be inferred.
49:29That's because you return it.
49:31And what's so cool about Effect is
49:33like, if you use a thing in a function
49:36and using, like you said, like if you
49:39yield something, so the equivalent
49:41of like an await, then Effect and like a,
49:45on the type level wires things up
49:47nicely with TypeScript that in the type
49:50signature, you say like, aha, here
49:53we need the database client.
49:55And also during runtime makes sure,
49:58okay, there's behind the
50:00scenes, the context objects where we have
50:01the database client.
50:02So it picks it up and not just even that,
50:04but also when you finally get to run your
50:07program, it makes sure that at some point
50:10you supply your database client.
50:13And I think that is so elegant when you,
50:16when you use it, but it's, it's hard to
50:19to kind of grasp it if you, if you
50:20haven't take a look at that with
50:22code and like try to refactor a little
50:25something, but I agree.
50:26It's one of the most
50:27elegant things about Effect.
50:29Absolutely.
50:29People just have to
50:30get their hands dirty.
50:31There's no other way of learning and
50:33understanding Effect.
50:34Like obviously you could read the
50:36documentation all day long, but then
50:38you get fatigued because there's just so
50:40much that Effect provides.
50:42I often see people being very confused
50:44about what is Effect?
50:45Like, "I don't understand it.
50:47it seems to do
50:48everything", because it's such a big
50:51departure from the tiny libraries with
50:54very well-defined responsibility
50:57in the JavaScript ecosystem.
50:59And then you can like pick and choose and
51:00you can build your own tech stack,
51:03upon certain libraries, and then that's
51:05your definition of production
51:08grade software, but then
51:09you have Effect, which seems
51:10to be like the glue code.
51:12It's a really a generic
51:14programming framework
51:15Right.
51:16And I suppose in a parallel universe
51:18Effect would have been a different
51:21programming language, but I think
51:23now we sort of have the best of both
51:26worlds in that regard as well, because
51:28TypeScript is darn good.
51:30Like, and so many people
51:32already love TypeScript.
51:34I love it.
51:34It has so much structure and has so much
51:37amazing tooling around it.
51:39VS code just works super well with it.
51:41You have like LSPs that
51:43work in other places.
51:44So at this point, you need to have a very
51:47good reason to create a new
51:48program language, and I think good
51:50reasons could be superior runtime
51:53performance, what like Rust is giving you
51:56or what other program languages give you.
51:59But if you can't provide those unfair
52:02advantages, then I think you
52:03gotta stick with TypeScript for now.
52:05And TypeScript is so elegant and
52:07so flexible that you can bring all of
52:10those semantics that you would get from
52:12something like reason or a re-script.
52:15But you can bring it
52:16directly into TypeScript.
52:17This is where Effect has
52:18struck this really nice balance.
52:20But I agree you need to rewire
52:22your brain a little bit.
52:24And people maybe
52:25don't immediately get it.
52:27And I've seen an interesting correlation
52:29that people have the easiest time
52:31getting what Effect is about if they've
52:33experienced the problems that Effect
52:36solves before and they
52:39have sort of like a lot of scar tissue
52:40from trying to solve those problems
52:43themselves, like trying to do proper
52:45error handling, trying to do
52:47observability, trying to do interruption.
52:49What you've mentioned
52:50before with Kubernetes.
52:52So the more problems an engineer has
52:55experienced in the past, particularly
52:57TypeScript engineer, I feel like
52:59for them
52:59Effect clicks
53:00most quickly, but yeah, I'm curious, what
53:03was the experience talking to other
53:05engineers at Zendesk so far?
53:07What have they been confused about?
53:09What has clicked for them?
53:11So far I mostly talked through
53:13my own experience.
53:15Then I had my immediate team members and,
53:19with them, obviously it's a journey
53:21because, they have to learn it.
53:23It's also different from fp-ts.
53:25Also fp-ts, they didn't
53:27really bother learning that much.
53:29Like as long as they could kind of
53:32understand in terms of the code
53:34review, what's going on, that was
53:36already a good enough level for them,
53:38To be productive and
53:40help me with the reviews.
53:41If I write some code, also my team in the
53:46past one, two years, like we've had this
53:50unfortunate situation where
53:52we had some churn in the team.
53:53So often I was like the only backend
53:56engineer on the team while being
53:57the tech lead as well.
53:59So I really needed like my front end
54:01engineers to be able to review my
54:04code, and Effect is just doing
54:06really well in this regard as well.
54:08Because once you have the generator
54:12syntax, where you have the gen and
54:16yeld star, which you can easily map
54:19in your mind to async and
54:20await, you can build up this
54:22adapter layer, in this mental
54:24model for you once that clicks,
54:26it's very easy for them to review code.
54:30I'm not talking about stuff like,
54:32you know, database queries and, you
54:34know, how to set up proper indices for,
54:37for your table and like these backend
54:39concerns, purely backend concerns, but
54:41like all the business logic that you
54:43write on the backend and there's a ton of
54:45it, that's not an issue in terms of
54:47review.
54:48So that's sort of like the 10 second
54:50onboarding like, Hey, this stuff going
54:52to look a little bit weird.
54:53Just everywhere you see yield, think
54:55that's await everywhere.
54:57You see that gen thing, I think that's
54:59async and you should be able to like,
55:01just read that code as like your
55:03traditional async, await code go.
55:06I think that is sort of like the hail
55:08Mary 10 second onboarding
55:10where someone can get really far.
55:12Yeah, exactly.
55:13And that's like totally
55:15Pareto, like, this 20% of effort
55:19gives you 80% of the results.
55:21Like after that, obviously they're going
55:23to have questions
55:24like, what is this layer?
55:27What is this runtime?
55:29Uh, what do you do when you catch tags?
55:31What are tags?
55:32Like there will be questions like this,
55:34but they're, and yeah, they require maybe
55:38more nuanced explanations, not just
55:41like a one-to-one mapping from a
55:43new concept to a well-known
55:45well-established other concept.
55:47But, but it's that
55:4920% of the, of, of the productivity
55:53that you're achieving
55:54with the 80% of the effort.
55:56So already with the 10 second onboarding,
55:58you're so far ahead that the
56:00reviews just work already.
56:02And then I like this idea of like,
56:04exposing someone
56:06to Effect first through
56:07like reading
56:07code and doing code review.
56:09Since this is where someone through
56:11the context that they are already
56:13familiar with, maybe through a refactor,
56:15maybe through a new feature, they
56:18have all of the context that they need to
56:20understand what the problem is about.
56:22And now they can focus
56:23on the implementation.
56:24And I think what's also so nice is
56:26depending on where someone
56:28reviews the code, possibly ideally in
56:30their IDE, this is where you can also
56:33use all of like the type inference
56:35benefits to help you understand
56:38what's going on, if you hover over an
56:40effect and see like, Oh, this is where
56:43we can have an error that is about maybe
56:46the user wasn't found or maybe
56:50another service is done.
56:52This can add so much to the picture to
56:54understand what's going on.
56:56Where before everything was just like,
56:58an implicit sort of wake
57:01thought, and I feel like this is where
57:03someone just by also being exposed
57:06can pick up so much.
57:08And then you have seen at the end of the
57:10day, a lot of code users are
57:13very similar to each other.
57:15And this is where in someone get now
57:17takes that step to writing their own
57:19Effect code, they probably have already
57:21seen two or three places that are very
57:23similar, so you can go copy some of that
57:26code, go over there, adjust it, and
57:29bring the usual programming muscle.
57:31And it's works going to work just as well
57:34and probably even better
57:35since you have improved type safety.
57:37Yeah, absolutely.
57:39Also, I really love the way you can work
57:42with generators because anything
57:44that's within the function body of a
57:47generator, it's basically your happy
57:49path because all the error cases just
57:52short circuit the happy path.
57:54And then you just do a quick pipe after
57:56the Effect where you
57:57handle all the
57:58possible failure cases.
58:00And I don't know why, but I just love
58:03this style of writing programs.
58:06Here's my happy path.
58:07Everybody can understand what's going on.
58:10And then now in this pipe, I'm going to
58:13handle all the errors.
58:14Right.
58:15This way can like, sprinkle a little bit
58:16of like extra sauce on top of it, where
58:19you can, I often do
58:20also like timeouts there.
58:22I add a little bit of like Otel
58:24instrumentation around that, or maybe do
58:27like a retry for an error
58:29but yeah, as you say,
58:31like in the generator,
58:32this, and I think this is so beautiful
58:34about it is like, you can nicely separate
58:36sort of like signal from the other stuff
58:39and say like, okay, here's my business
58:41logic and here's like,
58:43here are those other concerns.
58:45I think like in the future, if we have
58:47like a next
58:48generation of IDEs, et cetera,
58:50and maybe like even more AI assisted,
58:53maybe that can help you and say like,
58:55Hey, hide everything that is not about
58:57the business logic or
58:59hide everything that,
59:00or like highlight everything that is
59:02about concurrency or highlight everything
59:04that is about error handling with Effect.
59:06You already put in sort of like the
59:08structural effort and I think we're going
59:11to see some, some big rewards even beyond
59:13what we have right now.
59:16That's very interesting.
59:16I never thought about this, but, uh, it
59:19makes it enough sense.
59:20Yeah.
59:21The, the tooling that you can build on,
59:23on, on top of these like static
59:25descriptions of a
59:26program is just like limitless.
59:28Yeah.
59:29Interesting.
59:30Yeah.
59:30This is something I'm
59:31very, very excited about.
59:33And we've, we talked briefly before about
59:35the launch of the Effect Playground.
59:37I think it's super nice to have like an
59:39environment where it can just play
59:41around a little bit, get
59:42familiar with something.
59:43I use it on a daily basis to maybe
59:45understand an API surface a bit better
59:48and just play around with it, have fun.
59:50And we also threw in support for some of
59:53the effect dev tools in there,
59:55notably also the trace viewer.
59:59And this is where you can get real time
01:00:01feedback for what does it mean for
01:00:03my program to run this is where it may be
01:00:05a certain thing took like a second
01:00:08and then should just time out, et
01:00:11cetera, like visually
01:00:12see what's going on.
01:00:14There's so many tooling possibilities
01:00:16that are coming.
01:00:18And that's gonna just kind of like the
01:00:20gift that keeps on giving as like
01:00:22you adopt Effect, and there's like so
01:00:23many benefits that just fall out of that.
01:00:26I think we're still at the beginning and
01:00:28it's already very rewarding for at
01:00:31least in my experience
01:00:32and what I've seen so far.
01:00:33So you shared your
01:00:35experience using an adopting Effect
01:00:38and also how you help your own team adopt
01:00:42Effect and be productive with it
01:00:44through code reviews and helping them to
01:00:46refactor code and build new Effect
01:00:48programs.
01:00:49But given that you built this service
01:00:51framework that is used, I think all
01:00:53across Zendesk when it comes to
01:00:55TypeScript code, there's now more and more
01:00:58people that are exposed to effect.
01:01:00So how was their experience?
01:01:02Maybe you got a little
01:01:03bit of like questions.
01:01:05What is that thing?
01:01:06Uh, maybe some similar concerns that
01:01:10people asked about fp-ts
01:01:13So which sort of questions did you hear.
01:01:16Yes.
01:01:16Uh, well, that's a great question.
01:01:18So let me start with another
01:01:20team, uh, not my team.
01:01:21That's the closest to our team.
01:01:24And they have some services that are
01:01:27fully written in fp-ts
01:01:28and using our service
01:01:30framework, so they're looking and
01:01:33watching us from the
01:01:34sidelines, writing Effect
01:01:36code line, because we're enjoying this
01:01:38opportunity of building a completely
01:01:40new service from scratch.
01:01:42And, uh, they're, they weren't so lucky.
01:01:43So they're still stuck
01:01:44with their fp-ts project.
01:01:46And they're just looking at us, uh,
01:01:50and are maybe a little bit jealous,
01:01:53of us that we're writing effect
01:01:55already because they've been looking
01:01:56forward to writing effect as well.
01:01:59But, but I'm helping them try to
01:02:01figure out how to migrate, fp-ts to
01:02:04effect also incrementally
01:02:05it's, it's a bit tough.
01:02:07Especially if you have your own
01:02:08abstractions and own ways of doing things
01:02:12with fp-ts, so it's really slow.
01:02:15And also it's really hard to justify, to
01:02:17spend the time to fully migrate a
01:02:20rather large project in one go.
01:02:23So it really has to be incremental.
01:02:25So that's, that's a
01:02:26positive feedback from them.
01:02:27But then we also have teams that are
01:02:30outside of our immediate organization
01:02:33and they are, let's say more TypeScript
01:02:36native teams and they have completely
01:02:40different requirements from, from my team
01:02:44and from the other Guide team.
01:02:46Because Effect was not their choice.
01:02:49It was our choice for, for the
01:02:51TypeScript service framework.
01:02:52Right.
01:02:53And the service framework does
01:02:55provide a lot of value, but without
01:02:58knowing Effect necessarily or fp-ts
01:03:01even it's really hard to tap into
01:03:04that value and, and use it immediately in
01:03:06your project, which knows nothing
01:03:08about fp-ts or Effect and the engineers
01:03:10know nothing about fp-ts and Effect.
01:03:12So here Effect actually brings some
01:03:15really good tools, that can
01:03:17help bridge between the two
01:03:20requirements and
01:03:21that's the adapter layers.
01:03:24So basically when you have an Effect, you
01:03:25can run it as a promise or you have
01:03:28a promise and then you can wrap it into
01:03:29an effect using different APIs.
01:03:32So in our service framework, this is
01:03:35something that we're going to be leaning
01:03:37on more and more because we want to
01:03:41provide the benefit to all the users
01:03:44regardless whether
01:03:45they choose effect or not.
01:03:47So for every effect API, we can have a
01:03:49rule that we will also be able to a
01:03:51promise based API, which is fully built
01:03:54on top of the effect, because we're just
01:03:56going to satisfy all the dependencies at
01:03:58the time and, and run it as a promise.
01:04:02And then they can always look up what
01:04:04kind of failure
01:04:05modes there can be because they can just
01:04:07follow by convention, or by
01:04:10inspecting the implementation.
01:04:12They can see which effect APIs,
01:04:14rather which service framework effect
01:04:16based service framework API is wrapped
01:04:18and then discover the
01:04:20type signature there.
01:04:22So that's, that's one way how they can
01:04:24reap the benefit of knowing
01:04:25what kind of errors there are.
01:04:26They don't have to
01:04:27inspect all the depths.
01:04:30I don't know how even people were doing
01:04:32it with like regular
01:04:33type script libraries.
01:04:34You know, how do you discover what
01:04:35kind of errors you may encounter?
01:04:37Like, I think typically you don't and you
01:04:39discovered during runtime and logging.
01:04:42Yeah, exactly.
01:04:44It will be so nice to know like, Oh,
01:04:46here's the documentation page.
01:04:48It lists all the 150 ways of my program
01:04:52failing or my library failing.
01:04:54But this, this doesn't exist.
01:04:56I at least I have not seen a library
01:04:59documenting their
01:05:01implementation or
01:05:02their API's to this level.
01:05:04It would also be really terrible to
01:05:05maintain the documentation for this.
01:05:07I mean, we have the perfect primitive for
01:05:09that, which are types and I
01:05:11guess more modern programming languages,
01:05:14such as Rust, et cetera, they have
01:05:16figured this out and they return results
01:05:19in case something can go wrong.
01:05:21And I mean, Effect is about the same idea
01:05:24that you don't just return
01:05:26just the success value, but also you're
01:05:29returning the, the errors just through
01:05:31the return channel as, as other things as
01:05:34well, but coming back to
01:05:35the point you were just making, I liked
01:05:37that approach that basically for
01:05:39the folks in your organization who are
01:05:43already excited and interested about
01:05:45Effect, they can already start consuming
01:05:48the effect API's for the ones who
01:05:50are still on the fence or are not quite
01:05:53ready to make the jump yet.
01:05:55They can still stay in the Promise land
01:05:58and need to deal with,
01:06:01errors, et cetera, the, the good, bad
01:06:03way, um, the old bad way.
01:06:07Which sort of questions do you typically
01:06:09hear when someone is as
01:06:11confronted with Effect, I suppose
01:06:14there's a full spectrum of people.
01:06:16You immediately get it and are excited to
01:06:19dig in to people who are maybe curious,
01:06:23but don't quite get it.
01:06:25And then maybe people who are much
01:06:27more skeptical and maybe this
01:06:30reminds them of like some other bad time
01:06:32they had in the past and why they have
01:06:35reasons in mind, why
01:06:36they don't want to adopt it.
01:06:37So tell me more about the different kinds
01:06:39of reactions that you've seen.
01:06:42Yes.
01:06:43So I've done a few
01:06:46Effect related presentations
01:06:48at Zendesk already.
01:06:49I presented at our annual tech
01:06:52conference in May.
01:06:54So I had the opportunity to actually
01:06:56get some of those questions and lots
01:07:01of people are actually skeptical.
01:07:03Maybe due to their own
01:07:05experience with something
01:07:06similar that they tried or
01:07:07just, it just looks too functional for
01:07:10them and they're more familiar in the
01:07:14OP and dynamically typed languages.
01:07:18They don't necessarily understand it.
01:07:21Like at Zendesk, we have lots of
01:07:23engineers who have experienced all
01:07:25the issues related to scale
01:07:27maintainability,
01:07:29testability, reliability,
01:07:30all these things, but still this alone is
01:07:35not necessarily
01:07:36not a huge selling point for them necessarily
01:07:38because they already
01:07:39have their ways around it.
01:07:41Like they have years of experience doing
01:07:43Ruby years of experience doing whatever.
01:07:45And they, they know their way around it.
01:07:48Maybe they don't even care necessarily
01:07:49about super reliability because
01:07:52there's like feature flex.
01:07:54So you can basically not break
01:07:55everybody at the same time, but you just
01:07:57break a tiny bit of, uh, of the
01:08:01customers, which is understandable.
01:08:04If you don't have any other option
01:08:07because you're limiting the blast radius.
01:08:10But it's also not something I'm
01:08:11really a big fan of.
01:08:13Like I really want to catch the errors
01:08:16and possible failure cases even
01:08:18before I commit my changes.
01:08:20Like that's the ideal thing.
01:08:21I don't even want to push it somewhere to
01:08:23a CI and then waste CPU cycles,
01:08:26of a CI just to make it fail.
01:08:29Um, and then repeat rinse and repeat many
01:08:32times possibly, because also sometimes
01:08:34it's really hard to run all the things
01:08:36that the CI runs locally due to different
01:08:39limitations, but yeah, so we have these
01:08:42people who know their way around.
01:08:44So for them, maybe a bigger concern is
01:08:47usually, okay, but
01:08:48listen, we have so many
01:08:50different technologies at Zendesk, we have
01:08:53to consolidate like, why should this be
01:08:56the thing that we consolidate on?
01:08:58How will you align with
01:08:59all these hundreds of engineers
01:09:02on the single one technology?
01:09:03Obviously we have some processes like
01:09:05ADRs and whatnot, but if it comes
01:09:09to a big change like this, obviously
01:09:12there's going to be also resistance
01:09:13because people just are accustomed to
01:09:15to the status quo.
01:09:18And they're their way of operating and
01:09:21they don't necessarily want to switch.
01:09:23Which is totally reasonable.
01:09:25And I don't want to change anybody's
01:09:28mind or I don't want to force
01:09:31anybody to now, you know, forget about
01:09:34promise land and
01:09:35start incorporating
01:09:37Effect into your code
01:09:38base starting tomorrow.
01:09:40I truly believe it should be like a
01:09:43choice that everybody
01:09:45can make for themselves.
01:09:47But then you have, you know, the company
01:09:49incentives to try and consolidate to,
01:09:52to not go into too many directions
01:09:54because if you want to be productive at,
01:09:57at the top level, you know, at an
01:09:59organizational level, like the more
01:10:02people pull in the same direction, the
01:10:05better you are and the more productive
01:10:08you are.
01:10:09So these are also a little bit
01:10:10political, uh, you know, influence
01:10:13and political, it's a
01:10:16question of politics as well.
01:10:17Like how can you influence
01:10:18without being in a big leadership
01:10:22position and stuff like that.
01:10:24Have you found some arguments like from
01:10:26the many things that Effects can offer
01:10:28that has resonated still with the people
01:10:32who are more in the skeptical spectrum?
01:10:34Yes.
01:10:35Um, so sometimes I do, because let's say
01:10:39you're a company and then now you
01:10:42had this financial crisis where the
01:10:44interest rates went up and now, uh, you
01:10:48figure out that money doesn't grow on the
01:10:50trees and you have layoffs and whatnot.
01:10:53And suddenly you stop backfilling for
01:10:56positions, you know, which, which
01:11:00came up because of churn
01:11:01and you're not used to pairing.
01:11:04So you have hiring
01:11:04freeze or whatever suddenly.
01:11:06And, but the expectations of productivity
01:11:08are staying the same.
01:11:09So basically you have
01:11:10more workload per person.
01:11:13That's, that's the final result.
01:11:15The company still expects you to deliver,
01:11:17but now you are fewer people to do so.
01:11:20It's, it's a hypothetical one.
01:11:22Right.
01:11:22So what do you do?
01:11:25Well, I think TypeScript is positioned
01:11:27really well because
01:11:28you can have TypeScript
01:11:30both on the front end, which in many
01:11:32cases you do, and then
01:11:34you can have it on the
01:11:34back end as well, which
01:11:35is, isn't a terrible option.
01:11:37Especially like, you know, you have NodeJS
01:11:40or Dino or whatever, nodeJS with
01:11:42its event loop runtime, perfectly suited
01:11:46for i/o heavy operations.
01:11:50And as far as I'm aware, like 90% of what
01:11:53Zendesk does is i/o heavy.
01:11:55We take a message, no matter where it
01:11:57comes from, we do some processing and
01:12:00we send a message somewhere else.
01:12:02Like maybe it's like you, you, you start
01:12:05a record in the database or you emit a
01:12:07thing in Kafka, maybe you have like a
01:12:09MySQL connector with Kafka, so you can
01:12:11do these things
01:12:13in a single transaction.
01:12:14So basically you manage your distributed
01:12:16transactions this way.
01:12:17So you do a ton of like taking things
01:12:20from here, pushing there.
01:12:22A lot of waiting time, a
01:12:23lot of i/o, what do you do?
01:12:25Like with Ruby, obviously.
01:12:27And this is another thing
01:12:28that I often mention is cost.
01:12:30Like if you have nodeJS handling
01:12:34traffic, like large concurrent
01:12:37traffic, heavy traffic, you can save a
01:12:40lot of cost because with Ruby.
01:12:44What's your option there?
01:12:45Well, yes, you can use threads, but then
01:12:48your memory consumption goes up because
01:12:50threats are not for free.
01:12:52Or you can scale horizontally.
01:12:54So when you put the horizontal pod
01:12:56autoscaler max it out at 24 replicas
01:12:59or whatever you figure out the rules
01:13:02around how to increase the
01:13:04replica count by how much, when, what is
01:13:06the signal that you're looking at?
01:13:08You know, you can figure out all of these
01:13:10things, or you can
01:13:12just have a few replicas,
01:13:14maybe one per availability zone, 2
01:13:17per availability zone for extra
01:13:19redundancy
01:13:20of a node, uh, process.
01:13:22And then suddenly you
01:13:22have a throughput of what?
01:13:24Tens of thousands of requests per second.
01:13:27So, so it's also money, you know?
01:13:30So when you, when you talk to high, uh,
01:13:32to the leadership, you have to
01:13:35convince them with some
01:13:36hard hitting facts.
01:13:38And it's not just, obviously you can say,
01:13:40ah, in theory, this works.
01:13:43No, you have to sit down, do the
01:13:45analysis, maybe set up
01:13:46some project which can
01:13:48demonstrate how much more cost
01:13:51efficient it is compared to other similar
01:13:54workloads, put it into
01:13:56money, uh, values, right?
01:14:00Uh, convert it into dollars or whatever,
01:14:02and then show the difference.
01:14:05And then once you do this, you know, you,
01:14:08you, you won the golden ticket or
01:14:10something because it comes down to
01:14:12money in the end always.
01:14:13Yeah, totally.
01:14:15And I agree with that approach that
01:14:18you can basically like, let the
01:14:20actions, actions speak louder than words.
01:14:22And you're doing
01:14:24the right work already.
01:14:26You're are shipping things in production.
01:14:29You're appreciating and leveraging all
01:14:32the benefits that
01:14:34Effect provides to you.
01:14:35And I think the, your team and some other
01:14:39peer teams have a great
01:14:41experience already with Effect.
01:14:42And I think those will show the results
01:14:46and that might make a case for itself
01:14:49and prove out that it's not just words,
01:14:52but it's actually an improved
01:14:54reality that makes teams more effective,
01:14:58more efficient, happier, and
01:15:00possibly also then saves resources and
01:15:04money when it comes to running those
01:15:06services,
01:15:07saves down times, et cetera.
01:15:09So I'm sure the, the more time continues,
01:15:13the more all of those arguments
01:15:15going to resolve
01:15:16themselves in your favor.
01:15:18And I applaud you for being
01:15:20on the early adopter train.
01:15:24Thank you.
01:15:24I, I do hope that it
01:15:26plays out really well.
01:15:28I'll do my part for sure.
01:15:30Perfect.
01:15:31So maybe that leads me to the last
01:15:34question that I'd love to hear your
01:15:36thoughts on, which is what gets you most
01:15:38excited about the future with Effect.
01:15:43Yes.
01:15:44Ah, that's a good question.
01:15:47I haven't put a lot of research into
01:15:51Effect Cluster, but it's definitely
01:15:53something I'm observing again from the
01:15:56sidelines and look forward to using
01:15:58in the future, maybe for some
01:16:00use cases like backfills, let's say.
01:16:04I have my event sourced service and now I
01:16:07evolve my, uh, event schema from version
01:16:11one to version two,
01:16:12maybe two version three.
01:16:14And now I feel like, okay, my switch
01:16:18statements where we, where I, where I
01:16:20switch between the versions of the schema
01:16:22and then, uh, the way I'm reducing the
01:16:25events into a single aggregate, it's
01:16:28getting a bit cumbersome.
01:16:29So let's just migrate some of those old
01:16:31schema versions to the latest one.
01:16:34So having like millions, maybe billions
01:16:37of records, it could take quite
01:16:40some time to do this sequentially.
01:16:43So having like a solution where I can
01:16:45have set up some workers, which can agree
01:16:48on, you know, the scheduling and how
01:16:50they're going to partition the database
01:16:52table among each other, uh, and do it in
01:16:56parallel, that, that would be just the.
01:16:59You know, perfect dream come true.
01:17:01I don't want to start the backfill in
01:17:03every cluster one after another, or even
01:17:06in parallel, and then like having to like
01:17:08watch tens or dozens of, you
01:17:12know, monitors to see the progress of
01:17:14each individual
01:17:15backfill on every Kubernetes
01:17:17cluster and then managing that for hours.
01:17:22You know, if that could be like maybe a
01:17:2410 or 20 minute thing, that would be
01:17:28just the perfect dream, right?
01:17:29So I'm looking forward to Cluster.
01:17:32Yeah, me too.
01:17:33This is, uh, one of the, as I said, like,
01:17:35uh, be the, the gift that keeps on giving
01:17:38and we're going to have like many layers
01:17:41built on top of the foundations that
01:17:43we already benefit from and the Effect
01:17:47Cluster and Effect workflow primitives
01:17:49that are in the work and the
01:17:50systems that are in the work.
01:17:52Uh, I think that's gonna, yeah, that
01:17:54that's going to be literally next level.
01:17:56This is going to unlock some benefits
01:17:59that you see from systems like Temporal
01:18:02Temporal IO, not the new time standard,
01:18:05but temporal IO, which is about durable
01:18:07workflows and, and workflow scheduling
01:18:09and running long lived things.
01:18:13You can already do that in Effect
01:18:15combined with temporal, but Effect
01:18:19is the perfect foundation to do that, uh,
01:18:21natively with the effect primitives.
01:18:24When you think about rerunning something,
01:18:27if something has failed scheduling, some
01:18:29work, um, processing work across multiple
01:18:33workers and massively
01:18:35parallelized systems.
01:18:37This is where we have like amazing
01:18:39foundations for that.
01:18:41And that's being systematized with the
01:18:43effect cluster and effect workflows
01:18:45project, which is now
01:18:46in development for, I think also like in
01:18:49research for a few years now.
01:18:51And I think it's alpha grade right now.
01:18:54I think some people are
01:18:55already starting to use it.
01:18:57I'm actually also planning to give it a
01:19:00shot soon for the music app that I'm
01:19:03building, and I think it will take a
01:19:05little bit of more time to be fully
01:19:07production ready, just because it's also
01:19:08a very ambitious project, but it's very
01:19:11principled and I'm very
01:19:12excited about the potential for it.
01:19:15And I think we're going to hear a lot
01:19:16more about that in the months and years
01:19:19to come and possibly the next year's
01:19:21Effect Conference already.
01:19:23So yeah, super excited that
01:19:25you're excited about that.
01:19:27Because I think you have some really
01:19:28interesting use cases for that.
01:19:30So, Attila, thank you so much for
01:19:33taking the time today to doing the
01:19:35initial episode of the Cause & Effect
01:19:38Podcast with me and taking the time.
01:19:41So that's much appreciated.
01:19:42And thank you so much.
01:19:44Thank you.
01:19:44It's been a great honor to be the first
01:19:46guest of this amazing podcast.
01:19:50Perfect.
01:19:50Thank you.
01:19:51Take care.
01:19:52Take care.
01:19:53Thank you for listening to
01:19:54the "Cause & Effect" podcast.
01:19:56If you've enjoyed this episode, please
01:19:57subscribe, leave a review,
01:19:59and share it with your friends.
01:20:01If you haven't done so already, you can
01:20:03join our Discord community.
01:20:04And if you have any questions, feedback,
01:20:06or suggestions about this episode or
01:20:09about Effect in general,
01:20:10don't hesitate to get in touch.
01:20:13See you in the next episode.