Exploring Elixir Type Validation with Domo and Ivan Rublev - EMx 271

Welcome to another insightful episode of Elixir Mix, part of the Top End Devs podcast. In today’s conversation, our host Charles Max Wood and panelist Sasha Wolf welcome Ivan Rublev, a backend Elixir engineer with a particular focus on business domains like real estate and B2B.

Hosted by: Sascha Wolf

Show Notes

Welcome to another insightful episode of Elixir Mix, part of the Top End Devs podcast. In today’s conversation, our host Charles Max Wood and panelist Sasha Wolf welcome Ivan Rublev, a backend Elixir engineer with a particular focus on business domains like real estate and B2B.

Ivan dives deep into the Domo library—a project he started to address certain gaps he felt existed within Elixir’s type system. He explains how Domo provides meaningful errors by validating structures against type definitions both at compile-time and runtime. The discussion also covers the inspiration behind Domo, its practical applications, and performance considerations.

Moreover, Sasha and Ivan discuss potential use cases where Domo shines and some scenarios where it might not be the ideal tool. They also touch on domain-driven design principles and Ivan’s interest in seeing Domo deployed in large-scale systems with multiple microservices.

Don't miss it as they uncover the possibilities and limitations of Domo, its impact on compile times, and real-world testing scenarios. Plus, stay tuned till the end for some book recommendations and more details on how you can level up your development skills with Top End Devs.

Transcript

Charles Max Wood [00:00:06]:
Hey, everybody, and welcome to another episode of Elixir Mix. This week on our panel, we have Sasha Wolf.

Sasha Wolf [00:00:12]:
Hello, everybody.

Charles Max Wood [00:00:14]:
I'm Charles Max Wood from dev chat dot TV. And this week, we have a special guest, and that's Ivan Rublev. Did I get anywhere close to saying your name right?

Ivan Rublev [00:00:22]:
Yes. That's right. Hello, everybody.

Charles Max Wood [00:00:25]:
Do you wanna introduce yourself real quick? Let people know who you are and why you're famous.

Ivan Rublev [00:00:29]:
Yeah. Sure. Thanks a lot for kind words. So, hi. I'm Ivan. I'm originally from Russia, but, for 3 years, we, with my family, live in Hamburg, Germany. So I'm software back end Elixir engineer, working in, business domains, real estate, and currently in b to b business. Yeah.

Ivan Rublev [00:00:51]:
So that's Cool.

Charles Max Wood [00:00:52]:
To help me. And, yeah, we I was looking at this, Domo library that you wrote. I have to admit, I'm I'm still green when it comes to some of this stuff, so I didn't follow all of it. But do you wanna give us kind of the 10,000 foot view on what Domo is and what it does?

Ivan Rublev [00:01:08]:
Yeah. Sure. Is is that started, like, about a year ago, and I usually had these impressions that I missed something within Elixir. And, when I look at the structure and, especially the type definitions of the structure, Of course, there is a dialyzer tool that helps us to, check validity of the source code program. Same time, it doesn't work at run time, and dialyzer is quite heavy tool, to be honest. So and I was missing, these things that okay. Elixir is dynamically typed language. And on the other hand, this type definition, maybe I can do something about that.

Ivan Rublev [00:01:52]:
And then pandemic started, and I got some free time, and I just kick it off. So I made these libraries that basically validates the structure against the type definition and return meaningful errors about the fields. Okay. Here, you define that this field should be a string, and you have some number in this field in the structure. So this aims to keep the state valid because many software errors comes from invalid states in the memory, and structures looks like a good good place for keeping the state. So that was my thought. Okay. Let's make a tools that validates the state within the structure.

Sasha Wolf [00:02:40]:
Was this prompted by, like, a concrete, like, use case you had? Like, for example, at work, you you had some issues, or was this just like an just an academic idea at the beginning, and you were curious to to try some things out?

Ivan Rublev [00:02:53]:
Well, yeah, it's was mostly inspired by book, The Mind Dream Design by Eric Evans. So and it more it was more like an academic inspiration, let's say. And yeah. So I've got, these feelings that there are lots of, trials and errors around. So we know that there are other libraries like norm that they mean the validation and other attempts to make to introduce types in Elixir to get these benefits of, checking. And sometime, nothing what I meant before suit me well. And because of that, I decide, okay. Maybe I should give it a try and do some not full fledged type system or something because Elixir is not such kind of thing, but very little tiny specific libraries that does only validation of the structures and basically keeping invariants.

Ivan Rublev [00:03:54]:
Yeah. So answering your question directly, no. It wasn't inspired by any, concrete task at at the office. So it was more like general ideas that I would like to have such a thing.

Sasha Wolf [00:04:08]:
And, are you now using it in, like, any production scenarios? I mean, you said it comes from an academic background. Sure. But, do you know that, like, anybody is using it in production?

Ivan Rublev [00:04:17]:
Yeah. Well, sure. So I I checked it, with, current, real projects that we have, and it works well. So and it's, kind of at early stage. So, of course, it's in development for about a year, but only couple of days ago, I can say, okay. That's final. Things were fixed, and now it can be widely adopted.

Sasha Wolf [00:04:44]:
Okay. When where would you see, like, Domo being used most? Like, are there any specific use cases where you say, hey. That's, like, a pretty good fit for Domo where where I saw personal success in using it? Like, when will people reach for Domo compared to something like, for example, Norm, as you mentioned earlier? Because just to give some context for our listeners, like Norm is this data validation library where you specify schemas, like, in code. Like, it doesn't use the type specs, but it's like you can basically use functions and stuff from norm to say, okay. The data should conform to this schema. And, I mean, Domo that uses the type specs. So when would you say it's like is this a scenario where somebody would like to use Domo? Any specific

Ivan Rublev [00:05:25]:
things for sure would you mind? Yeah. Sure. That's, amazing question. Thanks a lot. So, there is another component in Domo. It's, that I haven't mentioned before. So it's it's not only validating the data against the type definition type spec, but it also has these precondition, functions attached to the type. So meaning that, for example, if you have type definition for a field of your structure, you can also add a precondition function to this type that the DOMA library would call.

Ivan Rublev [00:06:01]:
And, if this function returns okay, then it would consider that the value is not only of that type, but it's also over, for example, right format that you expect. So and saying that, I can point out to the concrete scenario. So for example, if you know that you have, identifier in your system for your order, for example, let's say you build the ecommerce system. Right? Some websites ecommerce website. And so you know that in your systems, these identifiers have specific format, for example, a a letter in the beginning and some numbers afterwards. You can just, define the type. Okay. My ID is of string type and add the precondition function to this.

Ivan Rublev [00:06:49]:
So saying that the value should begins with a. And then using this type across any structures in your application, you would have these, automatically validated, whenever the structure is created with a a construction function added by Domo library. And I the Domo will guarantee you that, you will have valid values for this ID type across your application. And that in this regard, the state will be valid. So, yeah, this one scenarios, and it can go even more. Like, we can go further. We can define with thermal library, it's possible to define as a precondition for the struct type. You know, when you write this type t for your structure, and you can say, okay.

Ivan Rublev [00:07:41]:
For this type t, my precondition function will be this 1. You name it. And let's say you would like to have some relation check between fields of the structure, saying that, if this is order structure for ecommerce websites that you have some allowed amount of the order in terms of money, and you would like to have the sum of all line items in this order to be not higher than this, given amount. So this precondition function attached to the type of the structure can validate that and give some meaningful error back that, okay. You should have this summary more pleasant allowed. And, that's a nice scenario when, Domo, gives you consistency of your structure or more higher level, let's say so. So it allows to follow business rules of the system you're implementing. So this is the second scenario.

Sasha Wolf [00:08:48]:
So that said, I guess it could make sense to to use Domo, for example, at, like, the edges of my system when I say I have a Phoenix API, for example, getting some JSON in. And now I want to verify that the user actually, like, the the the information the user gave me conforms to a certain to to my schema to, like, to go to the to the request objects I I expect. And that I then can use that to forward it to a rest of my application being sure that yeah. As you said, pretty good sort of preconditions are met. Is that right? Is that like a scenario where you would say Domo is applicable?

Ivan Rublev [00:09:25]:
Yes. It's, one of scenarios where Domo can, can play, and it's, like, equivalent to what can be implemented to its norm. Right? So you can define the schema and validate the JSON on the, let's say, boundary of your application and then be sure that the data that you operate on is valid. And, yeah, this is definitely one of the possible scenarios. On the other hand, there are other scenarios. It's when you work with a pure core, having only pure functions and structures in it. And, you would like to follow to make it follow some business rules that should be executed in your system. So, for example, it's from the domain domain driven design framework.

Ivan Rublev [00:10:14]:
Right? So when you have set of business rules, you can define them with DOMO precondition functions attached to the type and have this business rule fulfilled everywhere, you use these values of these type in structures. So, for example, as I mentioned this, before with order, Right? So you can have the order structure in your core and have these values dependency between items of this order and allowed amount. The same, invariance, same kind of invariance may be for, other structures that participate in the business logic, of your application. Right? And instead of the okay. This can be compared that you can say, hey. I can write this in any module, write this verifications that my structure, have valid number of items and that the sum is not exceeding the allowed amount for this order. And interesting part here is that if you do this with Domo by using this precondition function attached to type, you can have this validation not only in this structure, but in any other kind of structures using this type. So it goes, like, automatically in these places, and, you don't need to think twice about if I forgot any validations or, you know, any parts of checking my, structures in regards to business logic of the application.

Ivan Rublev [00:11:58]:
So and to it it even can go further across application boundaries. For example, if you have several microservices, that is very common nowadays, you may have hundreds of them. And if, for example, you share these type definition and precondition functions in some, model files across these several applications, due to the Domo library, you can be sure that this would be checked and fulfilled. This, either these validations for boundary situation or for business logic in the core.

Sasha Wolf [00:12:40]:
So so when you say sharing the the modified, I assume, like, in the sense of, like, a private hex package or or what exactly are you thinking of?

Ivan Rublev [00:12:48]:
Oh, yeah. Sure. Can be a hex package. On the other hand, it's usually starts like a little. You just have several modules like, shared models that you can check out in various repos. So the techniques are various for that. So for example, you can have a shared Git repository with this model, and you can edit as submodules to other Git repositories or, you know, just check it out.

Sasha Wolf [00:13:22]:
Basically, you use, like, some kind of mechanism to, like, get the code into your microservices, be it through hex package or, like, through sub module. Okay.

Ivan Rublev [00:13:31]:
Yes. That's right.

Sasha Wolf [00:13:33]:
Okay. I was just thinking because they they they also solutions such as protobuf or others I can think of right now, which, like, also follow this idea of having, like, a model definition, which then can be used to generate some code, but that's, like, more agnostic, not really specific to to to Elixir.

Ivan Rublev [00:13:50]:
Yeah. It's very interesting. Yes. That's true. Protobufs are very good to have the center communication be validated. Same time, it's impossible to put function protocol definition.

Sasha Wolf [00:14:05]:
So Which we Some might argue is a good thing.

Ivan Rublev [00:14:09]:
At some scenarios, yes. On the other hand, with DOMA, you can do that and do more precise validation. Like, okay. If that if these conditions that, match them, these values should be as expected. On the other hand, if I have another value in my structure set to these values, and this should be should be another way to expect it. So you can imagine that, it can be quite, complex interdependencies between, fields of even one structure. Not saying about, some nested structures that's, usually now can be seen in modern applications.

Sasha Wolf [00:14:50]:
Okay. And to to get back to something you you said earlier, so you said that you can reuse, like, type definitions and preconditions attached to the type. So if, for example, I like to to get back into an example, you said, like, yeah, I find certain identifier, like an order identifier. I could just specify this type in some module, attach some preconditions to it, and then use it across my my application. And wherever I use Domo, basically, I assume, then that would basically reuse these preconditions attached to my order identifier type. Is that right? Did I get that right?

Ivan Rublev [00:15:26]:
Yes. That's right. So that looks like that.

Sasha Wolf [00:15:29]:
Okay. Well well, that's nice. I guess Domo boils a bit down to, like, saying to avoid a bit of repetition. Right? Because, I mean, for example, if you look at, at emo, you schemas, like like, from at least from my experience, you you tend to have the scenario where you say, okay. This is like my schema, and these are my fields. But then it it's also helpful to to have type definition on top so that you then just for documentation purposes. Right? They say, okay. Mhmm.

Sasha Wolf [00:15:58]:
This is like with the type of the schema, and these are like the sphere, the certain integer, and this field is a string. And then you also have on the bottom, like, maybe some some echo change set validations where you say, okay. My user ID needs to start with an a or my order ID needs to start with an a. So so I guess Domo goes back in that direction where you say, okay. I don't want to maintain, like, multiple definitions of the same information, basically. Right?

Ivan Rublev [00:16:24]:
True. True. Let's see. And so moreover, Domo has support of Acto. So if you have this schema defined and you have this type defined into the schema, you can call the change set in the DOMA library and the function that's named validate type. And DOMA, will automatically validate changes in the act of change set for you according to the type you define. So this is already supported and quite convenient.

Sasha Wolf [00:16:57]:
That's nice. I assume that, like, to to actually reuse a type, for example, such as the the order ID, I have to, like, use Domo in that place. Right? Like, I can't just use any remote type. I mean, that like, how does that work when you say, okay. It's like a string t then, like, we probably have some code written which says, okay. If it's a string, then do in this and that check. But if I just say, I I have, like, this module over there, which, like, doesn't use Domo at all, but it specifies my type. I don't know, which let's just say, like, it's a map, reflects certain certain keys, and the keys need to be of a certain value.

Sasha Wolf [00:17:36]:
Is that, like, something Domo can can handle them? Or how how exactly can I can I imagine this to work? Yeah. Like, where where are the boundaries, basically? Like, where does it break?

Ivan Rublev [00:17:45]:
Okay. So, tricky question. So where is break? No. I can say that that's a very good example, and, it was a quite long year, pandemic year, so I had the time to resolve this. And it was successfully completed. So how DOM works, if you have remote type who is within some structure or, you know, as a module that's not using DOM at all, library automatically takes this type into, validation because, more has is shipped with compiler. So, it when you add library to the project, it, has 2 pass compilation. 1st pass is by Elixir, and 2nd pass of the compilation is by Domo compiler that just do the job by getting all the type definitions from remote modules and putting them in place where the validation should be performed.

Ivan Rublev [00:18:45]:
So and, moreover, if you change remote type, for example, you compiled your project and, you change one of the keys in this map you mentioned in the remote module I mean, type definition of this key, and you compile again, the DOMA will notice that and recompile the module where you use this remote map definition.

Sasha Wolf [00:19:08]:
So so Automatically assigns the compile time with dependency to to, like, view remote map.

Ivan Rublev [00:19:14]:
Yes. It tracks dependency between types in your application and recompiles appropriately.

Sasha Wolf [00:19:20]:
I assume that this can have a hit on compilation times because, I mean, if you look at what the Alexei core team and the Phoenix core team has been doing in the past few months, they very much try to, like, reduce this kind of, like, compile time compilation compilation links between modules, which, like,

Ivan Rublev [00:19:39]:
don't Sure.

Sasha Wolf [00:19:40]:
Compile times. So I assume that at least, like, a trade off of using Domo in that fashion is probably that it might impact your compile times. Right?

Ivan Rublev [00:19:47]:
Yeah. Sure. Value comes at price, so definitely, it would, increase compilation times. In synthetic tests, it was about maybe 20% of increase of compilation time. And, of course, during the run time, it's additional CPU cycles that are spent on validation of the data you've got.

Sasha Wolf [00:20:11]:
That's the whole idea. Right?

Ivan Rublev [00:20:15]:
That's true. Yeah. Same time, I can say that there is a heavy optimization implemented yet for these dependency, checks. It just works. I can say that, during the compilation time, Duomo relies to the pattern matching a lot. And at least for the part when you, have this validation at run time of your values, it's working on already optimized code optimized by Elixir and the ALAN compilers. And because of pattern matches that, automatically generated by Domo, you can have, quite a good performance.

Sasha Wolf [00:20:55]:
Okay.

Ivan Rublev [00:20:56]:
Yeah. If you you know, when we talk about, code generation that definitely happens here with the Domo library, it's always a question mark. Okay. What this library generates, and how it works in my application. So you can ask this question at some point in time. And, interesting enough that Domo, writes the source code of this validation into the build folder. So if you add the type definition to your structure and say use DOMO there, then in underscore build folder, you would have, DOMO generated code subfolder where you can see the old source codes that, is used to do this runtime validations. So it's Yeah.

Sasha Wolf [00:21:45]:
That are then then used for as a compilation source, or is it just, like, for the user's benefit?

Ivan Rublev [00:21:50]:
Well, it's used as compilation source. The same time, if you change it, it wouldn't affect anything because it would be overwritten during the next compilation. So you can read it, but, you can't affect it much. This adds, this additional confidence about what's going on when you call this function, validate type on your structure or constructor function, or if you do update type in echo schema.

Sasha Wolf [00:22:21]:
Okay. I guess a question which for some people might have, like, how readable is this code? Because that code generation tends to sometimes produce code, which is like a bit not so nice on the eyes to say it to to phrase it like that.

Ivan Rublev [00:22:36]:
Yeah. True. There there is a a format around during the generation of this code, and it's, quite readable and quite simple. So, of course, there's more fields in your structure you have, the longer would be the output and the source code file. Same time, it's quite straightforward. There are 2 sending functions there that you just can read and say, okay. Here is the validation. Here is a better matching.

Ivan Rublev [00:23:08]:
So it's quite simple.

Sasha Wolf [00:23:10]:
So that means that, like, Domo generates, like, an additional module or what, which is then used for for type checking? Or Yeah. Somehow? Okay.

Ivan Rublev [00:23:18]:
Okay. What happens when you use Domo? At minimum level, you can just add use Domo into your struct module. Right? And, then Domo generates submodules that is called type ensure. So let's say your module named car, and after DOMA, works, you have also, in addition, car dot type ensure. And inside of this type ensure, all validation happens. And how it works in regards to your original car structure, Domo adds functions to the car structure as well. It's a new function that is constructor function for the structure and validate type function that sees for validation of existing instance. So, there are also a couple of other functions like, re typed fields and required fields that returns the list of the fields of your structures that has not new types, let's say.

Ivan Rublev [00:24:26]:
So that's useful in actual, change sets. So the first two, new and validate type functions, they just facade for type insure module. So when you call car dot new and, keyword list with fields and values for these, fields, the new function bypasses that after some checks, to type ensure module type ensure module, do pattern matches, validates the toll types of the values is as expected, then run precondition functions associated with these types, checking okay, the format of these values is good, all invariance are fulfilled, and then returns back to the call site. So and it returns the constructor the structure, basically. So that's how you can be sure that at the time of the call, when you get the structure back, it's valid structure according to the type and preconditions defined. Then if you modify this structure, for example, alter, fields, of the car, then you can, call again the validate type function with this modified instance. And validate type function would do the same trip to the type insurer and back, giving you the answer, is it still okay structure, matching the type and preconditions, or no? You have these fields incorrect because of this and that. So that's how it works, basically.

Sasha Wolf [00:26:00]:
Okay. And what happen if I, like, I have my car struct and I set use Domo, and then instead of that, I I just define a module which is called type insurer. What would happen then? Like, because then I have a name clash. Right?

Ivan Rublev [00:26:15]:
Yeah. Sure. Yeah. This behavior will be the same if as if you define type ensure twice. So you can do this by hand. And there there are no any, you know, hidden things behind that. It's just simply a generation of the Elixir source code and compiling it with Elixir 2 times. So

Sasha Wolf [00:26:38]:
Yeah. Okay. I guess, like, one one thing Domo could do there is, like, generating, like, it it in a different namespace. Right? Like, could, for example, generate it in domo.typeinsurer. Name of a module because then, I mean, tech people could then still define a module, which is called that way. But if they basically mess with, like, another epic another library's namespace, it's like, they're all forward. Right?

Ivan Rublev [00:27:02]:
Yeah. Well, it's this nice idea. Let's see what can be done in this regard. And there is another scenario how to start using Domo. You may not even use all the functions that Domo adds to your structure. For example, let's say we have the car, and, if you even write use Domo inside the car, you already get some benefits. What I mean? During the compilation time, it would check the default values of your car structure, these values that you usually define with dev struct. And during the compilation time, Domo already would validate if this default value specified conforms to the type and preconditions.

Ivan Rublev [00:27:44]:
Oh, okay. And if it's not, it would say, compile error. So you have these values not matching. That's nice.

Sasha Wolf [00:27:53]:
Yeah. And that's that's interesting.

Ivan Rublev [00:27:55]:
Even more if, for example, you have some connected structures, like one structure nested in another, and you let's say car and what can be inside of the car. Let's say, seat

Sasha Wolf [00:28:12]:
Some seat?

Ivan Rublev [00:28:13]:
Yeah. Seat. And, you know, these seats with leather or other materials, some some so we can imagine that for the seed, it can be a separate structure defining all the parameters of the seed.

Sasha Wolf [00:28:26]:
I want to call the blue seed, an orange seed, and 2 yellow seeds.

Ivan Rublev [00:28:30]:
Yes. Yeah. For example. So, if you, give the default value of seeds to the car, saying, okay. I would like orange, seed and blue and, put it into the dev struct of the car. And if you use, doma function like seed dot new, right, so it will check, during the compilation time the validity of this default value. And, if, for example, you put into the c dot new some invalid value by mistake instead of orange, string, the orange atom, and it wouldn't match the c type. Domo will also give you back the compilation error saying, okay.

Ivan Rublev [00:29:16]:
So you're constructing the things that is not matching the type, as a default value. And this works even in function calls. So if you pass this default value with doma.new to the function, a header definition, it will also be checked during the compile time. So how doma does that? It basically, tracks the calls to dot new that is generated by the, obviously. And, then during the compilation pass, it's just make, validation of these, fields.

Sasha Wolf [00:29:54]:
Okay. That that sounds sounds helpful. I mean, I I've not had a scenario where, like, my default values were as complex where I said, okay. I I want to verify it, but I don't make the mistake here. But if you get it for free, that's that's nice, I guess.

Ivan Rublev [00:30:07]:
Yeah. And, you know, the software is constantly evolving. So and it may happen then, For example, at some point in time, you change the type of your structure and the old humans, so you can forget, to change the default value. Right? And that potentially could lead to mistakes, and Domo plays safe here. So it gives you appropriate feedback ready very early at compile time.

Sasha Wolf [00:30:36]:
Charles, do you have any questions? I've been talking

Charles Max Wood [00:30:39]:
I was about to chime in. I'm I'm more curious about, like, testing and performance. Yeah. So how does this affect any of that?

Ivan Rublev [00:30:47]:
Well, I did some, synthetic tests, so you can find the re detailed results in the readme to the library. What I've observed, it's 1.26 times slower than without library at run time. So it looks like around, 30% slower work. Same time, you get valid state of your application at this price.

Sasha Wolf [00:31:18]:
I guess it makes sense when you're like I wouldn't probably use it in a scenario where I already know that, certain data is is valid because then, I mean, we check-in the first place. Right? But if if you are in a scenario where you say, okay. I am not uncertain that the data which I'm getting here is conforming to what I expect it to be, then sure. Why not? I mean, you can even write no validation at all, but which, like, works if the user was friendly enough to give you a right data. But if if if they don't, then it it's gonna go boom. Right? So Yeah.

Ivan Rublev [00:31:51]:
Yes. And it's not only user. Sometimes, the business logic can be quite sophisticated. And if, of course, we have unit tests and cover all not happy, but unhappy path as well. And same time, it can be that you can forget one or another combination of all parameters. And having this, validated against the type can add additional, let's say, can can give you additional, insurance that, you will have valid state of your application.

Sasha Wolf [00:32:29]:
One thing that Charles asked about testing. For example, I say, like, I let's go back to that example from earlier with the ID. And, it's a string. It's supposed to start off in letter a. Like, I mean, how would I go then go writing a test for that? Like, because, I mean, as you mentioned earlier, this is like a reusable type. Right? Like, a type I I can use in multiple places. I can see, like, how I would use reuse, like, the distracts, how it would test the the struct definitions of Domo because then I can just call dot new. Right? Like, like, if it raises an error or if it returns an error to the, then then it it can like, it failed or it's successful.

Sasha Wolf [00:33:07]:
Mhmm. But is there, like, an option to say, okay. I I have this type over here, and now I would write to write some tests because I also have some preconditions attached to that, and I wanna make sure that I didn't make a mistake while writing these preconditions. Right? Yeah. So, like, some some some option to do that?

Ivan Rublev [00:33:22]:
Yeah. So I remember one talk in regards to that from Kent Beck about what is right size of unit that is under the test. And I can say that, for example, in the test, you can define a struct for test purposes that uses this type definition and be sure that this precondition associated with this type working properly by calling this, you know, test struct dot new. Okay. So this will be what what does it mean? It means that, you would test the interface and not internal implementation. Right? So as a publicly available interface, provided by Domo, this new function and validate type function.

Sasha Wolf [00:34:14]:
Okay. But but but there's, like, no API where I can say, hey, Domo. I'd like to use this type over there, and please check it like, check these values I give you, and now tell me if if that conforms. Like, basically, it's gonna kind probably similar to what norm does. Right? So there's, like, no API to do that, I guess. Not exactly. To go through, like, the the the motions of, like, specifying a struct. And then I mean, if I using a struct I already defined or specifying 1 if I want to, for example, test the remote type.

Ivan Rublev [00:34:45]:
Yeah. Well, technically, you can. So you can call type ensure modules that Domo generates for these kind of things. So there is a public function, that is called. And on the other hand, it's a question where, your interface is. So if Yeah.

Sasha Wolf [00:35:06]:
Yeah. Yeah. I I guess we're now entering some some certain level of philosophical, conversation, like, what is a unit test? What what is what is the purpose of life?

Ivan Rublev [00:35:17]:
Yeah. Well, it's possible to do the unit testing with either new function or with calling, type ensure model directly.

Sasha Wolf [00:35:26]:
Yeah. But I I I can see why, like, calling type ensure model directly is something which probably should not be encouraged. I from from what you told me, I it feels like it's more of a private API thing. So Yeah. Yeah. Better than not go there, I guess.

Ivan Rublev [00:35:42]:
So it's a quite simple thing. On the other hand, if you would like to express, business rules, it's another possible way to do that. So for me, it's also always a question, to keep everything in place, especially when some parts of the business rules are shared across various parts of the application or even across several microservices.

Sasha Wolf [00:36:11]:
So maybe a bit of a hard question now. When is, like, a scenario where you would not use Domo? So is there, like, any scenario? Say, okay. This is just not the right tool for job. When should people maybe reach for something else or write custom code?

Ivan Rublev [00:36:26]:
Mhmm. Yeah. So, I think every tool should be used for appropriate problem. And, if it's high performance applications, like maybe cryptocurrency where you have heavy calculations and every microsecond is on count, then maybe it's not right, a problem to use Domo for. On the other hand, if you have a business application like ecommerce website or, lots of business logics that should work correctly and you can spend some time to get the answer to provide to users, then Domo could be a good choice.

Sasha Wolf [00:37:10]:
Okay. So what is any anything you see on the horizon for for, like, Domo? Any next steps you'd like to take? Anything which is missing and you'd like to tackle? Or what what comes next?

Ivan Rublev [00:37:22]:
Yeah. So I'm looking forward for some large system to give this library a try because, all applications I work with of the, average size. So it's, kind of, web shops or such kind of, websites. And I'm really interested to see how it would work on 100 microservices setups. So Mhmm. Where you have lots of, components that should be play that should play nice to, together. So and, very welcome for any such kind of collaborations to run a test on such, larger than average systems. Other plans are to add additional type checks to Domo, like, it checks all the standard types, but, that are defined, in the Elixir documentation.

Ivan Rublev [00:38:26]:
At the same time, it doesn't check types that referencing, itself, yet. So, I mean, cursory trees, recursive types. Right? Yeah. So I'd like to add support for that. It's not such, usual scenario in business applications, but I intend to support this.

Sasha Wolf [00:38:48]:
I've done this when I wanted to, like, have a representation of, like, a JSON of, like, a arbitrary JSON because then you can say, okay. Like, a JSON value can be like a list. It can be an integer. It can be a string, but it can also it can be an object, which in turn uses values, which is then recursive by definition. So, yeah, I can see why why that would be useful.

Ivan Rublev [00:39:09]:
Yeah. And for many, for many such kind of definitions, Domo is working now. If you say, okay, this is part of JSON, and, inside of this part of JSON, it will be the same part of JSON. So, you know, recursive reason DOMA wouldn't work. So yeah.

Sasha Wolf [00:39:26]:
What happens when you do that? Does it raise an error? Or what what

Ivan Rublev [00:39:29]:
is Yeah. Yeah. It raises an error that is not supported yet. Supported yet.

Sasha Wolf [00:39:33]:
Okay.

Ivan Rublev [00:39:33]:
But so no binary trees, for now. Sorry. So with leaves and branches, but it's, it's a question of, some further work on that.

Sasha Wolf [00:39:45]:
It's also been it might just then explode the runtime complexity. Right? Because if you have a very large binary tree, then it needs

Ivan Rublev [00:39:53]:
to Yes.

Sasha Wolf [00:39:54]:
But I guess that that's that's always an issue.

Ivan Rublev [00:39:57]:
Sure. And, for example, if you have very long lists that, can be in your, structure, it's also can be an issue. So this is natural limitation for demo because it validates each list telemeds for conformance to the type. So, it should be considered, as well.

Sasha Wolf [00:40:18]:
Is there, like, some some smart instead of Domo? For example, when you say I I've got a list of Annie because then, like, there has no reason to check each element of a list if if you say it can be anything. Is there something like that built yet into Domo? Or

Ivan Rublev [00:40:32]:
Yeah. In regards to list, no. Well, it's, so is there is there are such kind of optimizations. If you say that some field is any, for example, it wouldn't be checked, so it would be a shortcut. Like, okay, it's valid. And lists should be supported as well with, any, type inside. Yeah. So I intend to look up for other such kind of optimizations too.

Sasha Wolf [00:41:01]:
Yeah. But but but I guess that it goes into what you said earlier, like, to see it used in a larger scale, and then these kind of issues and optimization things are gonna crop up naturally because you you push the library to to the to its limits.

Ivan Rublev [00:41:14]:
Yeah. That's true.

Sasha Wolf [00:41:15]:
Yeah. Okay. Charles, do you have anything left? Because I'm I'm dry now.

Charles Max Wood [00:41:19]:
I think you pretty much covered it. Yeah. A couple of the questions I was gonna ask, then you covered them. So

Ivan Rublev [00:41:25]:
Yeah. So, it may, seems a bit weird from the first point of view. Right? So attaching preconditions to types and sharing here and there. But, on the other hand, it's another view of the same problem of, having valid state and fulfilling invariants in models. So Yeah.

Charles Max Wood [00:41:49]:
Alright. Well, I'm gonna push us toward PIX. We have a conversation about stuff that we like. Before we do that, though, Ivan, if people wanna follow you on social media or connect on GitHub, how do they do that?

Ivan Rublev [00:42:01]:
You can follow me on GitHub. My username is Ivan Rublev, and, you can follow me on Twitter. Username is Levi Brown. Maybe I should write it somewhere, folks, and you can add it to the description of the podcast.

Sasha Wolf [00:42:17]:
Yeah. Yeah. We will do that.

Charles Max Wood [00:42:18]:
Yep. Absolutely. Yeah. Just put it in the chat, and we'll, alright. Well, let's go ahead and do the picks. Sasha, do you have some picks for us?

Sasha Wolf [00:42:26]:
Yes. And it's actually related to what we talked about because, I mean, Ivan mentioned that he a lot of these ideas are based on domain driven design by by Evan. True. I forgot his last name. Evan.

Ivan Rublev [00:42:38]:
Eric Evans.

Sasha Wolf [00:42:39]:
Eric Evans. Yeah. Eric Evans. That that was and there's also another book, not from Eric Evans, but from from Scott Blashen, and it's called domain modeling made functional.

Ivan Rublev [00:42:50]:
Yeah. That's amazing book.

Sasha Wolf [00:42:52]:
Yeah. It's Very nice. Arguably, it's probably the best book I read it on the render from design. It's also relatively short, especially compared to Eric Evans book, which is not short.

Ivan Rublev [00:43:01]:
Yes.

Sasha Wolf [00:43:03]:
And it it We should

Charles Max Wood [00:43:04]:
see if we get Eric on. We had him on Ruby Roads a long time ago.

Sasha Wolf [00:43:09]:
Nice.

Charles Max Wood [00:43:10]:
Wow.

Sasha Wolf [00:43:10]:
Yeah. That that would be pretty cool to be honest. Maybe you could also get Scott Blushing off or he's not a Elixir in-depth. But, yeah, just to get back to the pick. So the book is called domain modeling made functional, and it's it's actually a nice introduction into both, like, into the remainder of design and also functional programming. He's using f sharp there, and he's, like, talking a lot about how to use the type system to basically help you restricting and, like, restricting things to what they should be to, like, basically avoid in in that state already on the types of the level, which plays a bit into what we talked about today because, I mean, demo helps with, like, using the type definitions

Ivan Rublev [00:43:45]:
and, like, enforcing those that direction.

Sasha Wolf [00:43:48]:
Yeah. And, yeah, it's, like, a really, really nice book. It's well written. It's it didn't really bore me to death. There are some of those tech books which I just stopped reading at a certain point. And if anybody is interested in domain domain driven design, is interested in function programming and types, then I can really wholeheartedly recommend this book.

Charles Max Wood [00:44:05]:
Awesome. I'm gonna throw out a couple of pics. The book I'm reading right now is I'm still in the middle of a rhythm of war by Brandon Sanderson. Really enjoying that picture book, fantasy book. I have another pick, but I'm kinda saving it for last. There was something else we're gonna pick, and I can't remember. I guess I'll just go to this last one because I'm excited about it. So I've been doing a whole bunch of work lately around the idea of top end devs.

Charles Max Wood [00:44:29]:
You all, if you listen to dev chat dot tv and are, you know, subscribed to the mailing list and stuff like that, you're gonna start seeing a whole lot more stuff, branded with top end devs instead of devchat.tv, because we're kind of moving everything over to that mainly because I want to communicate to people that, hey. Look. If you put in some effort we talked a lot about this, last week with Adi. Adi and I talked about this, but you can take your career wherever you want it. And I am committed to to that idea, and so I want to because dev chat dot tv doesn't dev chat doesn't it doesn't really mean anything. You know, the idea was is, hey. We talked about dev. Right? But this is kind of more of a higher idea and aspirational idea.

Charles Max Wood [00:45:11]:
One of the things that I'm doing and I can't remember if I brought this up last time, and so I'm gonna just throw it out here so you all can show up if you need it. But one of the things that I've really picked up lately is is the coaching. Right? I've I've just loved helping people figure out, hey, what do I do next? What do I need to learn? What do I need to work on to grow into what I want, what I wanna be? And as I've been doing that, it just it just fires me up. I mean, I had a conversation with somebody on Friday, and, you know, he's trying to figure out where to go next. Right? And we talked about all kinds of stuff. And at the end of the call, you know, it was like, hey. You know, go do this stuff. Let's talk in a couple weeks.

Charles Max Wood [00:45:51]:
Right? And holy cow is is just seeing the potential of what he can do and and the power behind what he can accomplish. That it just gets me going. Right? And there are some things that everybody can do, and then there are some things that as we get into the particulars of your situation, you can do. Right? And that's kind of the difference, I guess, between, like, of course and coaching or training and coaching. And so what I'm doing is I'm kinda splitting the difference between both. And so I'm using Zoom's webinar system, but it's not a webinar. Right? Webinar is I give you half the information that that's useful, leave you hanging, and they give you a sales pitch. I'm not doing any of that crap.

Charles Max Wood [00:46:29]:
K. That's I'm not doing a webinar, But I am gonna do training, so I'm gonna do, like, 10 or 15 minutes of training. And then for the the rest of the hour, hour and a half that I have, I'm planning on doing this Wednesdays around noon, mountain time. I'm just gonna take questions. K? And not take questions in the sense of, you know, what what what how do how do strings work in Elixir? No. It's not that kind of stuff. Right? If I if you have that question and I can answer it, you can ask it. Right? And I'll try and answer it.

Charles Max Wood [00:46:57]:
But what I'm really looking to dive into is, hey. I've gotten this far in my career, or, hey. I'm trying to figure this stuff out, or, hey. I've got this situation at work, or I'm trying to find a job and I'm not getting interviews, or things are going really well, but I feel like I could do more. What should I be doing next? And then we'll actually talk through your situation. Right? Talk through where you're at and figure out where things should go. Right? So it's gonna be almost more coaching than q and a, but we'll just do it until we run out of time, run out of questions, whatever. Right? And I really just wanna help people out.

Charles Max Wood [00:47:33]:
So it's totally free. Right? No no commitment. No whatever. I'm not gonna do a sales pitch, right, and try and sell you on coaching. Nothing like that. Right? I am offering paid coaching, but I'm not gonna try and sell anybody on that on these calls. Right? It's completely free, completely, you know, whatever. So all you have to do is just go to devchat.tv/levelup.

Charles Max Wood [00:47:56]:
You I think you have to put your email address in so that the Zoom system can send you the link to the webinar software. And then from there, you're in. Right? And, yeah, just show up, jump on the call, and we'll answer as many questions as you want. And if we don't get to you, then show up the next week. Right? Because we're gonna do it every week. And, yeah, I'm I'm really looking forward to helping some folks out. Like I said, this is the stuff that really just makes me feel like I'm making a difference myself. Right? And then, yeah, you know, if it turns into a kind of a a deeper relationship and we wind up doing coaching, then great.

Charles Max Wood [00:48:33]:
And if I kinda get you there in 20 minutes, then great. Then you're got there in 20 minutes, and you can come back when you get stuck again or you need more guidance. Alright? So that's kinda what I'm looking at, and I'm really hoping that I can help some folks out. So dev chat.tv/levelup. That's my other pick. Ivan, what are your picks?

Ivan Rublev [00:48:50]:
Okay. My pick, for today is book called, Microservices in Action by Morgan Bruce and Paul Opereira. It's very nice and laconic book about building microservices. It's the right way to yeah. I can recommend it.

Charles Max Wood [00:49:08]:
Awesome. Alright. Well, we're gonna go ahead and wrap up. Thanks for coming. This was fun.

Ivan Rublev [00:49:12]:
Thanks a lot, folks. It was very nice discussion about types and, the library. Thanks for having me today.

Sasha Wolf [00:49:19]:
Yeah. And if you feel interested in types, like, check out our episode with like, Gleam of Luis

Charles Max Wood [00:49:24]:
Oh, yeah. 2 weeks ago.

Sasha Wolf [00:49:26]:
That was fun too.

Ivan Rublev [00:49:27]:
Yes. Yes. Gleam is very nice. Initially, very nice too.

Sasha Wolf [00:49:30]:
Yeah. We had him 2 2 weeks ago on the show. That was pretty cool.

Charles Max Wood [00:49:33]:
Yeah. Louie. Cool. Yep. It was good stuff. Alright. Well, till next time, folks. Max out.
Album Art
Exploring Elixir Type Validation with Domo and Ivan Rublev - EMx 271
0:00
1:06:10
Playback Speed: